Revamp patch_sdk.dart mainly to use libraries.json.

This will make it possible to use the script to create a patched sdk
for dart2js and the vm (some followup needed), which will be useful
to migrate their libraries to nnbd.

In the future, we should be able to leverage this new logic to
write tests that ensure our sdk is warning-free (there are > 80 real
warnings today even on the non-nnbd sdk)

In detail, this CL includes:

* loading the libraries data from libraries.json, this removes the need for a
   hand-crafted libraries.dart that replicates the data in libraries.json.

* auto-generates a libraries.dart in the patched sdk that can be used to run
 dartanalyzer or to compile an sdk with dartdevc-legacy.

* script simplifications in patch_sdk.dart
    * removed tracking of modification stamps. This didn't appeared to be
      used by the ninja rules. I believe it was used to reduce local
      iteration cycles when we were first developing the sdk itself.

    * use Uri directly instead of package:path - this simplifies things,
      especially since the libraries_specification is Uri-based as well.

    * switch to use package:args for parsing options

 * added an option to merge part files in a single file. I've noticed that the
 analyzer provides some false positive errors in part files, but once merged
 they are no longer shown. In particular, we are clearly hitting limitations of
 dartanalyzer on the patched sdk. At this time the old patch-script generated
 an sdk with 1500 warnings, this new script reduces it to 500 (not sure why),
 with merging of part files it goes down to 80.


Change-Id: I6bbaf92ef4554f00c8bf6b38d19bf79d44fb3e94
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/125780
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Sigmund Cherem 2019-11-20 22:51:42 +00:00 committed by commit-bot@chromium.org
parent be519e83b1
commit 3c9e924073
5 changed files with 240 additions and 775 deletions

View file

@ -23,8 +23,8 @@ Options _options;
String _dartdevcScript;
String _buildSdkScript;
String _patchSdkScript;
String _sdkDevRuntime;
String _sdkDevRuntimeNnbd;
String _librariesJson;
String _librariesJsonNnbd;
main(List<String> args) async {
_options = Options.parse(args);
@ -90,10 +90,13 @@ class DDCStep implements IOModularStep {
Platform.resolvedExecutable,
[
_patchSdkScript,
sdkRoot.toFilePath(),
if (nnbd) _sdkDevRuntimeNnbd else _sdkDevRuntime,
'patched_sdk',
if (nnbd) 'sdk_nnbd'
'--target',
'dartdevc',
'--libraries',
if (nnbd) _librariesJsonNnbd else _librariesJson,
'--out',
'patched_sdk/',
if (nnbd) '--nnbd'
],
root.toFilePath());
_checkExitCode(result, this, module);
@ -320,6 +323,6 @@ Future<void> _resolveScripts() async {
'pkg/dev_compiler/bin/dartdevc.dart', 'snapshots/dartdevc.dart.snapshot');
_buildSdkScript = await resolve('pkg/dev_compiler/tool/build_sdk.dart');
_patchSdkScript = await resolve('pkg/dev_compiler/tool/patch_sdk.dart');
_sdkDevRuntime = await resolve('sdk/lib/_internal/js_dev_runtime');
_sdkDevRuntimeNnbd = await resolve('sdk_nnbd/lib/_internal/js_dev_runtime');
_librariesJson = await resolve('sdk/lib/libraries.json');
_librariesJsonNnbd = await resolve('sdk_nnbd/lib/libraries.json');
}

View file

