[ddc] Use import URI to name a library
Import URIs are normalized by the CFE and should be globally unique in
the program. They serve as a good identifier to name a library in the
new "ddc" module format.
Change-Id: I9e255221bcffba52ad80138a4672d0490b7cbacd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/381781
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
diff --git a/pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js b/pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js
index 98a14b4..0b297c5 100644
--- a/pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js
+++ b/pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js
@@ -1367,7 +1367,7 @@
// See docs on `DartDevEmbedder.runMain`.
runMain(entryPointLibraryName, dartSdkRuntimeOptions) {
console.log('Setting Dart SDK runtime options.');
- let dartRuntimeLibrary = this.initializeAndLinkLibrary('dart');
+ let dartRuntimeLibrary = this.initializeAndLinkLibrary('dart:_runtime');
// TODO(nshahan) Use a single method in the Dart SDK to set all options.
dartRuntimeLibrary.weakNullSafetyErrors(dartSdkRuntimeOptions.weakNullSafetyErrors);
diff --git a/pkg/dev_compiler/lib/src/compiler/module_builder.dart b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
index 8961e8f..aaf8101 100644
--- a/pkg/dev_compiler/lib/src/compiler/module_builder.dart
+++ b/pkg/dev_compiler/lib/src/compiler/module_builder.dart
@@ -474,21 +474,21 @@
Identifier? moduleVar, ImportDeclaration import) {
var items = <Statement>[];
+ var fromName = import.from;
for (var importName in import.namedImports!) {
// import * is not emitted by the compiler, so we don't handle it here.
assert(!importName.isStar);
- var fromName = importName.name!.name;
var asName = importName.asName ?? importName.name;
if (import.from.valueWithoutQuotes != dartSdkModule) {
// Load non-SDK modules on demand (i.e., deferred).
items.add(js.statement(
'let # = dartDevEmbedder.importLibrary(#, function (lib) { '
'# = lib; });',
- [asName, js.string(fromName), asName]));
+ [asName, fromName, asName]));
} else {
- items.add(js.statement('const # = dartDevEmbedder.importLibrary(#)',
- [asName, js.string(fromName)]));
+ items.add(js.statement(
+ 'const # = dartDevEmbedder.importLibrary(#)', [asName, fromName]));
}
}
return items;
@@ -503,13 +503,11 @@
for (var export in exports) {
// Dart SDK module must export the libraries via a definition until it
// can be separated into individual libraries.
- var names = export.exportedNames!;
- for (var name in names) {
- var alias = name.asName ?? name.name!;
- items.add(js.statement(
- 'dartDevEmbedder.defineLibrary(#, function(_) { return #; })',
- [js.string(name.name!.name), alias]));
- }
+ var name = export.exportedNames!.single;
+ var alias = name.asName ?? name.name!;
+ items.add(js.statement(
+ 'dartDevEmbedder.defineLibrary(#, function(_) { return #; })',
+ [(export.exported as ExportClause).from, alias]));
}
}
return items;
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 06377fd..d3a4462 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -7934,39 +7934,71 @@
items.add(js.statement('#.library = #', [_runtimeModule, libraryProto]));
exports.add(js_ast.NameSpecifier(_runtimeModule));
}
-
- for (var library in libraries) {
- if (_isBuildingSdk && _isSdkInternalRuntime(library)) {
- _libraries[library] = _runtimeModule;
- continue;
+ if (_options.emitLibraryBundle) {
+ assert(_isBuildingSdk);
+ for (var library in libraries) {
+ js_ast.Identifier libraryId;
+ if (_isSdkInternalRuntime(library)) {
+ libraryId = _runtimeModule;
+ } else if (_isDartLibrary(library, '_rti')) {
+ libraryId = _rtiLibraryId;
+ } else {
+ libraryId = js_ast.TemporaryId(_jsLibraryName(library));
+ }
+ _libraries[library] = libraryId;
+ var alias = _jsLibraryAlias(library);
+ var aliasId = alias == null ? null : js_ast.TemporaryId(alias);
+ items.add(js_ast.ExportDeclaration(js_ast.ExportClause(
+ [js_ast.NameSpecifier(libraryId, asName: aliasId)],
+ from: js.string('${library.importUri}'))));
+ // The initialization object for the runtime library is created above so
+ // it is skipped here.
+ if (_isSdkInternalRuntime(library)) continue;
+ items.add(js.statement(
+ 'const # = Object.create(#.library)', [libraryId, _runtimeModule]));
}
- var libraryId = _isBuildingSdk && _isDartLibrary(library, '_rti')
- ? _rtiLibraryId
- : js_ast.TemporaryId(_jsLibraryName(library));
+ // dart:_runtime has a magic library that holds extension method symbols.
+ // TODO(nshahan): Could this be created with a kernel transform or just
+ // become a member in dart:_runtime?
+ items.add(js.statement('const # = Object.create(#.library)',
+ [_extensionSymbolsModule, _runtimeModule]));
+ items.add(js_ast.ExportDeclaration(js_ast.ExportClause(
+ [js_ast.NameSpecifier(_extensionSymbolsModule)],
+ from: js.string('dartx'))));
+ } else {
+ for (var library in libraries) {
+ if (_isBuildingSdk && _isSdkInternalRuntime(library)) {
+ _libraries[library] = _runtimeModule;
+ continue;
+ }
+ var libraryId = _isBuildingSdk && _isDartLibrary(library, '_rti')
+ ? _rtiLibraryId
+ : js_ast.TemporaryId(_jsLibraryName(library));
- _libraries[library] = libraryId;
- var alias = _jsLibraryAlias(library);
- var aliasId = alias == null ? null : js_ast.TemporaryId(alias);
+ _libraries[library] = libraryId;
+ var alias = _jsLibraryAlias(library);
+ var aliasId = alias == null ? null : js_ast.TemporaryId(alias);
- // TODO(vsm): Change back to `const`.
- // See https://github.com/dart-lang/sdk/issues/40380.
- items.add(js.statement(
- 'var # = Object.create(#.library)', [libraryId, _runtimeModule]));
- exports.add(js_ast.NameSpecifier(libraryId, asName: aliasId));
+ // TODO(vsm): Change back to `const`.
+ // See https://github.com/dart-lang/sdk/issues/40380.
+ items.add(js.statement(
+ 'var # = Object.create(#.library)', [libraryId, _runtimeModule]));
+ exports.add(js_ast.NameSpecifier(libraryId, asName: aliasId));
+ }
+
+ // dart:_runtime has a magic module that holds extension method symbols.
+ // TODO(jmesserly): find a cleaner design for this.
+ if (_isBuildingSdk) {
+ var id = _extensionSymbolsModule;
+ // TODO(vsm): Change back to `const`.
+ // See https://github.com/dart-lang/sdk/issues/40380.
+ items.add(js.statement(
+ 'var # = Object.create(#.library)', [id, _runtimeModule]));
+ exports.add(js_ast.NameSpecifier(id));
+ }
+ items.add(js_ast.ExportDeclaration(js_ast.ExportClause(exports)));
}
- // dart:_runtime has a magic module that holds extension method symbols.
- // TODO(jmesserly): find a cleaner design for this.
- if (_isBuildingSdk) {
- var id = _extensionSymbolsModule;
- // TODO(vsm): Change back to `const`.
- // See https://github.com/dart-lang/sdk/issues/40380.
- items.add(js
- .statement('var # = Object.create(#.library)', [id, _runtimeModule]));
- exports.add(js_ast.NameSpecifier(id));
- }
- items.add(js_ast.ExportDeclaration(js_ast.ExportClause(exports)));
-
if (_isBuildingSdk) {
// Initialize the private name function.
// To bootstrap the SDK, this needs to be emitted before other code.
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart
index daee98b..22bf41c 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart
@@ -867,15 +867,14 @@
// Emit the hoisted instantiated generic class table cache variables
items.addAll(_genericClassTable.dischargeBoundTypes());
_ticker?.logMs('Emitted instantiated generic class table');
-
- var module = _finishLibrary(
- items, _jsLibraryName(library), _emitLibraryName(library));
+ var compiledLibrary = _finishLibrary(
+ items, '${library.importUri}', _emitLibraryName(library));
_ticker?.logMs('Finished emitting module');
// Mark as finished for incremental mode, so it is safe to
// switch to the incremental mode for expression compilation.
_moduleEmitted = true;
- return module;
+ return compiledLibrary;
}
/// Choose a canonical name from the [library] element.
@@ -8023,36 +8022,38 @@
// import {foo} from 'foo'; // if no rename needed
// import {foo as foo$} from 'foo'; // if rename was needed
//
- var imports = <js_ast.NameSpecifier>[];
for (var library in libraries) {
if (!_incrementalMode ||
usedLibraries!.contains(_jsLibraryName(library))) {
var alias = _jsLibraryAlias(library);
if (alias != null) {
var aliasId = js_ast.TemporaryId(alias);
- imports.add(
- js_ast.NameSpecifier(aliasId, asName: _imports[library]));
+ items.add(js_ast.ImportDeclaration(
+ from: js.string('${library.importUri}'),
+ namedImports: [
+ js_ast.NameSpecifier(aliasId, asName: _imports[library])
+ ]));
} else {
- imports.add(js_ast.NameSpecifier(_imports[library]));
+ items.add(js_ast.ImportDeclaration(
+ from: js.string('${library.importUri}'),
+ namedImports: [js_ast.NameSpecifier(_imports[library])]));
}
}
}
-
if (module == coreModuleName) {
if (!_incrementalMode ||
usedLibraries!.contains(_runtimeModule.name)) {
- imports.add(js_ast.NameSpecifier(_runtimeModule));
+ items.add(js_ast.ImportDeclaration(
+ from: js.string('dart:_runtime'),
+ namedImports: [js_ast.NameSpecifier(_runtimeModule)]));
}
if (!_incrementalMode ||
usedLibraries!.contains(_extensionSymbolsModule.name)) {
- imports.add(js_ast.NameSpecifier(_extensionSymbolsModule));
+ items.add(js_ast.ImportDeclaration(
+ from: js.string('dartx'),
+ namedImports: [js_ast.NameSpecifier(_extensionSymbolsModule)]));
}
}
-
- if (!_incrementalMode || imports.isNotEmpty) {
- items.add(js_ast.ImportDeclaration(
- namedImports: imports, from: js.string(module, "'")));
- }
}
});
}
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index ff953fa..4f7eedc 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -25,8 +25,8 @@
print('Usage: ddb [options] <dart-script-file>\n');
print('Compiles <dart-script-file> with the dev_compiler and runs it on a '
'JS platform.\n'
- 'Optionally, mulitple Dart source files can be passed as arguments and '
- 'they will be compiled into seperate modules in the order provided. '
+ 'Optionally, multiple Dart source files can be passed as arguments and '
+ 'they will be compiled into separate modules in the order provided. '
'The order will be treated as an import DAG with the last file as the '
'application entrypoint. The .dill file outputs from each compile will '
'be collected and passed as dependency summaries for the next compile '
@@ -281,6 +281,10 @@
if (options['packages'] != null) '--packages=${options['packages']}',
if (emitDebugSymbols) '--emit-debug-symbols',
if (canaryFeatures) '--canary',
+ // Provide predictable library URIs for all libraries when using the
+ // new ddc module format.
+ if (canaryFeatures) '--multi-root-scheme=ddb',
+ if (canaryFeatures) '--multi-root=/',
];
var summaryFiles = [];
for (var sourceFile in sourceFiles) {
@@ -289,27 +293,28 @@
for (var summary in summaryFiles) '--summary=$summary',
'-o',
out,
- sourceFile,
+ if (canaryFeatures) 'ddb:$sourceFile' else sourceFile,
];
await runDdc([...ddcArgs, ...requestArgs]);
outputs.add(out);
var summaryFile = p.setExtension(out, '.dill');
- var libname =
- js_names.pathToJSIdentifier(p.basenameWithoutExtension(sourceFile));
+ var libname = canaryFeatures
+ ? 'ddb:$sourceFile'
+ : js_names.pathToJSIdentifier(p.basenameWithoutExtension(sourceFile));
summaryFiles.add('$summaryFile=$libname');
}
}
if (run) {
- var ddcModuleSdkOptions = canaryFeatures ?
-'''let sdkOptions = {
-weakNullSafetyWarnings: !($weakNullSafetyErrors || $soundNullSafety),
+ var ddcModuleSdkOptions = canaryFeatures
+ ? '''let sdkOptions = {
+ weakNullSafetyWarnings: !($weakNullSafetyErrors || $soundNullSafety),
weakNullSafetyErrors: $weakNullSafetyErrors,
nonNullAsserts: $nonNullAsserts,
nativeNonNullAsserts: $nativeNonNullAsserts,
jsInteropNonNullAsserts: $jsInteropNonNullAsserts,
-};''' :
-'''
+};'''
+ : '''
let sdk = dart_library.import("dart_sdk", "$appname");
sdk.dart.weakNullSafetyWarnings(!($weakNullSafetyErrors || $soundNullSafety));
sdk.dart.weakNullSafetyErrors($weakNullSafetyErrors);
@@ -318,9 +323,9 @@
sdk.dart.jsInteropNonNullAsserts($jsInteropNonNullAsserts);
''';
var ddcModuleRunMain = canaryFeatures
- ? 'dartDevEmbedder.runMain("$libname", sdkOptions);'
- : 'dart_library.start('
- '"$appname", "$uuid", "$basename", "$libname", false);';
+ ? 'dartDevEmbedder.runMain("ddb:$entryPoint", sdkOptions);'
+ : 'dart_library.start('
+ '"$appname", "$uuid", "$basename", "$libname", false);';
if (chrome) {
String chromeBinary;
if (binary != null) {
@@ -437,11 +442,11 @@
} else if (d8) {
var ddcModuleScriptTags =
[for (var output in outputs) 'load("$output");'].join('\n');
- var ddcModuleAssignGlobalSelf = canaryFeatures ?
- '''
-let dart = dartDevEmbedder.importLibrary("dart");
-dart.global.self = dart.global;''':
- 'sdk.dart.global.self = sdk.dart.global;';
+ var ddcModuleAssignGlobalSelf = canaryFeatures
+ ? '''
+let dart = dartDevEmbedder.importLibrary("dart:_runtime");
+dart.global.self = dart.global;'''
+ : 'sdk.dart.global.self = sdk.dart.global;';
var runjs = '''
load("$ddcPath/lib/js/ddc/ddc_module_loader.js");
load("$sdkJsPath/dart_sdk.js");