[analyzer] simplify the libraries.dart file

Change-Id: I86bc196eaddd9a80c02f38c8d947d3c0f4c63394
CoreLibraryReviewExempt: the sdk_library_metadata/libraries.dart is only used by the analyzer
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/317803
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Devon Carew <devoncarew@google.com>
This commit is contained in:
Devon Carew 2023-08-08 21:00:01 +00:00 committed by Commit Queue
parent 36c578f75c
commit 1948b0a9fe
6 changed files with 60 additions and 370 deletions

View file

@ -117,7 +117,7 @@ class _UriSuggestionBuilder extends SimpleAstVisitor<void> {
builder.suggestUri('dart:');
var factory = request.sourceFactory;
for (var lib in factory.dartSdk!.sdkLibraries) {
if (!lib.isInternal && !lib.isImplementation) {
if (!lib.isInternal && !lib.isImplementation && lib.isDocumented) {
if (!lib.shortName.startsWith('dart:_')) {
builder.suggestUri(lib.shortName);
}

View file

@ -148,9 +148,7 @@ class SdkDescription {
SdkDescription(this.path);
@override
int get hashCode {
return path.hashCode;
}
int get hashCode => path.hashCode;
@override
bool operator ==(Object other) {
@ -161,9 +159,7 @@ class SdkDescription {
}
@override
String toString() {
return path;
}
String toString() => path;
}
class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<void> {
@ -175,26 +171,10 @@ class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<void> {
/// an implementation library.
static const String _IMPLEMENTATION = "implementation";
/// The name of the optional parameter used to specify the path used when
/// compiling for dart2js.
static const String _DART2JS_PATH = "dart2jsPath";
/// The name of the optional parameter used to indicate whether the library is
/// documented.
static const String _DOCUMENTED = "documented";
/// The name of the optional parameter used to specify the category of the
/// library.
static const String _CATEGORIES = "categories";
/// The name of the optional parameter used to specify the platforms on which
/// the library can be used.
static const String _PLATFORMS = "platforms";
/// The value of the [PLATFORMS] parameter used to specify that the library
/// can be used on the VM.
static const String _VM_PLATFORM = "VM_PLATFORM";
/// The library map that is populated by visiting the AST structure parsed
/// from the contents of the libraries file.
final LibraryMap _librariesMap = LibraryMap();
@ -203,24 +183,6 @@ class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<void> {
/// parsed from the contents of the libraries file.
LibraryMap get librariesMap => _librariesMap;
// To be backwards-compatible the new categories field is translated to
// an old approximation.
String convertCategories(String categories) {
switch (categories) {
case "":
return "Internal";
case "Client":
return "Client";
case "Server":
return "Server";
case "Client,Server":
return "Shared";
case "Client,Server,Embedded":
return "Shared";
}
return "Shared";
}
@override
void visitMapLiteralEntry(MapLiteralEntry node) {
var key = node.key as SimpleStringLiteral;
@ -236,26 +198,10 @@ class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<void> {
} else if (argument is NamedExpression) {
String name = argument.name.label.name;
Expression expression = argument.expression;
if (name == _CATEGORIES) {
var value = (expression as StringLiteral).stringValue!;
library.category = convertCategories(value);
} else if (name == _IMPLEMENTATION) {
if (name == _IMPLEMENTATION) {
library._implementation = (expression as BooleanLiteral).value;
} else if (name == _DOCUMENTED) {
library.documented = (expression as BooleanLiteral).value;
} else if (name == _PLATFORMS) {
if (expression is SimpleIdentifier) {
String identifier = expression.name;
if (identifier == _VM_PLATFORM) {
library.setVmLibrary();
} else {
library.setDart2JsLibrary();
}
}
} else if (name == _DART2JS_PATH) {
if (expression is SimpleStringLiteral) {
library.path = expression.value;
}
}
}
}
@ -267,9 +213,11 @@ class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<void> {
/// Represents a single library in the SDK
abstract class SdkLibrary {
/// Return the name of the category containing the library.
@deprecated
String get category;
/// Return `true` if this library can be compiled to JavaScript by dart2js.
@deprecated
bool get isDart2JsLibrary;
/// Return `true` if the library is documented.
@ -283,9 +231,11 @@ abstract class SdkLibrary {
bool get isInternal;
/// Return `true` if this library can be used for both client and server.
@deprecated
bool get isShared;
/// Return `true` if this library can be run on the VM.
@deprecated
bool get isVmLibrary;
/// Return the path to the file defining the library. The path is relative to
@ -299,14 +249,6 @@ abstract class SdkLibrary {
/// The information known about a single library within the SDK.
class SdkLibraryImpl implements SdkLibrary {
/// The bit mask used to access the bit representing the flag indicating
/// whether a library is intended to work on the dart2js platform.
static int DART2JS_PLATFORM = 1;
/// The bit mask used to access the bit representing the flag indicating
/// whether a library is intended to work on the VM platform.
static int VM_PLATFORM = 2;
@override
final String shortName;
@ -315,23 +257,18 @@ class SdkLibraryImpl implements SdkLibrary {
@override
late String path;
/// The name of the category containing the library. Unless otherwise
/// specified in the libraries file all libraries are assumed to be shared
/// between server and client.
@override
String category = "Shared";
@deprecated
String category = "";
/// A flag indicating whether the library is documented.
bool _documented = true;
/// A flag indicating whether the library is an implementation library.
bool _implementation = false;
/// An encoding of which platforms this library is intended to work on.
int _platforms = 0;
bool? _implementation;
/// Initialize a newly created library to represent the library with the given
/// [name].
/// [shortName].
SdkLibraryImpl(this.shortName);
/// Set whether the library is documented.
@ -339,31 +276,24 @@ class SdkLibraryImpl implements SdkLibrary {
_documented = documented;
}
@deprecated
@override
bool get isDart2JsLibrary => (_platforms & DART2JS_PLATFORM) != 0;
bool get isDart2JsLibrary => false;
@override
bool get isDocumented => _documented;
@override
bool get isImplementation => _implementation;
bool get isImplementation => _implementation ?? !isDocumented;
@override
bool get isInternal => category == "Internal";
bool get isInternal => isImplementation;
@deprecated
@override
bool get isShared => category == "Shared";
bool get isShared => false;
@deprecated
@override
bool get isVmLibrary => (_platforms & VM_PLATFORM) != 0;
/// Record that this library can be compiled to JavaScript by dart2js.
void setDart2JsLibrary() {
_platforms |= DART2JS_PLATFORM;
}
/// Record that this library can be run on the VM.
void setVmLibrary() {
_platforms |= VM_PLATFORM;
}
bool get isVmLibrary => false;
}

View file

@ -1195,7 +1195,6 @@ class Symbol implements core.Symbol {
''',
)
],
categories: '',
);
final MockSdkLibrary _LIB_IO = MockSdkLibrary(
@ -1392,10 +1391,12 @@ void createMockSdk({
var file = lib.getChildAssumingFile(unit.path);
file.writeAsStringSync(unit.content);
}
librariesBuffer.writeln(
' "${library.name}": const LibraryInfo("${library.path}", '
'categories: "${library.categories}"),',
);
librariesBuffer.writeln('''
'${library.name}': const LibraryInfo(
'${library.path}',
documented: ${!library.isInternal},
),
''');
}
librariesBuffer.writeln('};');
@ -1424,14 +1425,15 @@ void createMockSdk({
class MockSdkLibrary implements SdkLibrary {
final String name;
final String categories;
final List<MockSdkLibraryUnit> units;
MockSdkLibrary(this.name, this.units, {this.categories = 'Shared'});
MockSdkLibrary(this.name, this.units);
@deprecated
@override
String get category => throw UnimplementedError();
@deprecated
@override
bool get isDart2JsLibrary => throw UnimplementedError();
@ -1444,9 +1446,11 @@ class MockSdkLibrary implements SdkLibrary {
@override
bool get isInternal => shortName.startsWith('dart:_');
@deprecated
@override
bool get isShared => throw UnimplementedError();
@deprecated
@override
bool get isVmLibrary => throw UnimplementedError();

View file

@ -239,28 +239,21 @@ class FolderBasedDartSdkTest with ResourceProviderMixin {
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
"async": const LibraryInfo(
"async/async.dart",
categories: "Client,Server",
maturity: Maturity.STABLE,
dart2jsPatchPath: "_internal/js_runtime/lib/async_patch.dart"),
),
"core": const LibraryInfo(
"core/core.dart",
categories: "Client,Server,Embedded",
maturity: Maturity.STABLE,
dart2jsPatchPath: "_internal/js_runtime/lib/core_patch.dart"),
),
"html": const LibraryInfo(
"html/dart2js/html_dart2js.dart",
categories: "Client",
maturity: Maturity.WEB_STABLE),
),
"html_common": const LibraryInfo(
"html/html_common/html_common.dart",
categories: "Client",
maturity: Maturity.WEB_STABLE,
dart2jsPath: "html/html_common/html_common_dart2js.dart",
"html/html_common/html_common_dart2js.dart",
documented: false,
implementation: true),
implementation: true,
),
};
''';
}
@ -280,36 +273,37 @@ class SdkLibrariesReaderTest with ResourceProviderMixin {
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
'first' : const LibraryInfo(
'first/first.dart',
categories: 'Client',
documented: true,
platforms: VM_PLATFORM),
),
'second' : const LibraryInfo(
'second/second.dart',
categories: 'Server',
documented: false,
implementation: true,
platforms: 0),
),
'_internal': const LibraryInfo(
'internal/internal.dart',
documented: false,
),
};''');
expect(libraryMap, isNotNull);
expect(libraryMap.size(), 2);
expect(libraryMap.size(), 3);
var first = libraryMap.getLibrary("dart:first")!;
expect(first, isNotNull);
expect(first.category, "Client");
expect(first.path, "first/first.dart");
expect(first.shortName, "dart:first");
expect(first.isDart2JsLibrary, false);
expect(first.isDocumented, true);
expect(first.isImplementation, false);
expect(first.isVmLibrary, true);
var second = libraryMap.getLibrary("dart:second")!;
expect(second, isNotNull);
expect(second.category, "Server");
expect(second.path, "second/second.dart");
expect(second.shortName, "dart:second");
expect(second.isDart2JsLibrary, false);
expect(second.isDocumented, false);
expect(second.isImplementation, true);
expect(second.isVmLibrary, false);
var internal = libraryMap.getLibrary("dart:_internal")!;
expect(internal, isNotNull);
expect(internal.path, "internal/internal.dart");
expect(internal.shortName, "dart:_internal");
expect(internal.isDocumented, false);
expect(internal.isImplementation, true);
}
}

View file

@ -6,301 +6,162 @@
// use of const.
// ignore_for_file: unnecessary_const
/// A bit flag used by [LibraryInfo] indicating that a library is used by
/// dart2js.
const int DART2JS_PLATFORM = 1;
/// A bit flag used by [LibraryInfo] indicating that a library is used by the
/// VM.
const int VM_PLATFORM = 2;
/// The contexts that a library can be used from.
enum Category {
/// Indicates that a library can be used in a browser context.
client,
/// Indicates that a library can be used in a command line context.
server,
/// Indicates that a library can be used from embedded devices.
embedded,
}
Category? parseCategory(String name) {
switch (name) {
case 'Client':
return Category.client;
case 'Server':
return Category.server;
case 'Embedded':
return Category.embedded;
default:
return null;
}
}
/// Mapping of "dart:" library name (e.g. "core") to information about that
/// library.
const Map<String, LibraryInfo> libraries = const {
'async': const LibraryInfo(
'async/async.dart',
categories: 'Client,Server',
maturity: Maturity.STABLE,
dart2jsPatchPath: '_internal/js_runtime/lib/async_patch.dart',
),
'collection': const LibraryInfo(
'collection/collection.dart',
categories: 'Client,Server,Embedded',
maturity: Maturity.STABLE,
dart2jsPatchPath: '_internal/js_runtime/lib/collection_patch.dart',
),
'convert': const LibraryInfo(
'convert/convert.dart',
categories: 'Client,Server',
maturity: Maturity.STABLE,
dart2jsPatchPath: '_internal/js_runtime/lib/convert_patch.dart',
),
'core': const LibraryInfo(
'core/core.dart',
categories: 'Client,Server,Embedded',
maturity: Maturity.STABLE,
dart2jsPatchPath: '_internal/js_runtime/lib/core_patch.dart',
),
'developer': const LibraryInfo(
'developer/developer.dart',
categories: 'Client,Server,Embedded',
maturity: Maturity.UNSTABLE,
dart2jsPatchPath: '_internal/js_runtime/lib/developer_patch.dart',
),
'ffi': const LibraryInfo(
'ffi/ffi.dart',
categories: 'Server',
maturity: Maturity.STABLE,
),
'html': const LibraryInfo(
'html/dart2js/html_dart2js.dart',
categories: 'Client',
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM,
),
'html_common': const LibraryInfo(
'html/html_common/html_common.dart',
categories: 'Client',
maturity: Maturity.WEB_STABLE,
dart2jsPath: 'html/html_common/html_common_dart2js.dart',
'html/html_common/html_common_dart2js.dart',
documented: false,
implementation: true,
implementation: false,
),
'indexed_db': const LibraryInfo(
'indexed_db/dart2js/indexed_db_dart2js.dart',
categories: 'Client',
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM,
),
'_http': const LibraryInfo(
'_http/http.dart',
categories: '',
documented: false,
),
'io': const LibraryInfo(
'io/io.dart',
categories: 'Server',
dart2jsPatchPath: '_internal/js_runtime/lib/io_patch.dart',
),
'isolate': const LibraryInfo(
'isolate/isolate.dart',
categories: 'Client,Server',
maturity: Maturity.STABLE,
dart2jsPatchPath: '_internal/js_runtime/lib/isolate_patch.dart',
),
'js': const LibraryInfo(
'js/js.dart',
categories: 'Client',
maturity: Maturity.STABLE,
platforms: DART2JS_PLATFORM,
dart2jsPatchPath: '_internal/js_runtime/lib/js_patch.dart',
),
'_js': const LibraryInfo(
'js/_js.dart',
categories: 'Client',
dart2jsPatchPath: 'js/_js_client.dart',
documented: false,
platforms: DART2JS_PLATFORM,
),
'js_interop': const LibraryInfo(
'js_interop/js_interop.dart',
categories: 'Client',
maturity: Maturity.EXPERIMENTAL,
platforms: DART2JS_PLATFORM,
),
'js_interop_unsafe': const LibraryInfo(
'js_interop_unsafe/js_interop_unsafe.dart',
categories: 'Client',
maturity: Maturity.EXPERIMENTAL,
platforms: DART2JS_PLATFORM,
),
'js_util': const LibraryInfo(
'js_util/js_util.dart',
categories: 'Client',
maturity: Maturity.STABLE,
platforms: DART2JS_PLATFORM,
),
'math': const LibraryInfo(
'math/math.dart',
categories: 'Client,Server,Embedded',
maturity: Maturity.STABLE,
dart2jsPatchPath: '_internal/js_runtime/lib/math_patch.dart',
),
'mirrors': const LibraryInfo(
'mirrors/mirrors.dart',
categories: 'Client,Server',
maturity: Maturity.UNSTABLE,
dart2jsPatchPath: '_internal/js_runtime/lib/mirrors_patch_cfe.dart',
),
'nativewrappers': const LibraryInfo(
'html/dartium/nativewrappers.dart',
categories: 'Client',
implementation: true,
documented: false,
platforms: VM_PLATFORM,
implementation: false,
),
'typed_data': const LibraryInfo(
'typed_data/typed_data.dart',
categories: 'Client,Server,Embedded',
maturity: Maturity.STABLE,
dart2jsPatchPath: '_internal/js_runtime/lib/typed_data_patch.dart',
),
'_native_typed_data': const LibraryInfo(
'_internal/js_runtime/lib/native_typed_data.dart',
categories: '',
implementation: true,
documented: false,
platforms: DART2JS_PLATFORM,
implementation: true,
),
'cli': const LibraryInfo(
'cli/cli.dart',
categories: 'Server',
platforms: VM_PLATFORM,
),
'svg': const LibraryInfo(
'svg/dart2js/svg_dart2js.dart',
categories: 'Client',
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM,
),
'web_audio': const LibraryInfo(
'web_audio/dart2js/web_audio_dart2js.dart',
categories: 'Client',
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM,
),
'web_gl': const LibraryInfo(
'web_gl/dart2js/web_gl_dart2js.dart',
categories: 'Client',
maturity: Maturity.WEB_STABLE,
platforms: DART2JS_PLATFORM,
),
'_internal': const LibraryInfo(
'internal/internal.dart',
categories: '',
documented: false,
dart2jsPatchPath: '_internal/js_runtime/lib/internal_patch.dart',
),
'_js_helper': const LibraryInfo(
'_internal/js_runtime/lib/js_helper.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_late_helper': const LibraryInfo(
'_internal/js_runtime/lib/late_helper.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_rti': const LibraryInfo(
'_internal/js_shared/lib/rti.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_dart2js_runtime_metrics': const LibraryInfo(
'_internal/js_runtime/lib/dart2js_runtime_metrics.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_interceptors': const LibraryInfo(
'_internal/js_runtime/lib/interceptors.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_foreign_helper': const LibraryInfo(
'_internal/js_runtime/lib/foreign_helper.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_js_names': const LibraryInfo(
'_internal/js_runtime/lib/js_names.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_js_primitives': const LibraryInfo(
'_internal/js_runtime/lib/js_primitives.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_js_embedded_names': const LibraryInfo(
'_internal/js_runtime/lib/synced/embedded_names.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_js_shared_embedded_names': const LibraryInfo(
'_internal/js_shared/lib/synced/embedded_names.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_js_types': const LibraryInfo(
'_internal/js_shared/lib/js_types.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_async_status_codes': const LibraryInfo(
'_internal/js_runtime/lib/synced/async_status_codes.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_recipe_syntax': const LibraryInfo(
'_internal/js_shared/lib/synced/recipe_syntax.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_load_library_priority': const LibraryInfo(
'_internal/js_runtime/lib/synced/load_library_priority.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_metadata': const LibraryInfo(
'html/html_common/metadata.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
'_js_annotations': const LibraryInfo(
'js/_js_annotations.dart',
categories: '',
documented: false,
platforms: DART2JS_PLATFORM,
),
};
@ -309,118 +170,18 @@ class LibraryInfo {
/// Path to the library's *.dart file relative to this file.
final String path;
/// The categories in which the library can be used encoded as a
/// comma-separated String.
final String _categories;
/// States the current maturity of this library.
final Maturity maturity;
/// Path to the dart2js library's *.dart file relative to this file
/// or null if dart2js uses the common library path defined above.
/// Access using the [#getDart2JsPath()] method.
final String? dart2jsPath;
/// Path to the dart2js library's patch file relative to this file
/// or null if no dart2js patch file associated with this library.
/// Access using the [#getDart2JsPatchPath()] method.
final String? dart2jsPatchPath;
/// True if this library is documented and should be shown to the user.
final bool documented;
/// Bit flags indicating which platforms consume this library.
/// See [DART2JS_LIBRARY] and [VM_LIBRARY].
final int platforms;
/// True if the library contains implementation details for another library.
/// The implication is that these libraries are less commonly used
/// and that tools like Dart Editor should not show these libraries
/// in a list of all libraries unless the user specifically asks the tool to
/// do so.
///
/// The implication is that tools should generally not show these libraries to
/// users.
final bool implementation;
const LibraryInfo(
this.path, {
String categories = '',
this.dart2jsPath,
this.dart2jsPatchPath,
this.implementation = false,
this.documented = true,
this.maturity = Maturity.UNSPECIFIED,
this.platforms = DART2JS_PLATFORM | VM_PLATFORM,
}) : _categories = categories;
bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0;
bool get isVmLibrary => (platforms & VM_PLATFORM) != 0;
/// The categories in which the library can be used.
///
/// If no categories are specified, the library is internal and can not be
/// loaded by user code.
List<Category> get categories {
// `"".split(,)` returns [""] not [], so we handle that case separately.
if (_categories.isEmpty) {
return const <Category>[];
} else {
return _categories
.split(',')
.map(parseCategory)
.whereType<Category>()
.toList();
}
}
bool get isInternal => categories.isEmpty;
/// The original "categories" String that was passed to the constructor.
///
/// Can be used to construct a slightly modified copy of this LibraryInfo.
String get categoriesString => _categories;
}
/// Abstraction to capture the maturity of a library.
class Maturity {
final int level;
final String name;
final String description;
const Maturity(this.level, this.name, this.description);
@override
String toString() => '$name: $level\n$description\n';
static const Maturity DEPRECATED = Maturity(0, 'Deprecated',
'This library will be remove before next major release.');
static const Maturity EXPERIMENTAL = Maturity(
1,
'Experimental',
'This library is experimental and will likely change or be removed\n'
'in future versions.');
static const Maturity UNSTABLE = Maturity(
2,
'Unstable',
'This library is in still changing and have not yet endured\n'
'sufficient real-world testing.\n'
'Backwards-compatibility is NOT guaranteed.');
static const Maturity WEB_STABLE = Maturity(
3,
'Web Stable',
'This library is tracking the DOM evolution as defined by WC3.\n'
'Backwards-compatibility is NOT guaranteed.');
static const Maturity STABLE = Maturity(
4,
'Stable',
'The library is stable. API backwards-compatibility is guaranteed.\n'
'However implementation details might change.');
static const Maturity LOCKED = Maturity(5, 'Locked',
'This library will not change except when serious bugs are encountered.');
static const Maturity UNSPECIFIED = Maturity(-1, 'Unspecified',
'The maturity for this library has not been specified.');
bool? implementation,
}) : this.implementation = implementation ?? !documented;
}

View file

@ -1,3 +1,4 @@
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.