Chromium Code Reviews| 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 0bcd1a51ca3f377c5f4de13601372de47740c680..90ddaa58fbcdaf98f96992f3ea234ca355e18685 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 |
| @@ -226,15 +227,19 @@ 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); |
| currentHandler = new LibraryDependencyHandler(compiler); |
| - LibraryElement library = |
| - createLibrary(currentHandler, null, resolvedUri, node, canonicalUri); |
| - currentHandler.computeExports(); |
| - currentHandler = null; |
| - return library; |
| + return createLibrary(currentHandler, null, resolvedUri, node, |
| + canonicalUri).then((LibraryElement library) { |
| + return measure(() { |
|
ahe
2013/08/06 16:29:17
Record current element?
Johnni Winther
2013/08/27 11:05:00
Done.
|
| + currentHandler.computeExports(); |
| + currentHandler = null; |
| + return library; |
| + }); |
| + }); |
| }); |
| } |
| @@ -244,8 +249,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; |
| /** |
| @@ -266,49 +271,56 @@ 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); |
| + }); |
| + }).then((_) { |
|
ahe
2013/08/06 16:29:17
Seems like there is a lack of calls to withCurrent
Johnni Winther
2013/08/27 11:05:00
Don't think they are needed but better safe than s
|
| + // Apply patch, if any. |
| + if (library.isPlatformLibrary) { |
| + return patchDartLibrary(handler, library, library.canonicalUri.path); |
| } |
| - } |
| - |
| - // 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((_) { |
| + // 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 registerLibraryFromTag(handler, library, tag); |
| + }); |
| + }); |
| } |
| void checkDuplicatedLibraryName(LibraryElement library) { |
| @@ -337,50 +349,56 @@ 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); |
| - Script sourceScript = compiler.readScript(readableUri, part); |
| - CompilationUnitElement unit = |
| - new CompilationUnitElementX(sourceScript, library); |
| - compiler.withCurrentElement(unit, () { |
| - compiler.scanner.scan(unit); |
| - if (unit.partTag == null) { |
| - bool wasDiagnosticEmitted = false; |
| - compiler.withCurrentElement(library, () { |
| - wasDiagnosticEmitted = |
| - compiler.onDeprecatedFeature(part, 'missing part-of tag'); |
| + return compiler.readScript(readableUri, library, part). |
| + then((Script sourceScript) { |
| + CompilationUnitElement unit = |
| + new CompilationUnitElementX(sourceScript, library); |
| + compiler.withCurrentElement(unit, () { |
| + compiler.scanner.scan(unit); |
| + if (unit.partTag == null) { |
| + bool wasDiagnosticEmitted = false; |
| + compiler.withCurrentElement(library, () { |
| + wasDiagnosticEmitted = |
| + compiler.onDeprecatedFeature(part, 'missing part-of tag'); |
| + }); |
| + if (wasDiagnosticEmitted) { |
| + compiler.reportMessage( |
| + compiler.spanFromElement(unit), |
| + MessageKind.MISSING_PART_OF_TAG.error(), |
| + api.Diagnostic.INFO); |
| + } |
| + } |
| + }); |
| }); |
| - if (wasDiagnosticEmitted) { |
| - compiler.reportMessage( |
| - compiler.spanFromElement(unit), |
| - MessageKind.MISSING_PART_OF_TAG.error(), |
| - api.Diagnostic.INFO); |
| - } |
| - } |
| - }); |
| } |
| /** |
| @@ -388,24 +406,26 @@ 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); |
| - handler.registerDependency(library, tag, loadedLibrary); |
| + return createLibrary(handler, library, resolvedUri, tag.uri, resolvedUri) |
| + .then((LibraryElement loadedLibrary) { |
|
ahe
2013/08/06 16:29:17
withCurrentElement?
Johnni Winther
2013/08/27 11:05:00
Done.
|
| + 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}.'}); |
| - }); |
| - } |
| + if (!loadedLibrary.hasLibraryName()) { |
| + compiler.withCurrentElement(library, () { |
| + compiler.reportFatalError( |
| + tag == null ? null : tag.uri, |
| + MessageKind.GENERIC, |
| + {'text': |
| + 'Error: No library name found in ' |
| + '${loadedLibrary.canonicalUri}.'}); |
| + }); |
| + } |
| + }); |
| } |
| /** |
| @@ -416,37 +436,37 @@ 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) { |
| - bool newLibrary = false; |
| Uri readableUri = |
| compiler.translateResolvedUri(importingLibrary, resolvedUri, node); |
| if (readableUri == null) return null; |
| - LibraryElement createLibrary() { |
| - newLibrary = true; |
| - Script script = compiler.readScript(readableUri, node); |
| - LibraryElement element = new LibraryElementX(script, canonicalUri); |
| - handler.registerNewLibrary(element); |
| - native.maybeEnableNative(compiler, element); |
| - return element; |
| - } |
| - LibraryElement library; |
| - if (canonicalUri == null) { |
| - library = createLibrary(); |
| - } else { |
| - library = compiler.libraries.putIfAbsent(canonicalUri.toString(), |
| - createLibrary); |
| - } |
| - if (newLibrary) { |
| - compiler.withCurrentElement(library, () { |
| - compiler.scanner.scanLibrary(library); |
| - processLibraryTags(handler, library); |
| - handler.registerLibraryExports(library); |
| - compiler.onLibraryScanned(library, resolvedUri); |
| - }); |
| + |
| + if (canonicalUri != null) { |
| + LibraryElement library = compiler.libraries[canonicalUri.toString()]; |
| + if (library != null) { |
| + return new Future.value(library); |
| + } |
| } |
| - return library; |
| + |
| + return compiler.readScript(readableUri, importingLibrary, node). |
|
ahe
2013/08/06 16:29:17
Period goes on next line according to style guide
Johnni Winther
2013/08/27 11:05:00
Done.
|
| + then((Script script) { |
| + LibraryElement element = new LibraryElementX(script, canonicalUri); |
| + handler.registerNewLibrary(element); |
| + native.maybeEnableNative(compiler, element); |
| + compiler.libraries[canonicalUri.toString()] = element; |
| + compiler.withCurrentElement(element, () { |
|
ahe
2013/08/06 16:29:17
Would it make sense to move lines 456-458 into thi
Johnni Winther
2013/08/27 11:05:00
Done.
|
| + compiler.scanner.scanLibrary(element); |
| + }); |
| + return processLibraryTags(handler, element).then((_) { |
| + compiler.withCurrentElement(element, () { |
| + handler.registerLibraryExports(element); |
| + compiler.onLibraryScanned(element, resolvedUri); |
| + }); |
| + return element; |
| + }); |
| + }); |
| } |
| // TODO(johnniwinther): Remove this method when 'js_helper' is handled by |