diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index f4ff5630b68..da947f06ebe 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart @@ -608,16 +608,25 @@ class ProgramCompiler extends ComputeOnceConstantVisitor } @override - String libraryToModule(Library library) { + String libraryToModule(Library library, {bool throwIfNotFound = true}) { if (library.importUri.isScheme('dart')) { // TODO(jmesserly): we need to split out HTML. return js_ast.dartSdkModule; } - var summary = _importToSummary[library]!; + var summary = _importToSummary[library]; + if (summary == null) { + if (throwIfNotFound) { + throw StateError('Could not find summary for library "$library".'); + } + return ''; + } var moduleName = _summaryToModule[summary]; if (moduleName == null) { - throw StateError('Could not find module name for library "$library" ' - 'from component "$summary".'); + if (throwIfNotFound) { + throw StateError('Could not find module name for library "$library" ' + 'from component "$summary".'); + } + return ''; } return moduleName; } @@ -7050,9 +7059,11 @@ class ProgramCompiler extends ComputeOnceConstantVisitor @override js_ast.Expression visitLoadLibrary(LoadLibrary node) => - runtimeCall('loadLibrary(#, #)', [ + runtimeCall('loadLibrary(#, #, #)', [ js.string(node.import.enclosingLibrary.importUri.toString()), - js.string(node.import.name!) + js.string(node.import.name!), + js.string( + libraryToModule(node.import.targetLibrary, throwIfNotFound: false)) ]); // TODO(jmesserly): DDC loads all libraries eagerly. diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart index d79a8adf1c9..fc3e66390cf 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart @@ -856,32 +856,51 @@ _canonicalMember(obj, name) { return name; } +@notNull +bool _realDeferredLoading = false; + +/// Sets the runtime mode to perform deferred loading (instead of just runtime +/// correctness checks on loaded libraries). +/// +/// This is only supported in the DDC module system. +void realDeferredLoading(bool enable) { + _realDeferredLoading = enable; +} + /// A map from libraries to a set of import prefixes that have been loaded. /// /// Used to validate deferred library conventions. final deferredImports = JS('!', 'new Map()'); -/// Emulates the implicit "loadLibrary" function provided by a deferred library. +/// Loads the element [importPrefix] in the module [targetModule] from the +/// context of the library [libraryUri]. /// -/// Libraries are not actually deferred in DDC, so this just records the import -/// for runtime validation, then returns a future that completes immediately. -Future loadLibrary( - @notNull String enclosingLibrary, @notNull String importPrefix) { - var result = JS('', '#.get(#)', deferredImports, enclosingLibrary); - if (JS('', '# === void 0', result)) { - JS('', '#.set(#, # = new Set())', deferredImports, enclosingLibrary, - result); +/// Will load any modules required by [targetModule] as a side effect. +/// Only supported in the DDC module system. +Future loadLibrary(@notNull String libraryUri, + @notNull String importPrefix, @notNull String targetModule) { + if (!_realDeferredLoading) { + var result = JS('', '#.get(#)', deferredImports, libraryUri); + if (JS('', '# === void 0', result)) { + JS('', '#.set(#, # = new Set())', deferredImports, libraryUri, result); + } + JS('', '#.add(#)', result, importPrefix); + return Future.value(); + } else { + throw UnimplementedError('realDeferredLoading flag is not yet supported'); } - JS('', '#.add(#)', result, importPrefix); - return Future.value(); } void checkDeferredIsLoaded( - @notNull String enclosingLibrary, @notNull String importPrefix) { - var loaded = JS('', '#.get(#)', deferredImports, enclosingLibrary); - if (JS('', '# === void 0', loaded) || - JS('', '!#.has(#)', loaded, importPrefix)) { - throwDeferredIsLoadedError(enclosingLibrary, importPrefix); + @notNull String libraryUri, @notNull String importPrefix) { + if (!_realDeferredLoading) { + var loaded = JS('', '#.get(#)', deferredImports, libraryUri); + if (JS('', '# === void 0', loaded) || + JS('', '!#.has(#)', loaded, importPrefix)) { + throwDeferredIsLoadedError(libraryUri, importPrefix); + } + } else { + throw UnimplementedError('realDeferredLoading flag is not yet supported'); } }