@ -7,169 +7,137 @@
/// This is currently designed as an offline tool, but we could automate it.
import 'dart:io';
import 'dart:math' as math;
import 'package:_fe_analyzer_shared/src/util/relativize.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:path/path.dart' as p;
import 'package:args/args.dart';
import 'package:front_end/src/base/libraries_specification.dart';
import 'package:front_end/src/fasta/resolve_input_uri.dart';
void main(List<String> argv) {
var self = p.relative(p.fromUri(Platform.script));
if (argv.length < 3) {
var toolDir = p.relative(p.dirname(p.fromUri(Platform.script)));
var dartDir =
p.dirname(p.dirname(p.dirname(p.dirname(p.fromUri(Platform.script)))));
var repoExample = p.join(toolDir, '..', '..', '..');
var patchExample =
p.join(dartDir, 'sdk', 'lib', '_internal', 'js_dev_runtime');
var outExample = p.relative(p.normalize(p.join('gen', 'patched_sdk')));
print('Usage: $self DART_REPO_DIR PATCH_DIR OUTPUT_DIR');
var args = _parser.parse(argv);
if (args['libraries'] == null || args['out'] == null) {
var self = relativizeUri(Uri.base, Platform.script, isWindows);
var librariesJson = relativizeUri(Uri.base,
Platform.script.resolve('../../../sdk/lib/libraries.json'), isWindows);
print('Usage: $self [other options]'
' --libraries <libraries.json> --out <output-dir>');
print('For example:');
print('\$ $self $repoExample $patchExample $outExample');
print('\$ $self --nnbd --libraries $librariesJson --out patched-sdk-dir');
exit(1);
}
var sdk = 'sdk';
var useNnbd = false;
if (argv.length > 3) {
sdk = argv[3];
var useNnbd = args['nnbd'] as bool;
var target = args['target'] as String;
var jsonUri = resolveInputUri(args['libraries'] as String);
var libRoot = jsonUri.resolve('./');
var outPath = args['out'] as String;
var outDir = resolveInputUri(outPath.endsWith('/') ? outPath : '$outPath/');
var outLibRoot = outDir.resolve('lib/');
// TODO(38701): While the core libraries have been forked for NNBD, use the
// SDK directory name to determine whether to enable the NNBD experiment
// when parsing the lib sources. Once the libraries have been unforked, we
// should unconditionally enable the experiment flag since then the
// canonical SDK libs will use NNBD syntax.
useNnbd = sdk.contains("nnbd");
}
var inputVersion = Platform.script.resolve('../../../tools/VERSION');
var outVersion = outDir.resolve('version');
var selfModifyTime = File(self).lastModifiedSync().millisecondsSinceEpoch;
var repoDir = argv[0];
var patchDir = argv[1];
var sdkLibIn = p.join(repoDir, sdk, 'lib');
var patchIn = p.join(patchDir, 'patch');
var privateIn = p.join(patchDir, 'private');
var sdkOut = p.join(argv[2], 'lib');
var INTERNAL_PATH = '_internal/js_runtime/lib/';
var specification = LibrariesSpecification.parse(
jsonUri, File.fromUri(jsonUri).readAsStringSync())
.specificationFor(target);
// Copy libraries.dart and version
var librariesDart = p.join(patchDir, 'libraries.dart');
var libContents = File(librariesDart).readAsStringSync();
// TODO(jmesserly): can we remove this?
_writeSync(p.join(sdkOut, '_internal', 'libraries.dart'), libContents);
_writeSync(
p.join(
sdkOut, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'),
libContents);
_writeSync(p.join(sdkOut, '..', 'version'),
File(p.join(repoDir, 'tools', 'VERSION')).readAsStringSync());
_writeSync(outVersion, File.fromUri(inputVersion).readAsStringSync());
// Parse libraries.dart
var sdkLibraries = _getSdkLibraries(libContents, useNnbd: useNnbd);
// Enumerate core libraries and apply patches
for (SdkLibrary library in sdkLibraries) {
// TODO(jmesserly): analyzer does not handle the default case of
// "both platforms" correctly, and treats it as being supported on neither.
// So instead we skip explicitly marked as VM libs.
if (library.isVmLibrary) continue;
var libraryOut = p.join(sdkLibIn, library.path);
var libraryOverride = p.join(patchDir, 'lib', library.path);
String libraryIn;
if (library.path.contains(INTERNAL_PATH)) {
libraryIn = p.join(privateIn, library.path.replaceAll(INTERNAL_PATH, ''));
} else if (File(libraryOverride).existsSync()) {
libraryIn = libraryOverride;
} else {
libraryIn = libraryOut;
}
var libraryFile = File(libraryIn);
// Enumerate sdk libraries and apply patches
for (var library in specification.allLibraries) {
var libraryFile = File.fromUri(library.uri);
var libraryOut =
outLibRoot.resolve(relativizeLibraryUri(libRoot, library.uri, useNnbd));
if (libraryFile.existsSync()) {
var outPaths = <String>[libraryOut];
var outUris = <Uri>[libraryOut];
var libraryContents = libraryFile.readAsStringSync();
var contents = <String>[libraryContents];
int inputModifyTime = math.max(selfModifyTime,
libraryFile.lastModifiedSync().millisecondsSinceEpoch);
var partFiles = <File>[];
for (var part
in _parseString(libraryContents, useNnbd: useNnbd).unit.directives) {
if (part is PartDirective) {
var partPath = part.uri.stringValue;
outPaths.add(p.join(p.dirname(libraryOut), partPath));
var partFile = File(p.join(p.dirname(libraryIn), partPath));
partFiles.add(partFile);
inputModifyTime = math.max(inputModifyTime,
partFile.lastModifiedSync().millisecondsSinceEpoch);
outUris.add(libraryOut.resolve(partPath));
contents.add(
File.fromUri(library.uri.resolve(partPath)).readAsStringSync());
}
}
// See if we can find a patch file.
var patchPath = p.join(
patchIn, p.basenameWithoutExtension(libraryIn) + '_patch.dart');
var patchFile = File(patchPath);
bool patchExists = patchFile.existsSync();
if (patchExists) {
inputModifyTime = math.max(inputModifyTime,
patchFile.lastModifiedSync().millisecondsSinceEpoch);
if (args['merge-parts'] as bool && outUris.length > 1) {
outUris.length = 1;
contents = [
contents
.join('\n')
.replaceAll(RegExp("^part [^\n]*\$", multiLine: true), "")
];
}
// Compute output paths
outPaths = outPaths
.map((path) => p.join(sdkOut, p.relative(path, from: sdkLibIn)))
.toList();
var buffer = StringBuffer();
for (var patchUri in library.patches) {
// Note: VM targets enumerate more than one patch file, they are
// currently written so that the first file is a valid patch file and
// all other files can be appended at the end.
buffer.write(File.fromUri(patchUri).readAsStringSync());
}
var patchContents = '$buffer';
// Compare output modify time with input modify time.
bool needsUpdate = false;
for (var outPath in outPaths) {
var outFile = File(outPath);
if (!outFile.existsSync() ||
outFile.lastModifiedSync().millisecondsSinceEpoch <
inputModifyTime) {
needsUpdate = true;
break;
}
if (patchContents.isNotEmpty) {
contents = _patchLibrary(contents, patchContents, useNnbd: useNnbd);
}
if (needsUpdate) {
var contents = <String>[libraryContents];
contents.addAll(partFiles.map((f) => f.readAsStringSync()));
if (patchExists) {
var patchContents = patchFile.readAsStringSync();
contents = _patchLibrary(contents, patchContents, useNnbd: useNnbd);
}
if (contents != null) {
for (var i = 0; i < outPaths.length; i++) {
_writeSync(outPaths[i], contents[i]);
}
} else {
exitCode = 2;
if (contents != null) {
for (var i = 0; i < outUris.length; i++) {
_writeSync(outUris[i], contents[i]);
}
} else {
exitCode = 2;
}
}
}
var outLibrariesDart =
outLibRoot.resolve('_internal/sdk_library_metadata/lib/libraries.dart');
_writeSync(outLibrariesDart,
_generateLibrariesDart(libRoot, specification, useNnbd));
}
/// Writes a file, creating the directory if needed.
void _writeSync(String filePath, String contents) {
var outDir = Directory(p.dirname(filePath));
void _writeSync(Uri fileUri, String contents) {
var outDir = Directory.fromUri(fileUri.resolve('.'));
if (!outDir.existsSync()) outDir.createSync(recursive: true);
File(filePath).writeAsStringSync(contents);
File.fromUri(fileUri).writeAsStringSync(contents);
}
final _parser = ArgParser()
..addFlag('nnbd',
help: 'Whether to enable the nnbd feature.', defaultsTo: false)
..addFlag('merge-parts',
help: 'Whether to merge part files. '
'Technically this is not necessary, but dartanalyzer '
'produces less warnings when enabling this flag.',
defaultsTo: false)
..addOption('libraries',
help: 'Path to a libraries.json specification file (required). '
'All libary URIs within libraries.json are expected to be somewhere '
'under the directory containing the libraries.json file. Reaching '
'out above such directory is generally not supported. Today it is '
'only allowed for the nnbd sdk to reuse libraries of the non-nnbd '
'sdk, in which case the path starts with "../../sdk/lib/".')
..addOption('out', help: 'Path to an output folder (required).')
..addOption('target',
help: 'The target tool. '
'This name matches one of the possible targets in libraries.json '
'and it is used to pick which patch files will be applied.',
allowed: ['dartdevc', 'dart2js', 'dart2js_server', 'vm', 'flutter']);
/// Merges dart:* library code with code from *_patch.dart file.
///
/// Takes a list of the library's parts contents, with the main library contents
@ -490,16 +458,142 @@ class _StringEdit implements Comparable<_StringEdit> {
}
}
List<SdkLibrary> _getSdkLibraries(String contents, {bool useNnbd}) {
// TODO(jmesserly): fix SdkLibrariesReader_LibraryBuilder in Analyzer.
// It doesn't understand optional new/const in Dart 2. For now, we keep
// redundant `const` in tool/input_sdk/libraries.dart as a workaround.
var libraryBuilder = SdkLibrariesReader_LibraryBuilder();
_parseString(contents, useNnbd: useNnbd).unit.accept(libraryBuilder);
return libraryBuilder.librariesMap.sdkLibraries;
}
ParseStringResult _parseString(String source, {bool useNnbd}) {
var features = FeatureSet.fromEnableFlags([if (useNnbd) "non-nullable"]);
return parseString(content: source, featureSet: features);
}
/// Use the data from a libraries.json specification to generate the contents
/// of `sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart`, which is
/// needed by dartdevc-legacy and dartanalyzer.
String _generateLibrariesDart(
Uri libBaseUri, TargetLibrariesSpecification specification, bool usdNnbd) {
var contents = StringBuffer();
contents.write(_LIBRARIES_DART_PREFIX);
for (var library in specification.allLibraries) {
var path = relativizeLibraryUri(libBaseUri, library.uri, usdNnbd);
contents.write(' "${library.name}": \n'
' const LibraryInfo("$path",\n'
' categories: "Client,Server"),\n');
}
contents.write(_LIBRARIES_DART_SUFFIX);
return '$contents';
}
String relativizeLibraryUri(Uri libRoot, Uri uri, bool useNnbd) {
String relativePath = relativizeUri(libRoot, uri, isWindows);
// During the nnbd-migration we may have paths that reach out into the
// non-nnbd directory.
if (relativePath.startsWith("..")) {
if (!useNnbd || !relativePath.startsWith('../../sdk/lib/')) {
print("error: can't handle libraries that live out of the sdk folder"
": $relativePath");
exit(1);
}
relativePath = relativePath.replaceFirst('../../sdk/lib/', '');
}
return relativePath;
}
final _LIBRARIES_DART_PREFIX = r'''
library libraries;
const int DART2JS_PLATFORM = 1;
const int VM_PLATFORM = 2;
enum Category { client, server, embedded }
Category parseCategory(String name) {
switch (name) {
case "Client":
return Category.client;
case "Server":
return Category.server;
case "Embedded":
return Category.embedded;
}
return null;
}
const Map<String, LibraryInfo> libraries = const {
''';
final _LIBRARIES_DART_SUFFIX = r'''
};
class LibraryInfo {
final String path;
final String _categories;
final String dart2jsPath;
final String dart2jsPatchPath;
final bool documented;
final int platforms;
final bool implementation;
final Maturity maturity;
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;
List<Category> get categories {
// `"".split(,)` returns [""] not [], so we handle that case separately.
if (_categories == "") return const <Category>[];
return _categories.split(",").map(parseCategory).toList();
}
bool get isInternal => categories.isEmpty;
String get categoriesString => _categories;
}
class Maturity {
final int level;
final String name;
final String description;
const Maturity(this.level, this.name, this.description);
String toString() => "$name: $level\n$description\n";
static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
"This library will be remove before next major release.");
static const Maturity EXPERIMENTAL = const Maturity(
1,
"Experimental",
"This library is experimental and will likely change or be removed\n"
"in future versions.");
static const Maturity UNSTABLE = const 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 = const 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 = const Maturity(
4,
"Stable",
"The library is stable. API backwards-compatibility is guaranteed.\n"
"However implementation details might change.");
static const Maturity LOCKED = const Maturity(5, "Locked",
"This library will not change except when serious bugs are encountered.");
static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
"The maturity for this library has not been specified.");
}
''';

View file

@ -1,312 +0,0 @@
// 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.
// @dart = 2.6
library libraries;
/**
* 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;
}
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"),
"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",
documented: false,
implementation: true),
"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/dart2js/js_dart2js.dart",
categories: "Client",
maturity: Maturity.STABLE,
platforms: DART2JS_PLATFORM),
"js_util": const LibraryInfo("js_util/dart2js/js_util_dart2js.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.dart"),
"nativewrappers": const LibraryInfo("html/dartium/nativewrappers.dart",
categories: "Client",
implementation: true,
documented: false,
platforms: DART2JS_PLATFORM),
"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),
"cli": const LibraryInfo("cli/cli.dart",
categories: "Server",
dart2jsPatchPath: "_internal/js_runtime/lib/cli_patch.dart"),
"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),
"web_sql": const LibraryInfo("web_sql/dart2js/web_sql_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),
"_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),
"_isolate_helper": const LibraryInfo(
"_internal/js_runtime/lib/isolate_helper.dart",
categories: "",
documented: false,
platforms: DART2JS_PLATFORM),
"_js_mirrors": const LibraryInfo("_internal/js_runtime/lib/js_mirrors.dart",
categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_js_primitives": const LibraryInfo(
"_internal/js_runtime/lib/js_primitives.dart",
categories: "",
documented: false,
platforms: DART2JS_PLATFORM),
"_metadata": const LibraryInfo("html/html_common/metadata.dart",
categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_debugger": const LibraryInfo("_internal/js_runtime/lib/debugger.dart",
category: "", documented: false, platforms: DART2JS_PLATFORM),
"_runtime": const LibraryInfo(
"_internal/js_runtime/lib/ddc_runtime/runtime.dart",
category: "",
documented: false,
platforms: DART2JS_PLATFORM),
};
/**
* Information about a "dart:" library.
*/
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;
/**
* 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.
*/
final bool implementation;
/**
* States the current maturity of this library.
*/
final Maturity maturity;
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 == "") return const <Category>[];
return _categories.split(",").map(parseCategory).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 {
return _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);
String toString() => "$name: $level\n$description\n";
static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
"This library will be remove before next major release.");
static const Maturity EXPERIMENTAL = const Maturity(
1,
"Experimental",
"This library is experimental and will likely change or be removed\n"
"in future versions.");
static const Maturity UNSTABLE = const 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 = const 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 = const Maturity(
4,
"Stable",
"The library is stable. API backwards-compatibility is guaranteed.\n"
"However implementation details might change.");
static const Maturity LOCKED = const Maturity(5, "Locked",
"This library will not change except when serious bugs are encountered.");
static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
"The maturity for this library has not been specified.");
}

View file

@ -1,312 +0,0 @@
// 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.
// @dart = 2.5
library libraries;
/**
* 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;
}
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"),
"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",
documented: false,
implementation: true),
"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/dart2js/js_dart2js.dart",
categories: "Client",
maturity: Maturity.STABLE,
platforms: DART2JS_PLATFORM),
"js_util": const LibraryInfo("js_util/dart2js/js_util_dart2js.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.dart"),
"nativewrappers": const LibraryInfo("html/dartium/nativewrappers.dart",
categories: "Client",
implementation: true,
documented: false,
platforms: DART2JS_PLATFORM),
"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),
"cli": const LibraryInfo("cli/cli.dart",
categories: "Server",
dart2jsPatchPath: "_internal/js_runtime/lib/cli_patch.dart"),
"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),
"web_sql": const LibraryInfo("web_sql/dart2js/web_sql_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),
"_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),
"_isolate_helper": const LibraryInfo(
"_internal/js_runtime/lib/isolate_helper.dart",
categories: "",
documented: false,
platforms: DART2JS_PLATFORM),
"_js_mirrors": const LibraryInfo("_internal/js_runtime/lib/js_mirrors.dart",
categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_js_primitives": const LibraryInfo(
"_internal/js_runtime/lib/js_primitives.dart",
categories: "",
documented: false,
platforms: DART2JS_PLATFORM),
"_metadata": const LibraryInfo("html/html_common/metadata.dart",
categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_debugger": const LibraryInfo("_internal/js_runtime/lib/debugger.dart",
category: "", documented: false, platforms: DART2JS_PLATFORM),
"_runtime": const LibraryInfo(
"_internal/js_runtime/lib/ddc_runtime/runtime.dart",
category: "",
documented: false,
platforms: DART2JS_PLATFORM),
};
/**
* Information about a "dart:" library.
*/
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;
/**
* 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.
*/
final bool implementation;
/**
* States the current maturity of this library.
*/
final Maturity maturity;
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 == "") return const <Category>[];
return _categories.split(",").map(parseCategory).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 {
return _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);
String toString() => "$name: $level\n$description\n";
static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
"This library will be remove before next major release.");
static const Maturity EXPERIMENTAL = const Maturity(
1,
"Experimental",
"This library is experimental and will likely change or be removed\n"
"in future versions.");
static const Maturity UNSTABLE = const 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 = const 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 = const Maturity(
4,
"Stable",
"The library is stable. API backwards-compatibility is guaranteed.\n"
"However implementation details might change.");
static const Maturity LOCKED = const Maturity(5, "Locked",
"This library will not change except when serious bugs are encountered.");
static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
"The maturity for this library has not been specified.");
}

