Chromium Code Reviews| Index: pkg/compiler/lib/src/library_loader.dart |
| diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart |
| index ff7d59ae25c578070bcbb5c6a2221b60b70e6c01..6338a1f03642f2030dc313adf343d016caa88a55 100644 |
| --- a/pkg/compiler/lib/src/library_loader.dart |
| +++ b/pkg/compiler/lib/src/library_loader.dart |
| @@ -249,6 +249,7 @@ class HideFilter extends CombinatorFilter { |
| */ |
| class _LibraryLoaderTask extends CompilerTask implements LibraryLoaderTask { |
| _LibraryLoaderTask(Compiler compiler) : super(compiler); |
| + |
| String get name => 'LibraryLoader'; |
| final Map<Uri, LibraryElement> libraryCanonicalUriMap = |
| @@ -342,11 +343,8 @@ class _LibraryLoaderTask extends CompilerTask implements LibraryLoaderTask { |
| return compiler.withCurrentElement(library, () { |
| return measure(() { |
| currentHandler.computeExports(); |
| - Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; |
| - currentHandler.loadedLibraries.forEach( |
| - (LibraryElement loadedLibrary) { |
| - loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; |
| - }); |
| + LoadedLibraries loadedLibraries = |
| + new _LoadedLibraries(library, currentHandler.nodeMap, this); |
| currentHandler = null; |
| return compiler.onLibrariesLoaded(loadedLibraries) |
| .then((_) => library); |
| @@ -1032,3 +1030,106 @@ class LibraryDependencyHandler implements LibraryLoader { |
| return task.processLibraryTags(this, library); |
| } |
| } |
| + |
| +/// Information on the bulk of newly loaded libraries through a call to |
| +/// [LibraryLoader.loadLibrary]. |
| +abstract class LoadedLibraries { |
| + /// The uri passed to [LibraryLoader.loadLibrary]. |
| + Uri get rootUri; |
| + |
| + /// Returns `true` if a library with canonical [uri] was loaded in this bulk. |
| + bool containsLibrary(Uri uri); |
| + |
| + /// Returns the library with canonical [uri] that was loaded in this bulk. |
| + LibraryElement getLibrary(Uri uri); |
| + |
| + /// Applies all libraries in this bulk to [f]. |
| + void forEachLibrary(f(LibraryElement library)); |
| + |
| + /// Applies all imports chains of [uri] in this bulk to [callback]. |
| + /// |
| + /// The argument [importChainReversed] to [callback] contains the chain of |
| + /// imports uris that lead to importing [uri] starting in [uri] and ending in |
| + /// [rootUri]. |
| + /// |
| + /// [callback] is called once for each chain of imports leading to [uri] until |
| + /// [callback] returns `false`. |
| + void forEachImportChain(Uri uri, |
| + {bool callback(Link<Uri> importChainReversed)}); |
| +} |
| + |
| +class _LoadedLibraries implements LoadedLibraries { |
| + final _LibraryLoaderTask task; |
| + final LibraryElement rootLibrary; |
| + final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; |
| + final Map<LibraryElement, LibraryDependencyNode> nodeMap; |
| + |
| + _LoadedLibraries(this.rootLibrary, this.nodeMap, this.task) { |
| + nodeMap.keys.forEach((LibraryElement loadedLibrary) { |
| + loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; |
| + }); |
| + } |
| + |
| + Uri get rootUri => rootLibrary.canonicalUri; |
| + |
| + bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri); |
| + |
| + LibraryElement getLibrary(Uri uri) => loadedLibraries[uri]; |
| + |
| + void forEachLibrary(f(LibraryElement library)) => nodeMap.keys.forEach(f); |
| + |
| + void forEachImportChain(Uri uri, |
|
floitsch
2014/11/18 15:50:01
uri -> targetUri ?
Johnni Winther
2014/11/19 08:52:19
Done.
|
| + {bool callback(Link<Uri> importChainReversed)}) { |
| + bool aborted = false; |
| + |
| + /// Map from libraries to the set of (unreversed) paths to [uri]. |
| + Map<LibraryElement, Iterable<Link<Uri>>> suffixChainMap = |
| + <LibraryElement, Iterable<Link<Uri>>>{}; |
| + |
| + /// Compute the set of (unreversed) paths to [uri]. |
|
floitsch
2014/11/18 15:50:01
Computes
Johnni Winther
2014/11/19 08:52:19
Done.
|
| + void computeSuffixes(LibraryElement library, |
|
floitsch
2014/11/18 15:50:01
More comments. Eg:
Finds all paths (suffixes) fro
Johnni Winther
2014/11/19 08:52:19
Done.
|
| + Link<Uri> prefix) { |
| + if (aborted) return; |
| + |
| + Uri canonicalUri = library.canonicalUri; |
| + prefix = prefix.prepend(canonicalUri); |
| + if (suffixChainMap.containsKey(library)) return; |
| + suffixChainMap[library] = const <Link<Uri>>[]; |
| + List<Link<Uri>> suffixes = []; |
| + if (uri == canonicalUri) { |
|
floitsch
2014/11/18 15:50:01
for some reason I prefer to put the "changing" thi
Johnni Winther
2014/11/19 08:52:19
Done.
|
| + if (!callback(prefix)) { |
| + aborted = true; |
| + return; |
| + } |
| + suffixes.add(const Link<Uri>().prepend(canonicalUri)); |
| + } else { |
| + LibraryDependencyNode node = nodeMap[library]; |
| + for (ImportLink import in node.imports.reverse()) { |
| + if (!suffixChainMap.containsKey(import.importedLibrary)) { |
|
floitsch
2014/11/18 15:50:01
The 'if' checks if 'import.importedLibrary' is alr
Johnni Winther
2014/11/19 08:52:19
[callback] should only have been call in this loop
|
| + computeSuffixes(import.importedLibrary, prefix); |
| + if (aborted) return; |
| + } |
| + computeSuffixes(import.importedLibrary, prefix); |
| + if (aborted) return; |
| + for (Link<Uri> suffix in suffixChainMap[import.importedLibrary]) { |
| + suffixes.add(suffix.prepend(canonicalUri)); |
| + |
| + Link<Uri> chain = prefix; |
| + while (!suffix.isEmpty) { |
| + chain = chain.prepend(suffix.head); |
| + suffix = suffix.tail; |
| + } |
| + if (!callback(chain)) { |
| + aborted = true; |
| + return; |
| + } |
| + } |
| + } |
| + } |
| + suffixChainMap[library] = suffixes; |
| + return; |
| + } |
| + |
| + computeSuffixes(rootLibrary, const Link<Uri>()); |
| + } |
| +} |