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 | 8 |
9 import 'common/names.dart' show Uris; | 9 import 'common/names.dart' show Uris; |
10 import 'common/tasks.dart' show CompilerTask, Measurer; | 10 import 'common/tasks.dart' show CompilerTask, Measurer; |
11 import 'common.dart'; | 11 import 'common.dart'; |
12 import 'elements/elements.dart' | 12 import 'elements/elements.dart' |
13 show | 13 show |
14 CompilationUnitElement, | 14 CompilationUnitElement, |
15 Element, | 15 Element, |
16 ImportElement, | 16 ImportElement, |
17 ExportElement, | 17 ExportElement, |
18 LibraryElement; | 18 LibraryElement; |
19 import 'elements/entities.dart' show LibraryEntity; | |
20 import 'elements/modelx.dart' | 19 import 'elements/modelx.dart' |
21 show | 20 show |
22 CompilationUnitElementX, | 21 CompilationUnitElementX, |
23 DeferredLoaderGetterElementX, | 22 DeferredLoaderGetterElementX, |
24 ErroneousElementX, | 23 ErroneousElementX, |
25 ExportElementX, | 24 ExportElementX, |
26 ImportElementX, | 25 ImportElementX, |
27 LibraryElementX, | 26 LibraryElementX, |
28 LibraryDependencyElementX, | 27 LibraryDependencyElementX, |
29 PrefixElementX, | 28 PrefixElementX, |
30 SyntheticImportElement; | 29 SyntheticImportElement; |
31 import 'enqueue.dart' show DeferredAction; | 30 import 'enqueue.dart' show DeferredAction; |
32 import 'environment.dart'; | 31 import 'environment.dart'; |
33 import 'kernel/world_builder.dart' show KernelWorldBuilder; | |
34 import 'patch_parser.dart' show PatchParserTask; | 32 import 'patch_parser.dart' show PatchParserTask; |
35 import 'resolved_uri_translator.dart'; | 33 import 'resolved_uri_translator.dart'; |
36 import 'script.dart'; | 34 import 'script.dart'; |
37 import 'serialization/serialization.dart' show LibraryDeserializer; | 35 import 'serialization/serialization.dart' show LibraryDeserializer; |
38 import 'tree/tree.dart'; | 36 import 'tree/tree.dart'; |
39 import 'util/util.dart' show Link, LinkBuilder; | 37 import 'util/util.dart' show Link, LinkBuilder; |
40 | 38 |
41 import 'package:kernel/ast.dart' as ir; | |
42 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder; | |
43 | |
44 typedef Future<Iterable<LibraryElement>> ReuseLibrariesFunction( | 39 typedef Future<Iterable<LibraryElement>> ReuseLibrariesFunction( |
45 Iterable<LibraryElement> libraries); | 40 Iterable<LibraryElement> libraries); |
46 | 41 |
47 typedef Uri PatchResolverFunction(String dartLibraryPath); | 42 typedef Uri PatchResolverFunction(String dartLibraryPath); |
48 | 43 |
49 /** | 44 /** |
50 * [CompilerTask] for loading libraries and setting up the import/export scopes. | 45 * [CompilerTask] for loading libraries and setting up the import/export scopes. |
51 * | 46 * |
52 * The library loader uses four different kinds of URIs in different parts of | 47 * The library loader uses four different kinds of URIs in different parts of |
53 * the loading process. | 48 * the loading process. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 * | 130 * |
136 * import 'package:foo.dart' as a; | 131 * import 'package:foo.dart' as a; |
137 * import 'packages/foo.dart' as b; | 132 * import 'packages/foo.dart' as b; |
138 * | 133 * |
139 * do _not_ resolve to the same library when the package root URI happens to | 134 * do _not_ resolve to the same library when the package root URI happens to |
140 * point to the 'packages' folder. | 135 * point to the 'packages' folder. |
141 * | 136 * |
142 */ | 137 */ |
143 abstract class LibraryLoaderTask implements LibraryProvider, CompilerTask { | 138 abstract class LibraryLoaderTask implements LibraryProvider, CompilerTask { |
144 factory LibraryLoaderTask( | 139 factory LibraryLoaderTask( |
145 bool loadFromDillFile, | 140 ResolvedUriTranslator uriTranslator, |
146 ResolvedUriTranslator uriTranslator, | 141 ScriptLoader scriptLoader, |
147 ScriptLoader scriptLoader, | 142 ElementScanner scriptScanner, |
148 ElementScanner scriptScanner, | 143 LibraryDeserializer deserializer, |
149 LibraryDeserializer deserializer, | 144 PatchResolverFunction patchResolverFunc, |
150 PatchResolverFunction patchResolverFunc, | 145 PatchParserTask patchParser, |
151 PatchParserTask patchParser, | 146 Environment environment, |
152 Environment environment, | 147 DiagnosticReporter reporter, |
153 DiagnosticReporter reporter, | 148 Measurer measurer) = _LibraryLoaderTask; |
154 Measurer measurer) => | |
155 loadFromDillFile | |
156 ? new _DillLibraryLoaderTask( | |
157 uriTranslator, scriptLoader, reporter, measurer) | |
158 : new _LibraryLoaderTask( | |
159 uriTranslator, | |
160 scriptLoader, | |
161 scriptScanner, | |
162 deserializer, | |
163 patchResolverFunc, | |
164 patchParser, | |
165 environment, | |
166 reporter, | |
167 measurer); | |
168 | 149 |
169 /// Returns all libraries that have been loaded. | 150 /// Returns all libraries that have been loaded. |
170 Iterable<LibraryEntity> get libraries; | 151 Iterable<LibraryElement> get libraries; |
171 | 152 |
172 /// Loads the library specified by the [resolvedUri] and returns the | 153 /// Loads the library specified by the [resolvedUri] and returns the |
173 /// [LoadedLibraries] that were loaded to load the specified uri. The | 154 /// [LoadedLibraries] that were loaded to load the specified uri. The |
174 /// [LibraryElement] itself can be found by calling | 155 /// [LibraryElement] itself can be found by calling |
175 /// `loadedLibraries.rootLibrary`. | 156 /// `loadedLibraries.rootLibrary`. |
176 /// | 157 /// |
177 /// If the library is not already loaded, the method creates the | 158 /// If the library is not already loaded, the method creates the |
178 /// [LibraryElement] for the library and computes the import/export scope, | 159 /// [LibraryElement] for the library and computes the import/export scope, |
179 /// loading and computing the import/export scopes of all required libraries | 160 /// loading and computing the import/export scopes of all required libraries |
180 /// in the process. The method handles cyclic dependency between libraries. | 161 /// in the process. The method handles cyclic dependency between libraries. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 if (patchLocation == null) return null; | 211 if (patchLocation == null) return null; |
231 return platformConfigUri.resolve(patchLocation); | 212 return platformConfigUri.resolve(patchLocation); |
232 } | 213 } |
233 } | 214 } |
234 | 215 |
235 /// Interface for an entity that provide libraries. For instance from normal | 216 /// Interface for an entity that provide libraries. For instance from normal |
236 /// library loading or from deserialization. | 217 /// library loading or from deserialization. |
237 // TODO(johnniwinther): Use this to integrate deserialized libraries better. | 218 // TODO(johnniwinther): Use this to integrate deserialized libraries better. |
238 abstract class LibraryProvider { | 219 abstract class LibraryProvider { |
239 /// Looks up the library with the [canonicalUri]. | 220 /// Looks up the library with the [canonicalUri]. |
240 LibraryEntity lookupLibrary(Uri canonicalUri); | 221 LibraryElement lookupLibrary(Uri canonicalUri); |
241 } | 222 } |
242 | 223 |
243 /// Handle for creating synthesized/patch libraries during library loading. | 224 /// Handle for creating synthesized/patch libraries during library loading. |
244 abstract class LibraryLoader { | 225 abstract class LibraryLoader { |
245 /// This method must be called when a new synthesized/patch library has been | 226 /// This method must be called when a new synthesized/patch library has been |
246 /// created to ensure that [library] will part of library dependency graph | 227 /// created to ensure that [library] will part of library dependency graph |
247 /// used for computing import/export scopes. | 228 /// used for computing import/export scopes. |
248 void registerNewLibrary(LibraryElement library); | 229 void registerNewLibrary(LibraryElement library); |
249 | 230 |
250 /// This method must be called when a new synthesized/patch library has been | 231 /// This method must be called when a new synthesized/patch library has been |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 | 365 |
385 String get name => 'LibraryLoader'; | 366 String get name => 'LibraryLoader'; |
386 | 367 |
387 final Map<Uri, LibraryElement> libraryCanonicalUriMap = | 368 final Map<Uri, LibraryElement> libraryCanonicalUriMap = |
388 new Map<Uri, LibraryElement>(); | 369 new Map<Uri, LibraryElement>(); |
389 final Map<Uri, LibraryElement> libraryResourceUriMap = | 370 final Map<Uri, LibraryElement> libraryResourceUriMap = |
390 new Map<Uri, LibraryElement>(); | 371 new Map<Uri, LibraryElement>(); |
391 final Map<String, LibraryElement> libraryNames = | 372 final Map<String, LibraryElement> libraryNames = |
392 new Map<String, LibraryElement>(); | 373 new Map<String, LibraryElement>(); |
393 | 374 |
394 Iterable<LibraryEntity> get libraries => libraryCanonicalUriMap.values; | 375 Iterable<LibraryElement> get libraries => libraryCanonicalUriMap.values; |
395 | 376 |
396 LibraryEntity lookupLibrary(Uri canonicalUri) { | 377 LibraryElement lookupLibrary(Uri canonicalUri) { |
397 return libraryCanonicalUriMap[canonicalUri]; | 378 return libraryCanonicalUriMap[canonicalUri]; |
398 } | 379 } |
399 | 380 |
400 void reset({bool reuseLibrary(LibraryElement library)}) { | 381 void reset({bool reuseLibrary(LibraryElement library)}) { |
401 measure(() { | 382 measure(() { |
402 Iterable<LibraryElement> reusedLibraries = null; | 383 Iterable<LibraryElement> reusedLibraries = null; |
403 if (reuseLibrary != null) { | 384 if (reuseLibrary != null) { |
404 reusedLibraries = measureSubtask(_reuseLibrarySubtaskName, () { | 385 reusedLibraries = measureSubtask(_reuseLibrarySubtaskName, () { |
405 // Call [toList] to force eager calls to [reuseLibrary]. | 386 // Call [toList] to force eager calls to [reuseLibrary]. |
406 return libraryCanonicalUriMap.values.where(reuseLibrary).toList(); | 387 return libraryCanonicalUriMap.values.where(reuseLibrary).toList(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 {bool skipFileWithPartOfTag: false}) { | 465 {bool skipFileWithPartOfTag: false}) { |
485 return measure(() async { | 466 return measure(() async { |
486 LibraryDependencyHandler handler = new LibraryDependencyHandler(this); | 467 LibraryDependencyHandler handler = new LibraryDependencyHandler(this); |
487 LibraryElement library = await createLibrary( | 468 LibraryElement library = await createLibrary( |
488 handler, null, resolvedUri, NO_LOCATION_SPANNABLE, | 469 handler, null, resolvedUri, NO_LOCATION_SPANNABLE, |
489 skipFileWithPartOfTag: skipFileWithPartOfTag); | 470 skipFileWithPartOfTag: skipFileWithPartOfTag); |
490 if (library == null) return null; | 471 if (library == null) return null; |
491 return reporter.withCurrentElement(library, () { | 472 return reporter.withCurrentElement(library, () { |
492 return measure(() { | 473 return measure(() { |
493 handler.computeExports(); | 474 handler.computeExports(); |
494 return new _LoadedLibraries(library, handler.newLibraries); | 475 return new _LoadedLibraries(library, handler.newLibraries, this); |
495 }); | 476 }); |
496 }); | 477 }); |
497 }); | 478 }); |
498 } | 479 } |
499 | 480 |
500 /** | 481 /** |
501 * Processes the library tags in [library]. | 482 * Processes the library tags in [library]. |
502 * | 483 * |
503 * The imported/exported libraries are loaded and processed recursively but | 484 * The imported/exported libraries are loaded and processed recursively but |
504 * the import/export scopes are not set up. | 485 * the import/export scopes are not set up. |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 _deferredActions.add(action); | 804 _deferredActions.add(action); |
824 } | 805 } |
825 | 806 |
826 Iterable<DeferredAction> pullDeferredActions() { | 807 Iterable<DeferredAction> pullDeferredActions() { |
827 Iterable<DeferredAction> actions = _deferredActions.toList(); | 808 Iterable<DeferredAction> actions = _deferredActions.toList(); |
828 _deferredActions.clear(); | 809 _deferredActions.clear(); |
829 return actions; | 810 return actions; |
830 } | 811 } |
831 } | 812 } |
832 | 813 |
833 /// A task for loading a pre-processed .dill file into memory rather than | |
834 /// parsing Dart source. Use of this task only makes sense when used in | |
835 /// conjunction with --use-kernel. | |
836 class _DillLibraryLoaderTask extends CompilerTask implements LibraryLoaderTask { | |
837 final DiagnosticReporter reporter; | |
838 | |
839 final ResolvedUriTranslator uriTranslator; | |
840 | |
841 /// Loads the contents of a script file (a .dart file). Used when loading | |
842 /// libraries from source. | |
843 final ScriptLoader scriptLoader; | |
844 | |
845 /// Holds the mapping of Kernel IR to KElements that is constructed as a | |
846 /// result of loading a program. | |
847 KernelWorldBuilder _worldBuilder; | |
848 | |
849 List<LibraryEntity> _allLoadedLibraries; | |
850 | |
851 _DillLibraryLoaderTask( | |
852 this.uriTranslator, this.scriptLoader, this.reporter, Measurer measurer) | |
853 : _allLoadedLibraries = new List<LibraryEntity>(), | |
854 super(measurer); | |
855 | |
856 /// Loads an entire Kernel [Program] from a file on disk (note, not just a | |
857 /// library, so this name is actuall a bit of a misnomer). | |
858 // TODO(efortuna): Rename this once the Element library loader class goes | |
859 // away. | |
860 Future<LoadedLibraries> loadLibrary(Uri resolvedUri, | |
861 {bool skipFileWithPartOfTag: false}) { | |
862 assert(resolvedUri.pathSegments.last.endsWith('.dill')); | |
863 Uri readableUri = uriTranslator.translate(null, resolvedUri, null); | |
864 return measure(() async { | |
865 Script script = await scriptLoader.readScript(readableUri, null); | |
866 ir.Program program = new ir.Program(); | |
867 // Hack because the existing file has a terminating 0 and the | |
868 // BinaryBuilder doesn't expect that. | |
869 var bytes = new List<int>.from(script.file.slowUtf8ZeroTerminatedBytes()); | |
870 bytes.removeLast(); | |
871 new BinaryBuilder(bytes).readProgram(program); | |
872 return measure(() { | |
873 _worldBuilder = new KernelWorldBuilder(reporter, program); | |
874 program.libraries.forEach((ir.Library library) => _allLoadedLibraries | |
875 .add(_worldBuilder.lookupLibrary(library.importUri))); | |
876 // TODO(efortuna): Handle `prgram.mainMethod == null` gracefully. | |
877 return new _LoadedLibrariesAdapter( | |
878 _worldBuilder | |
879 .lookupLibrary(program.mainMethod.enclosingLibrary.importUri), | |
880 _allLoadedLibraries, | |
881 _worldBuilder); | |
882 }); | |
883 }); | |
884 } | |
885 | |
886 KernelWorldBuilder get worldBuilder => _worldBuilder; | |
887 | |
888 void reset({bool reuseLibrary(LibraryElement library)}) { | |
889 throw new UnimplementedError('_DillLibraryLoaderTask.reset'); | |
890 } | |
891 | |
892 Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) { | |
893 throw new UnimplementedError('_DillLibraryLoaderTask.resetAsync'); | |
894 } | |
895 | |
896 Iterable<LibraryEntity> get libraries => _allLoadedLibraries; | |
897 | |
898 LibraryEntity lookupLibrary(Uri canonicalUri) { | |
899 return _worldBuilder?.lookupLibrary(canonicalUri); | |
900 } | |
901 | |
902 Future<Null> resetLibraries(ReuseLibrariesFunction reuseLibraries) { | |
903 throw new UnimplementedError('_DillLibraryLoaderTask.reuseLibraries'); | |
904 } | |
905 | |
906 void registerDeferredAction(DeferredAction action) { | |
907 throw new UnimplementedError( | |
908 '_DillLibraryLoaderTask.registerDeferredAction'); | |
909 } | |
910 | |
911 Iterable<DeferredAction> pullDeferredActions() { | |
912 throw new UnimplementedError('_DillLibraryLoaderTask.pullDeferredActions'); | |
913 } | |
914 } | |
915 | |
916 /// A state machine for checking script tags come in the correct order. | 814 /// A state machine for checking script tags come in the correct order. |
917 class TagState { | 815 class TagState { |
918 /// Initial state. | 816 /// Initial state. |
919 static const int NO_TAG_SEEN = 0; | 817 static const int NO_TAG_SEEN = 0; |
920 | 818 |
921 /// Passed to [checkTag] when a library declaration (the syntax "library | 819 /// Passed to [checkTag] when a library declaration (the syntax "library |
922 /// name;") has been seen. Not an actual state. | 820 /// name;") has been seen. Not an actual state. |
923 static const int LIBRARY = 1; | 821 static const int LIBRARY = 1; |
924 | 822 |
925 /// The state after the first library declaration. | 823 /// The state after the first library declaration. |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1477 Future processLibraryTags(LibraryElement library) { | 1375 Future processLibraryTags(LibraryElement library) { |
1478 return task.processLibraryTags(this, library); | 1376 return task.processLibraryTags(this, library); |
1479 } | 1377 } |
1480 } | 1378 } |
1481 | 1379 |
1482 /// Information on the set libraries loaded as a result of a call to | 1380 /// Information on the set libraries loaded as a result of a call to |
1483 /// [LibraryLoader.loadLibrary]. | 1381 /// [LibraryLoader.loadLibrary]. |
1484 abstract class LoadedLibraries { | 1382 abstract class LoadedLibraries { |
1485 /// The accesss the library object created corresponding to the library | 1383 /// The accesss the library object created corresponding to the library |
1486 /// passed to [LibraryLoader.loadLibrary]. | 1384 /// passed to [LibraryLoader.loadLibrary]. |
1487 LibraryEntity get rootLibrary; | 1385 LibraryElement get rootLibrary; |
1488 | 1386 |
1489 /// Returns `true` if a library with canonical [uri] was loaded in this bulk. | 1387 /// Returns `true` if a library with canonical [uri] was loaded in this bulk. |
1490 bool containsLibrary(Uri uri); | 1388 bool containsLibrary(Uri uri); |
1491 | 1389 |
1492 /// Returns the library with canonical [uri] that was loaded in this bulk. | 1390 /// Returns the library with canonical [uri] that was loaded in this bulk. |
1493 LibraryEntity getLibrary(Uri uri); | 1391 LibraryElement getLibrary(Uri uri); |
1494 | 1392 |
1495 /// Applies all libraries in this bulk to [f]. | 1393 /// Applies all libraries in this bulk to [f]. |
1496 void forEachLibrary(f(LibraryEntity library)); | 1394 void forEachLibrary(f(LibraryElement library)); |
1497 | 1395 |
1498 /// Applies all imports chains of [uri] in this bulk to [callback]. | 1396 /// Applies all imports chains of [uri] in this bulk to [callback]. |
1499 /// | 1397 /// |
1500 /// The argument [importChainReversed] to [callback] contains the chain of | 1398 /// The argument [importChainReversed] to [callback] contains the chain of |
1501 /// imports uris that lead to importing [uri] starting in [uri] and ending in | 1399 /// imports uris that lead to importing [uri] starting in [uri] and ending in |
1502 /// the uri that was passed in with [loadLibrary]. | 1400 /// the uri that was passed in with [loadLibrary]. |
1503 /// | 1401 /// |
1504 /// [callback] is called once for each chain of imports leading to [uri] until | 1402 /// [callback] is called once for each chain of imports leading to [uri] until |
1505 /// [callback] returns `false`. | 1403 /// [callback] returns `false`. |
1506 void forEachImportChain(Uri uri, | 1404 void forEachImportChain(Uri uri, |
1507 {bool callback(Link<Uri> importChainReversed)}); | 1405 {bool callback(Link<Uri> importChainReversed)}); |
1508 } | 1406 } |
1509 | 1407 |
1510 class _LoadedLibraries implements LoadedLibraries { | 1408 class _LoadedLibraries implements LoadedLibraries { |
| 1409 final _LibraryLoaderTask task; |
1511 final LibraryElement rootLibrary; | 1410 final LibraryElement rootLibrary; |
1512 final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; | 1411 final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; |
1513 final List<LibraryElement> _newLibraries; | 1412 final List<LibraryElement> _newLibraries; |
1514 | 1413 |
1515 _LoadedLibraries(this.rootLibrary, this._newLibraries) { | 1414 _LoadedLibraries(this.rootLibrary, this._newLibraries, this.task) { |
1516 _newLibraries.forEach((LibraryElement loadedLibrary) { | 1415 _newLibraries.forEach((LibraryElement loadedLibrary) { |
1517 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; | 1416 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; |
1518 }); | 1417 }); |
1519 assert(rootLibrary != null); | 1418 assert(rootLibrary != null); |
1520 } | 1419 } |
1521 | 1420 |
1522 bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri); | 1421 bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri); |
1523 | 1422 |
1524 LibraryElement getLibrary(Uri uri) => loadedLibraries[uri]; | 1423 LibraryElement getLibrary(Uri uri) => loadedLibraries[uri]; |
1525 | 1424 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1598 suffixChainMap[library] = suffixes; | 1497 suffixChainMap[library] = suffixes; |
1599 return; | 1498 return; |
1600 } | 1499 } |
1601 | 1500 |
1602 computeSuffixes(rootLibrary, const Link<Uri>()); | 1501 computeSuffixes(rootLibrary, const Link<Uri>()); |
1603 } | 1502 } |
1604 | 1503 |
1605 String toString() => 'root=$rootLibrary,libraries=${_newLibraries}'; | 1504 String toString() => 'root=$rootLibrary,libraries=${_newLibraries}'; |
1606 } | 1505 } |
1607 | 1506 |
1608 /// Adapter class to mimic the behavior of LoadedLibraries for Kernel element | |
1609 /// behavior. Ultimately we'll just access worldBuilder instead. | |
1610 class _LoadedLibrariesAdapter implements LoadedLibraries { | |
1611 final LibraryEntity rootLibrary; | |
1612 final List<LibraryEntity> _newLibraries; | |
1613 final KernelWorldBuilder worldBuilder; | |
1614 | |
1615 _LoadedLibrariesAdapter( | |
1616 this.rootLibrary, this._newLibraries, this.worldBuilder) { | |
1617 assert(rootLibrary != null); | |
1618 } | |
1619 | |
1620 bool containsLibrary(Uri uri) => getLibrary(uri) != null; | |
1621 | |
1622 LibraryEntity getLibrary(Uri uri) => worldBuilder.lookupLibrary(uri); | |
1623 | |
1624 void forEachLibrary(f(LibraryEntity library)) => _newLibraries.forEach(f); | |
1625 | |
1626 void forEachImportChain(Uri uri, | |
1627 {bool callback(Link<Uri> importChainReversed)}) { | |
1628 // Currently a no-op. This seems wrong. | |
1629 } | |
1630 | |
1631 String toString() => 'root=$rootLibrary,libraries=${_newLibraries}'; | |
1632 } | |
1633 | |
1634 // TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems | 1507 // TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems |
1635 // rather low-level. It might be more practical to split the library-loading | 1508 // rather low-level. It might be more practical to split the library-loading |
1636 // task itself. The task would continue to do the work of recursively loading | 1509 // task itself. The task would continue to do the work of recursively loading |
1637 // dependencies, but it can delegate to a set of subloaders how to do the actual | 1510 // dependencies, but it can delegate to a set of subloaders how to do the actual |
1638 // loading. We would then have a list of subloaders that use different | 1511 // loading. We would then have a list of subloaders that use different |
1639 // implementations: in-memory cache, deserialization, scanning from files. | 1512 // implementations: in-memory cache, deserialization, scanning from files. |
1640 // | 1513 // |
1641 // For example, the API might look like this: | 1514 // For example, the API might look like this: |
1642 // | 1515 // |
1643 // /// APIs to create [LibraryElement] and [CompilationUnitElements] given it's | 1516 // /// APIs to create [LibraryElement] and [CompilationUnitElements] given it's |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1677 } | 1550 } |
1678 | 1551 |
1679 /// API used by the library loader to synchronously scan a library or | 1552 /// API used by the library loader to synchronously scan a library or |
1680 /// compilation unit and ensure that their library tags are computed. | 1553 /// compilation unit and ensure that their library tags are computed. |
1681 abstract class ElementScanner { | 1554 abstract class ElementScanner { |
1682 void scanLibrary(LibraryElement library); | 1555 void scanLibrary(LibraryElement library); |
1683 void scanUnit(CompilationUnitElement unit); | 1556 void scanUnit(CompilationUnitElement unit); |
1684 } | 1557 } |
1685 | 1558 |
1686 const _reuseLibrarySubtaskName = "Reuse library"; | 1559 const _reuseLibrarySubtaskName = "Reuse library"; |
OLD | NEW |