OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.library_loader; | 5 library dart2js.library_loader; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart2jslib.dart' | 8 import 'dart2jslib.dart' |
9 show Compiler, | 9 show Compiler, |
10 CompilerTask, | 10 CompilerTask, |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 bool exclude(Element element) => excludedNames.contains(element.name); | 242 bool exclude(Element element) => excludedNames.contains(element.name); |
243 } | 243 } |
244 | 244 |
245 /** | 245 /** |
246 * Implementation class for [LibraryLoader]. The distinction between | 246 * Implementation class for [LibraryLoader]. The distinction between |
247 * [LibraryLoader] and [LibraryLoaderTask] is made to hide internal members from | 247 * [LibraryLoader] and [LibraryLoaderTask] is made to hide internal members from |
248 * the [LibraryLoader] interface. | 248 * the [LibraryLoader] interface. |
249 */ | 249 */ |
250 class _LibraryLoaderTask extends CompilerTask implements LibraryLoaderTask { | 250 class _LibraryLoaderTask extends CompilerTask implements LibraryLoaderTask { |
251 _LibraryLoaderTask(Compiler compiler) : super(compiler); | 251 _LibraryLoaderTask(Compiler compiler) : super(compiler); |
| 252 |
252 String get name => 'LibraryLoader'; | 253 String get name => 'LibraryLoader'; |
253 | 254 |
254 final Map<Uri, LibraryElement> libraryCanonicalUriMap = | 255 final Map<Uri, LibraryElement> libraryCanonicalUriMap = |
255 new Map<Uri, LibraryElement>(); | 256 new Map<Uri, LibraryElement>(); |
256 final Map<Uri, LibraryElement> libraryResourceUriMap = | 257 final Map<Uri, LibraryElement> libraryResourceUriMap = |
257 new Map<Uri, LibraryElement>(); | 258 new Map<Uri, LibraryElement>(); |
258 final Map<String, LibraryElement> libraryNames = | 259 final Map<String, LibraryElement> libraryNames = |
259 new Map<String, LibraryElement>(); | 260 new Map<String, LibraryElement>(); |
260 | 261 |
261 LibraryDependencyHandler currentHandler; | 262 LibraryDependencyHandler currentHandler; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 return measure(() { | 336 return measure(() { |
336 assert(currentHandler == null); | 337 assert(currentHandler == null); |
337 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the | 338 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the |
338 // loading of a library cluster. | 339 // loading of a library cluster. |
339 currentHandler = new LibraryDependencyHandler(this); | 340 currentHandler = new LibraryDependencyHandler(this); |
340 return createLibrary(currentHandler, null, resolvedUri) | 341 return createLibrary(currentHandler, null, resolvedUri) |
341 .then((LibraryElement library) { | 342 .then((LibraryElement library) { |
342 return compiler.withCurrentElement(library, () { | 343 return compiler.withCurrentElement(library, () { |
343 return measure(() { | 344 return measure(() { |
344 currentHandler.computeExports(); | 345 currentHandler.computeExports(); |
345 Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; | 346 LoadedLibraries loadedLibraries = |
346 currentHandler.loadedLibraries.forEach( | 347 new _LoadedLibraries(library, currentHandler.nodeMap, this); |
347 (LibraryElement loadedLibrary) { | |
348 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; | |
349 }); | |
350 currentHandler = null; | 348 currentHandler = null; |
351 return compiler.onLibrariesLoaded(loadedLibraries) | 349 return compiler.onLibrariesLoaded(loadedLibraries) |
352 .then((_) => library); | 350 .then((_) => library); |
353 }); | 351 }); |
354 }); | 352 }); |
355 }); | 353 }); |
356 }); | 354 }); |
357 } | 355 } |
358 | 356 |
359 /** | 357 /** |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 * fixed-point computation of the import/export scopes. | 1023 * fixed-point computation of the import/export scopes. |
1026 */ | 1024 */ |
1027 void registerLibraryExports(LibraryElement library) { | 1025 void registerLibraryExports(LibraryElement library) { |
1028 nodeMap[library].registerInitialExports(); | 1026 nodeMap[library].registerInitialExports(); |
1029 } | 1027 } |
1030 | 1028 |
1031 Future processLibraryTags(LibraryElement library) { | 1029 Future processLibraryTags(LibraryElement library) { |
1032 return task.processLibraryTags(this, library); | 1030 return task.processLibraryTags(this, library); |
1033 } | 1031 } |
1034 } | 1032 } |
| 1033 |
| 1034 /// Information on the bulk of newly loaded libraries through a call to |
| 1035 /// [LibraryLoader.loadLibrary]. |
| 1036 abstract class LoadedLibraries { |
| 1037 /// The uri passed to [LibraryLoader.loadLibrary]. |
| 1038 Uri get rootUri; |
| 1039 |
| 1040 /// Returns `true` if a library with canonical [uri] was loaded in this bulk. |
| 1041 bool containsLibrary(Uri uri); |
| 1042 |
| 1043 /// Returns the library with canonical [uri] that was loaded in this bulk. |
| 1044 LibraryElement getLibrary(Uri uri); |
| 1045 |
| 1046 /// Applies all libraries in this bulk to [f]. |
| 1047 void forEachLibrary(f(LibraryElement library)); |
| 1048 |
| 1049 /// Applies all imports chains of [uri] in this bulk to [callback]. |
| 1050 /// |
| 1051 /// The argument [importChainReversed] to [callback] contains the chain of |
| 1052 /// imports uris that lead to importing [uri] starting in [uri] and ending in |
| 1053 /// [rootUri]. |
| 1054 /// |
| 1055 /// [callback] is called once for each chain of imports leading to [uri] until |
| 1056 /// [callback] returns `false`. |
| 1057 void forEachImportChain(Uri uri, |
| 1058 {bool callback(Link<Uri> importChainReversed)}); |
| 1059 } |
| 1060 |
| 1061 class _LoadedLibraries implements LoadedLibraries { |
| 1062 final _LibraryLoaderTask task; |
| 1063 final LibraryElement rootLibrary; |
| 1064 final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; |
| 1065 final Map<LibraryElement, LibraryDependencyNode> nodeMap; |
| 1066 |
| 1067 _LoadedLibraries(this.rootLibrary, this.nodeMap, this.task) { |
| 1068 nodeMap.keys.forEach((LibraryElement loadedLibrary) { |
| 1069 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; |
| 1070 }); |
| 1071 } |
| 1072 |
| 1073 Uri get rootUri => rootLibrary.canonicalUri; |
| 1074 |
| 1075 bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri); |
| 1076 |
| 1077 LibraryElement getLibrary(Uri uri) => loadedLibraries[uri]; |
| 1078 |
| 1079 void forEachLibrary(f(LibraryElement library)) => nodeMap.keys.forEach(f); |
| 1080 |
| 1081 void forEachImportChain(Uri targetUri, |
| 1082 {bool callback(Link<Uri> importChainReversed)}) { |
| 1083 bool aborted = false; |
| 1084 |
| 1085 /// Map from libraries to the set of (unreversed) paths to [uri]. |
| 1086 Map<LibraryElement, Iterable<Link<Uri>>> suffixChainMap = |
| 1087 <LibraryElement, Iterable<Link<Uri>>>{}; |
| 1088 |
| 1089 /// Computes the set of (unreversed) paths to [targetUri]. |
| 1090 /// |
| 1091 /// Finds all paths (suffixes) from the current library to [uri] and stores |
| 1092 /// it in [suffixChainMap]. |
| 1093 /// |
| 1094 /// For every found suffix it prepends the given [prefix] and the canonical |
| 1095 /// uri of [library] and invokes the [callback] with the concatenated chain. |
| 1096 void computeSuffixes(LibraryElement library, |
| 1097 Link<Uri> prefix) { |
| 1098 if (aborted) return; |
| 1099 |
| 1100 Uri canonicalUri = library.canonicalUri; |
| 1101 prefix = prefix.prepend(canonicalUri); |
| 1102 if (suffixChainMap.containsKey(library)) return; |
| 1103 suffixChainMap[library] = const <Link<Uri>>[]; |
| 1104 List<Link<Uri>> suffixes = []; |
| 1105 if (targetUri != canonicalUri) { |
| 1106 LibraryDependencyNode node = nodeMap[library]; |
| 1107 for (ImportLink import in node.imports.reverse()) { |
| 1108 bool suffixesArePrecomputed = |
| 1109 suffixChainMap.containsKey(import.importedLibrary); |
| 1110 |
| 1111 if (!suffixesArePrecomputed) { |
| 1112 computeSuffixes(import.importedLibrary, prefix); |
| 1113 if (aborted) return; |
| 1114 } |
| 1115 |
| 1116 for (Link<Uri> suffix in suffixChainMap[import.importedLibrary]) { |
| 1117 suffixes.add(suffix.prepend(canonicalUri)); |
| 1118 |
| 1119 if (suffixesArePrecomputed) { |
| 1120 // Only report chains through [import] if the suffixes had already |
| 1121 // been computed, otherwise [computeSuffixes] have reported the |
| 1122 // paths through [prefix]. |
| 1123 Link<Uri> chain = prefix; |
| 1124 while (!suffix.isEmpty) { |
| 1125 chain = chain.prepend(suffix.head); |
| 1126 suffix = suffix.tail; |
| 1127 } |
| 1128 if (!callback(chain)) { |
| 1129 aborted = true; |
| 1130 return; |
| 1131 } |
| 1132 } |
| 1133 } |
| 1134 } |
| 1135 } else { // Here `targetUri == canonicalUri`. |
| 1136 if (!callback(prefix)) { |
| 1137 aborted = true; |
| 1138 return; |
| 1139 } |
| 1140 suffixes.add(const Link<Uri>().prepend(canonicalUri)); |
| 1141 } |
| 1142 suffixChainMap[library] = suffixes; |
| 1143 return; |
| 1144 } |
| 1145 |
| 1146 computeSuffixes(rootLibrary, const Link<Uri>()); |
| 1147 } |
| 1148 } |
OLD | NEW |