Index: sdk/lib/_internal/compiler/implementation/library_loader.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/library_loader.dart b/sdk/lib/_internal/compiler/implementation/library_loader.dart |
index 55031d273303c63cc85b8de0be0705b43c44182e..3c515a18c270cb52ced6910fc845255eaac0e1f9 100644 |
--- a/sdk/lib/_internal/compiler/implementation/library_loader.dart |
+++ b/sdk/lib/_internal/compiler/implementation/library_loader.dart |
@@ -113,12 +113,13 @@ abstract class LibraryLoader extends CompilerTask { |
*/ |
// TODO(johnniwinther): Remove [canonicalUri] together with |
// [Compiler.scanBuiltinLibrary]. |
- LibraryElement loadLibrary(Uri resolvedUri, Node node, Uri canonicalUri); |
+ Future<LibraryElement> loadLibrary(Uri resolvedUri, Node node, |
+ Uri canonicalUri); |
// TODO(johnniwinther): Remove this when patches don't need special parsing. |
- void registerLibraryFromTag(LibraryDependencyHandler handler, |
- LibraryElement library, |
- LibraryDependency tag); |
+ Future registerLibraryFromTag(LibraryDependencyHandler handler, |
+ LibraryElement library, |
+ LibraryDependency tag); |
/** |
* Adds the elements in the export scope of [importedLibrary] to the import |
@@ -227,18 +228,25 @@ class LibraryLoaderTask extends LibraryLoader { |
LibraryDependencyHandler currentHandler; |
- LibraryElement loadLibrary(Uri resolvedUri, Node node, Uri canonicalUri) { |
+ Future<LibraryElement> loadLibrary(Uri resolvedUri, Node node, |
+ Uri canonicalUri) { |
return measure(() { |
assert(currentHandler == null); |
+ // TODO(johnniwinther): Ensure that currentHandler correctly encloses the |
+ // loading of a library cluster. |
currentHandler = new LibraryDependencyHandler(compiler); |
- LibraryElement library = |
- createLibrary(currentHandler, null, resolvedUri, node, canonicalUri); |
- currentHandler.computeExports(); |
- currentHandler = null; |
- var workList = onLibraryLoadedCallbacks; |
- onLibraryLoadedCallbacks = []; |
- workList.forEach((f) => f()); |
- return library; |
+ return createLibrary(currentHandler, null, resolvedUri, node, |
+ canonicalUri).then((LibraryElement library) { |
+ return compiler.withCurrentElement(library, () { |
+ return measure(() { |
+ currentHandler.computeExports(); |
+ currentHandler = null; |
+ var workList = onLibraryLoadedCallbacks; |
+ onLibraryLoadedCallbacks = []; |
+ return Future.forEach(workList, (f) => f()).then((_) => library); |
+ }); |
+ }); |
+ }); |
}); |
} |
@@ -248,8 +256,8 @@ class LibraryLoaderTask extends LibraryLoader { |
* The imported/exported libraries are loaded and processed recursively but |
* the import/export scopes are not set up. |
*/ |
- void processLibraryTags(LibraryDependencyHandler handler, |
- LibraryElement library) { |
+ Future processLibraryTags(LibraryDependencyHandler handler, |
+ LibraryElement library) { |
int tagState = TagState.NO_TAG_SEEN; |
/** |
@@ -270,49 +278,62 @@ class LibraryLoaderTask extends LibraryLoader { |
bool importsDartCore = false; |
var libraryDependencies = new LinkBuilder<LibraryDependency>(); |
Uri base = library.entryCompilationUnit.script.uri; |
- for (LibraryTag tag in library.tags.reverse()) { |
- if (tag.isImport) { |
- Import import = tag; |
- tagState = checkTag(TagState.IMPORT_OR_EXPORT, import); |
- if (import.uri.dartString.slowToString() == 'dart:core') { |
- importsDartCore = true; |
- } |
- libraryDependencies.addLast(import); |
- } else if (tag.isExport) { |
- tagState = checkTag(TagState.IMPORT_OR_EXPORT, tag); |
- libraryDependencies.addLast(tag); |
- } else if (tag.isLibraryName) { |
- tagState = checkTag(TagState.LIBRARY, tag); |
- if (library.libraryTag != null) { |
- compiler.cancel("duplicated library declaration", node: tag); |
+ |
+ // TODO(rnystrom): Remove .toList() here if #11523 is fixed. |
+ return Future.forEach(library.tags.reverse().toList(), (LibraryTag tag) { |
+ compiler.withCurrentElement(library, () { |
+ if (tag.isImport) { |
+ Import import = tag; |
+ tagState = checkTag(TagState.IMPORT_OR_EXPORT, import); |
+ if (import.uri.dartString.slowToString() == 'dart:core') { |
+ importsDartCore = true; |
+ } |
+ libraryDependencies.addLast(import); |
+ } else if (tag.isExport) { |
+ tagState = checkTag(TagState.IMPORT_OR_EXPORT, tag); |
+ libraryDependencies.addLast(tag); |
+ } else if (tag.isLibraryName) { |
+ tagState = checkTag(TagState.LIBRARY, tag); |
+ if (library.libraryTag != null) { |
+ compiler.cancel("duplicated library declaration", node: tag); |
+ } else { |
+ library.libraryTag = tag; |
+ } |
+ checkDuplicatedLibraryName(library); |
+ } else if (tag.isPart) { |
+ Part part = tag; |
+ StringNode uri = part.uri; |
+ Uri resolvedUri = base.resolve(uri.dartString.slowToString()); |
+ tagState = checkTag(TagState.SOURCE, part); |
+ return scanPart(part, resolvedUri, library); |
} else { |
- library.libraryTag = tag; |
+ compiler.internalError("Unhandled library tag.", node: tag); |
} |
- checkDuplicatedLibraryName(library); |
- } else if (tag.isPart) { |
- Part part = tag; |
- StringNode uri = part.uri; |
- Uri resolvedUri = base.resolve(uri.dartString.slowToString()); |
- tagState = checkTag(TagState.SOURCE, part); |
- scanPart(part, resolvedUri, library); |
- } else { |
- compiler.internalError("Unhandled library tag.", node: tag); |
- } |
- } |
- |
- // Apply patch, if any. |
- if (library.isPlatformLibrary) { |
- patchDartLibrary(handler, library, library.canonicalUri.path); |
- } |
- |
- // Import dart:core if not already imported. |
- if (!importsDartCore && !isDartCore(library.canonicalUri)) { |
- handler.registerDependency(library, null, loadCoreLibrary(handler)); |
- } |
- |
- for (LibraryDependency tag in libraryDependencies.toLink()) { |
- registerLibraryFromTag(handler, library, tag); |
- } |
+ }); |
+ }).then((_) { |
+ return compiler.withCurrentElement(library, () { |
+ // Apply patch, if any. |
+ if (library.isPlatformLibrary) { |
+ return patchDartLibrary(handler, library, library.canonicalUri.path); |
+ } |
+ }); |
+ }).then((_) { |
+ return compiler.withCurrentElement(library, () { |
+ // Import dart:core if not already imported. |
+ if (!importsDartCore && !isDartCore(library.canonicalUri)) { |
+ return loadCoreLibrary(handler).then((LibraryElement coreLibrary) { |
+ handler.registerDependency(library, null, coreLibrary); |
+ }); |
+ } |
+ }); |
+ }).then((_) { |
+ // TODO(rnystrom): Remove .toList() here if #11523 is fixed. |
+ return Future.forEach(libraryDependencies.toLink().toList(), (tag) { |
+ return compiler.withCurrentElement(library, () { |
+ return registerLibraryFromTag(handler, library, tag); |
+ }); |
+ }); |
+ }); |
} |
void checkDuplicatedLibraryName(LibraryElement library) { |
@@ -341,42 +362,48 @@ class LibraryLoaderTask extends LibraryLoader { |
/** |
* Lazily loads and returns the [LibraryElement] for the dart:core library. |
*/ |
- LibraryElement loadCoreLibrary(LibraryDependencyHandler handler) { |
- if (compiler.coreLibrary == null) { |
- Uri coreUri = new Uri(scheme: 'dart', path: 'core'); |
- compiler.coreLibrary |
- = createLibrary(handler, null, coreUri, null, coreUri); |
+ Future<LibraryElement> loadCoreLibrary(LibraryDependencyHandler handler) { |
+ if (compiler.coreLibrary != null) { |
+ return new Future.value(compiler.coreLibrary); |
} |
- return compiler.coreLibrary; |
+ |
+ Uri coreUri = new Uri(scheme: 'dart', path: 'core'); |
+ return createLibrary(handler, null, coreUri, null, coreUri) |
+ .then((LibraryElement library) { |
+ compiler.coreLibrary = library; |
+ return library; |
+ }); |
} |
- void patchDartLibrary(LibraryDependencyHandler handler, |
+ Future patchDartLibrary(LibraryDependencyHandler handler, |
LibraryElement library, String dartLibraryPath) { |
- if (library.isPatched) return; |
+ if (library.isPatched) return new Future.value(); |
Uri patchUri = compiler.resolvePatchUri(dartLibraryPath); |
- if (patchUri != null) { |
- compiler.patchParser.patchLibrary(handler, patchUri, library); |
- } |
+ if (patchUri == null) return new Future.value(); |
+ |
+ return compiler.patchParser.patchLibrary(handler, patchUri, library); |
} |
/** |
* Handle a part tag in the scope of [library]. The [resolvedUri] given is |
* used as is, any URI resolution should be done beforehand. |
*/ |
- void scanPart(Part part, Uri resolvedUri, LibraryElement library) { |
+ Future scanPart(Part part, Uri resolvedUri, LibraryElement library) { |
if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri); |
Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part); |
- if (readableUri == null) return; |
- Script sourceScript = compiler.readScript(readableUri, part); |
- if (sourceScript == null) return; |
- CompilationUnitElement unit = |
- new CompilationUnitElementX(sourceScript, library); |
- compiler.withCurrentElement(unit, () { |
- compiler.scanner.scan(unit); |
- if (unit.partTag == null) { |
- compiler.reportError(unit, MessageKind.MISSING_PART_OF_TAG); |
- } |
- }); |
+ if (readableUri == null) return new Future.value(); |
+ return compiler.readScript(readableUri, library, part). |
+ then((Script sourceScript) { |
+ if (sourceScript == null) return; |
+ CompilationUnitElement unit = |
+ new CompilationUnitElementX(sourceScript, library); |
+ compiler.withCurrentElement(unit, () { |
+ compiler.scanner.scan(unit); |
+ if (unit.partTag == null) { |
+ compiler.reportError(unit, MessageKind.MISSING_PART_OF_TAG); |
+ } |
+ }); |
+ }); |
} |
/** |
@@ -384,25 +411,27 @@ class LibraryLoaderTask extends LibraryLoader { |
* registering its dependency in [handler] for the computation of the import/ |
* export scope. |
*/ |
- void registerLibraryFromTag(LibraryDependencyHandler handler, |
- LibraryElement library, |
- LibraryDependency tag) { |
+ Future registerLibraryFromTag(LibraryDependencyHandler handler, |
+ LibraryElement library, |
+ LibraryDependency tag) { |
Uri base = library.entryCompilationUnit.script.uri; |
Uri resolvedUri = base.resolve(tag.uri.dartString.slowToString()); |
- LibraryElement loadedLibrary = |
- createLibrary(handler, library, resolvedUri, tag.uri, resolvedUri); |
- if (loadedLibrary == null) return; |
- handler.registerDependency(library, tag, loadedLibrary); |
- |
- if (!loadedLibrary.hasLibraryName()) { |
- compiler.withCurrentElement(library, () { |
- compiler.reportFatalError( |
- tag == null ? null : tag.uri, |
- MessageKind.GENERIC, |
- {'text': |
- 'Error: No library name found in ${loadedLibrary.canonicalUri}.'}); |
- }); |
- } |
+ return createLibrary(handler, library, resolvedUri, tag.uri, resolvedUri) |
+ .then((LibraryElement loadedLibrary) { |
+ if (loadedLibrary == null) return; |
+ compiler.withCurrentElement(library, () { |
+ handler.registerDependency(library, tag, loadedLibrary); |
+ |
+ if (!loadedLibrary.hasLibraryName()) { |
+ compiler.reportFatalError( |
+ tag == null ? null : tag.uri, |
+ MessageKind.GENERIC, |
+ {'text': |
+ 'Error: No library name found in ' |
+ '${loadedLibrary.canonicalUri}.'}); |
+ } |
+ }); |
+ }); |
} |
/** |
@@ -413,38 +442,42 @@ class LibraryLoaderTask extends LibraryLoader { |
*/ |
// TODO(johnniwinther): Remove [canonicalUri] and make [resolvedUri] the |
// canonical uri when [Compiler.scanBuiltinLibrary] is removed. |
- LibraryElement createLibrary(LibraryDependencyHandler handler, |
+ Future<LibraryElement> createLibrary(LibraryDependencyHandler handler, |
LibraryElement importingLibrary, |
Uri resolvedUri, Node node, Uri canonicalUri) { |
// TODO(johnniwinther): Create erroneous library elements for missing |
// libraries. |
Uri readableUri = |
compiler.translateResolvedUri(importingLibrary, resolvedUri, node); |
- if (readableUri == null) return null; |
+ if (readableUri == null) return new Future.value(); |
LibraryElement library; |
if (canonicalUri != null) { |
library = compiler.libraries[canonicalUri.toString()]; |
} |
- if (library == null) { |
- Script script = compiler.readScript(readableUri, node); |
- if (script == null) return null; |
- |
- library = new LibraryElementX(script, canonicalUri); |
- handler.registerNewLibrary(library); |
- native.maybeEnableNative(compiler, library); |
- if (canonicalUri != null) { |
- compiler.libraries[canonicalUri.toString()] = library; |
- } |
- |
- compiler.withCurrentElement(library, () { |
- compiler.scanner.scanLibrary(library); |
- processLibraryTags(handler, library); |
- handler.registerLibraryExports(library); |
- onLibraryLoadedCallbacks.add( |
- () => compiler.onLibraryLoaded(library, resolvedUri)); |
- }); |
+ if (library != null) { |
+ return new Future.value(library); |
} |
- return library; |
+ return compiler.readScript(readableUri, importingLibrary, node) |
+ .then((Script script) { |
+ if (script == null) return null; |
+ LibraryElement element = new LibraryElementX(script, canonicalUri); |
+ compiler.withCurrentElement(element, () { |
+ handler.registerNewLibrary(element); |
+ native.maybeEnableNative(compiler, element); |
+ if (canonicalUri != null) { |
+ compiler.libraries[canonicalUri.toString()] = element; |
+ } |
+ compiler.scanner.scanLibrary(element); |
+ }); |
+ return processLibraryTags(handler, element).then((_) { |
+ compiler.withCurrentElement(element, () { |
+ handler.registerLibraryExports(element); |
+ onLibraryLoadedCallbacks.add( |
+ () => compiler.onLibraryLoaded(element, resolvedUri)); |
+ }); |
+ return element; |
+ }); |
+ }); |
} |
// TODO(johnniwinther): Remove this method when 'js_helper' is handled by |