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>()); |
+ } |
+} |