View file

@ -129,8 +129,6 @@ dart2js_compile("stack_trace_mapper") {
# Apply dev_compiler's patch files to create the Dart version of the dartdevc
# SDK.
prebuilt_dart_action("dartdevc_patch_sdk") {
# TODO(rnystrom): Unfork DDC's patch_sdk.dart script with the
# tools/patch_sdk.dart and then change this to use generate_patch_sdk().
deps = [
":dartdevc_files_stamp",
":dartdevc_sdk_patch_stamp",
@ -142,17 +140,8 @@ prebuilt_dart_action("dartdevc_patch_sdk") {
script = "../../pkg/dev_compiler/tool/patch_sdk.dart"
# The main SDK library sources.
inputs = sdk_lib_files
# dev_compiler's additional sources and patch files.
inputs += exec_script("../../tools/list_dart_files.py",
[
"absolute",
rebase_path("$sdk_root/lib/_internal/js_dev_runtime"),
],
"list lines")
# Arbitrarily use the version file as a token file to check against to see if
# the sources have changed.
# TODO(rnystrom): List the outputs more precisely?
@ -161,14 +150,17 @@ prebuilt_dart_action("dartdevc_patch_sdk") {
]
args = [
rebase_path("../../"),
rebase_path("$sdk_root/lib/_internal/js_dev_runtime"),
rebase_path(patched_sdk_dir),
"--libraries",
rebase_path("$sdk_root/lib/libraries.json"),
"--target",
"dartdevc",
"--out",
rebase_path("$patched_sdk_dir/"),
]
# TODO(#38701) Cleanup after merging the forked SDK into mainline.
if (use_nnbd) {
args += [ "sdk_nnbd" ]
args += [ "--nnbd" ]
}
}