| 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; |
| 19 import 'elements/modelx.dart' | 20 import 'elements/modelx.dart' |
| 20 show | 21 show |
| 21 CompilationUnitElementX, | 22 CompilationUnitElementX, |
| 22 DeferredLoaderGetterElementX, | 23 DeferredLoaderGetterElementX, |
| 23 ErroneousElementX, | 24 ErroneousElementX, |
| 24 ExportElementX, | 25 ExportElementX, |
| 25 ImportElementX, | 26 ImportElementX, |
| 26 LibraryElementX, | 27 LibraryElementX, |
| 27 LibraryDependencyElementX, | 28 LibraryDependencyElementX, |
| 28 PrefixElementX, | 29 PrefixElementX, |
| 29 SyntheticImportElement; | 30 SyntheticImportElement; |
| 30 import 'enqueue.dart' show DeferredAction; | 31 import 'enqueue.dart' show DeferredAction; |
| 31 import 'environment.dart'; | 32 import 'environment.dart'; |
| 33 import 'kernel/world_builder.dart' show KernelWorldBuilder; |
| 32 import 'patch_parser.dart' show PatchParserTask; | 34 import 'patch_parser.dart' show PatchParserTask; |
| 33 import 'resolved_uri_translator.dart'; | 35 import 'resolved_uri_translator.dart'; |
| 34 import 'script.dart'; | 36 import 'script.dart'; |
| 35 import 'serialization/serialization.dart' show LibraryDeserializer; | 37 import 'serialization/serialization.dart' show LibraryDeserializer; |
| 36 import 'tree/tree.dart'; | 38 import 'tree/tree.dart'; |
| 37 import 'util/util.dart' show Link, LinkBuilder; | 39 import 'util/util.dart' show Link, LinkBuilder; |
| 38 | 40 |
| 41 import 'package:kernel/ast.dart' as ir; |
| 42 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder; |
| 43 |
| 39 typedef Future<Iterable<LibraryElement>> ReuseLibrariesFunction( | 44 typedef Future<Iterable<LibraryElement>> ReuseLibrariesFunction( |
| 40 Iterable<LibraryElement> libraries); | 45 Iterable<LibraryElement> libraries); |
| 41 | 46 |
| 42 typedef Uri PatchResolverFunction(String dartLibraryPath); | 47 typedef Uri PatchResolverFunction(String dartLibraryPath); |
| 43 | 48 |
| 44 /** | 49 /** |
| 45 * [CompilerTask] for loading libraries and setting up the import/export scopes. | 50 * [CompilerTask] for loading libraries and setting up the import/export scopes. |
| 46 * | 51 * |
| 47 * The library loader uses four different kinds of URIs in different parts of | 52 * The library loader uses four different kinds of URIs in different parts of |
| 48 * the loading process. | 53 * the loading process. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 * | 135 * |
| 131 * import 'package:foo.dart' as a; | 136 * import 'package:foo.dart' as a; |
| 132 * import 'packages/foo.dart' as b; | 137 * import 'packages/foo.dart' as b; |
| 133 * | 138 * |
| 134 * do _not_ resolve to the same library when the package root URI happens to | 139 * do _not_ resolve to the same library when the package root URI happens to |
| 135 * point to the 'packages' folder. | 140 * point to the 'packages' folder. |
| 136 * | 141 * |
| 137 */ | 142 */ |
| 138 abstract class LibraryLoaderTask implements LibraryProvider, CompilerTask { | 143 abstract class LibraryLoaderTask implements LibraryProvider, CompilerTask { |
| 139 factory LibraryLoaderTask( | 144 factory LibraryLoaderTask( |
| 140 ResolvedUriTranslator uriTranslator, | 145 bool loadFromDillFile, |
| 141 ScriptLoader scriptLoader, | 146 ResolvedUriTranslator uriTranslator, |
| 142 ElementScanner scriptScanner, | 147 ScriptLoader scriptLoader, |
| 143 LibraryDeserializer deserializer, | 148 ElementScanner scriptScanner, |
| 144 PatchResolverFunction patchResolverFunc, | 149 LibraryDeserializer deserializer, |
| 145 PatchParserTask patchParser, | 150 PatchResolverFunction patchResolverFunc, |
| 146 Environment environment, | 151 PatchParserTask patchParser, |
| 147 DiagnosticReporter reporter, | 152 Environment environment, |
| 148 Measurer measurer) = _LibraryLoaderTask; | 153 DiagnosticReporter reporter, |
| 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); |
| 149 | 168 |
| 150 /// Returns all libraries that have been loaded. | 169 /// Returns all libraries that have been loaded. |
| 151 Iterable<LibraryElement> get libraries; | 170 Iterable<LibraryEntity> get libraries; |
| 152 | 171 |
| 153 /// Loads the library specified by the [resolvedUri] and returns the | 172 /// Loads the library specified by the [resolvedUri] and returns the |
| 154 /// [LoadedLibraries] that were loaded to load the specified uri. The | 173 /// [LoadedLibraries] that were loaded to load the specified uri. The |
| 155 /// [LibraryElement] itself can be found by calling | 174 /// [LibraryElement] itself can be found by calling |
| 156 /// `loadedLibraries.rootLibrary`. | 175 /// `loadedLibraries.rootLibrary`. |
| 157 /// | 176 /// |
| 158 /// If the library is not already loaded, the method creates the | 177 /// If the library is not already loaded, the method creates the |
| 159 /// [LibraryElement] for the library and computes the import/export scope, | 178 /// [LibraryElement] for the library and computes the import/export scope, |
| 160 /// loading and computing the import/export scopes of all required libraries | 179 /// loading and computing the import/export scopes of all required libraries |
| 161 /// in the process. The method handles cyclic dependency between libraries. | 180 /// in the process. The method handles cyclic dependency between libraries. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 if (patchLocation == null) return null; | 230 if (patchLocation == null) return null; |
| 212 return platformConfigUri.resolve(patchLocation); | 231 return platformConfigUri.resolve(patchLocation); |
| 213 } | 232 } |
| 214 } | 233 } |
| 215 | 234 |
| 216 /// Interface for an entity that provide libraries. For instance from normal | 235 /// Interface for an entity that provide libraries. For instance from normal |
| 217 /// library loading or from deserialization. | 236 /// library loading or from deserialization. |
| 218 // TODO(johnniwinther): Use this to integrate deserialized libraries better. | 237 // TODO(johnniwinther): Use this to integrate deserialized libraries better. |
| 219 abstract class LibraryProvider { | 238 abstract class LibraryProvider { |
| 220 /// Looks up the library with the [canonicalUri]. | 239 /// Looks up the library with the [canonicalUri]. |
| 221 LibraryElement lookupLibrary(Uri canonicalUri); | 240 LibraryEntity lookupLibrary(Uri canonicalUri); |
| 222 } | 241 } |
| 223 | 242 |
| 224 /// Handle for creating synthesized/patch libraries during library loading. | 243 /// Handle for creating synthesized/patch libraries during library loading. |
| 225 abstract class LibraryLoader { | 244 abstract class LibraryLoader { |
| 226 /// This method must be called when a new synthesized/patch library has been | 245 /// This method must be called when a new synthesized/patch library has been |
| 227 /// created to ensure that [library] will part of library dependency graph | 246 /// created to ensure that [library] will part of library dependency graph |
| 228 /// used for computing import/export scopes. | 247 /// used for computing import/export scopes. |
| 229 void registerNewLibrary(LibraryElement library); | 248 void registerNewLibrary(LibraryElement library); |
| 230 | 249 |
| 231 /// This method must be called when a new synthesized/patch library has been | 250 /// 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... |
| 365 | 384 |
| 366 String get name => 'LibraryLoader'; | 385 String get name => 'LibraryLoader'; |
| 367 | 386 |
| 368 final Map<Uri, LibraryElement> libraryCanonicalUriMap = | 387 final Map<Uri, LibraryElement> libraryCanonicalUriMap = |
| 369 new Map<Uri, LibraryElement>(); | 388 new Map<Uri, LibraryElement>(); |
| 370 final Map<Uri, LibraryElement> libraryResourceUriMap = | 389 final Map<Uri, LibraryElement> libraryResourceUriMap = |
| 371 new Map<Uri, LibraryElement>(); | 390 new Map<Uri, LibraryElement>(); |
| 372 final Map<String, LibraryElement> libraryNames = | 391 final Map<String, LibraryElement> libraryNames = |
| 373 new Map<String, LibraryElement>(); | 392 new Map<String, LibraryElement>(); |
| 374 | 393 |
| 375 Iterable<LibraryElement> get libraries => libraryCanonicalUriMap.values; | 394 Iterable<LibraryEntity> get libraries => libraryCanonicalUriMap.values; |
| 376 | 395 |
| 377 LibraryElement lookupLibrary(Uri canonicalUri) { | 396 LibraryEntity lookupLibrary(Uri canonicalUri) { |
| 378 return libraryCanonicalUriMap[canonicalUri]; | 397 return libraryCanonicalUriMap[canonicalUri]; |
| 379 } | 398 } |
| 380 | 399 |
| 381 void reset({bool reuseLibrary(LibraryElement library)}) { | 400 void reset({bool reuseLibrary(LibraryElement library)}) { |
| 382 measure(() { | 401 measure(() { |
| 383 Iterable<LibraryElement> reusedLibraries = null; | 402 Iterable<LibraryElement> reusedLibraries = null; |
| 384 if (reuseLibrary != null) { | 403 if (reuseLibrary != null) { |
| 385 reusedLibraries = measureSubtask(_reuseLibrarySubtaskName, () { | 404 reusedLibraries = measureSubtask(_reuseLibrarySubtaskName, () { |
| 386 // Call [toList] to force eager calls to [reuseLibrary]. | 405 // Call [toList] to force eager calls to [reuseLibrary]. |
| 387 return libraryCanonicalUriMap.values.where(reuseLibrary).toList(); | 406 return libraryCanonicalUriMap.values.where(reuseLibrary).toList(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 {bool skipFileWithPartOfTag: false}) { | 484 {bool skipFileWithPartOfTag: false}) { |
| 466 return measure(() async { | 485 return measure(() async { |
| 467 LibraryDependencyHandler handler = new LibraryDependencyHandler(this); | 486 LibraryDependencyHandler handler = new LibraryDependencyHandler(this); |
| 468 LibraryElement library = await createLibrary( | 487 LibraryElement library = await createLibrary( |
| 469 handler, null, resolvedUri, NO_LOCATION_SPANNABLE, | 488 handler, null, resolvedUri, NO_LOCATION_SPANNABLE, |
| 470 skipFileWithPartOfTag: skipFileWithPartOfTag); | 489 skipFileWithPartOfTag: skipFileWithPartOfTag); |
| 471 if (library == null) return null; | 490 if (library == null) return null; |
| 472 return reporter.withCurrentElement(library, () { | 491 return reporter.withCurrentElement(library, () { |
| 473 return measure(() { | 492 return measure(() { |
| 474 handler.computeExports(); | 493 handler.computeExports(); |
| 475 return new _LoadedLibraries(library, handler.newLibraries, this); | 494 return new _LoadedLibraries(library, handler.newLibraries); |
| 476 }); | 495 }); |
| 477 }); | 496 }); |
| 478 }); | 497 }); |
| 479 } | 498 } |
| 480 | 499 |
| 481 /** | 500 /** |
| 482 * Processes the library tags in [library]. | 501 * Processes the library tags in [library]. |
| 483 * | 502 * |
| 484 * The imported/exported libraries are loaded and processed recursively but | 503 * The imported/exported libraries are loaded and processed recursively but |
| 485 * the import/export scopes are not set up. | 504 * the import/export scopes are not set up. |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 _deferredActions.add(action); | 823 _deferredActions.add(action); |
| 805 } | 824 } |
| 806 | 825 |
| 807 Iterable<DeferredAction> pullDeferredActions() { | 826 Iterable<DeferredAction> pullDeferredActions() { |
| 808 Iterable<DeferredAction> actions = _deferredActions.toList(); | 827 Iterable<DeferredAction> actions = _deferredActions.toList(); |
| 809 _deferredActions.clear(); | 828 _deferredActions.clear(); |
| 810 return actions; | 829 return actions; |
| 811 } | 830 } |
| 812 } | 831 } |
| 813 | 832 |
| 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 |
| 814 /// A state machine for checking script tags come in the correct order. | 916 /// A state machine for checking script tags come in the correct order. |
| 815 class TagState { | 917 class TagState { |
| 816 /// Initial state. | 918 /// Initial state. |
| 817 static const int NO_TAG_SEEN = 0; | 919 static const int NO_TAG_SEEN = 0; |
| 818 | 920 |
| 819 /// Passed to [checkTag] when a library declaration (the syntax "library | 921 /// Passed to [checkTag] when a library declaration (the syntax "library |
| 820 /// name;") has been seen. Not an actual state. | 922 /// name;") has been seen. Not an actual state. |
| 821 static const int LIBRARY = 1; | 923 static const int LIBRARY = 1; |
| 822 | 924 |
| 823 /// The state after the first library declaration. | 925 /// The state after the first library declaration. |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1375 Future processLibraryTags(LibraryElement library) { | 1477 Future processLibraryTags(LibraryElement library) { |
| 1376 return task.processLibraryTags(this, library); | 1478 return task.processLibraryTags(this, library); |
| 1377 } | 1479 } |
| 1378 } | 1480 } |
| 1379 | 1481 |
| 1380 /// Information on the set libraries loaded as a result of a call to | 1482 /// Information on the set libraries loaded as a result of a call to |
| 1381 /// [LibraryLoader.loadLibrary]. | 1483 /// [LibraryLoader.loadLibrary]. |
| 1382 abstract class LoadedLibraries { | 1484 abstract class LoadedLibraries { |
| 1383 /// The accesss the library object created corresponding to the library | 1485 /// The accesss the library object created corresponding to the library |
| 1384 /// passed to [LibraryLoader.loadLibrary]. | 1486 /// passed to [LibraryLoader.loadLibrary]. |
| 1385 LibraryElement get rootLibrary; | 1487 LibraryEntity get rootLibrary; |
| 1386 | 1488 |
| 1387 /// Returns `true` if a library with canonical [uri] was loaded in this bulk. | 1489 /// Returns `true` if a library with canonical [uri] was loaded in this bulk. |
| 1388 bool containsLibrary(Uri uri); | 1490 bool containsLibrary(Uri uri); |
| 1389 | 1491 |
| 1390 /// Returns the library with canonical [uri] that was loaded in this bulk. | 1492 /// Returns the library with canonical [uri] that was loaded in this bulk. |
| 1391 LibraryElement getLibrary(Uri uri); | 1493 LibraryEntity getLibrary(Uri uri); |
| 1392 | 1494 |
| 1393 /// Applies all libraries in this bulk to [f]. | 1495 /// Applies all libraries in this bulk to [f]. |
| 1394 void forEachLibrary(f(LibraryElement library)); | 1496 void forEachLibrary(f(LibraryEntity library)); |
| 1395 | 1497 |
| 1396 /// Applies all imports chains of [uri] in this bulk to [callback]. | 1498 /// Applies all imports chains of [uri] in this bulk to [callback]. |
| 1397 /// | 1499 /// |
| 1398 /// The argument [importChainReversed] to [callback] contains the chain of | 1500 /// The argument [importChainReversed] to [callback] contains the chain of |
| 1399 /// imports uris that lead to importing [uri] starting in [uri] and ending in | 1501 /// imports uris that lead to importing [uri] starting in [uri] and ending in |
| 1400 /// the uri that was passed in with [loadLibrary]. | 1502 /// the uri that was passed in with [loadLibrary]. |
| 1401 /// | 1503 /// |
| 1402 /// [callback] is called once for each chain of imports leading to [uri] until | 1504 /// [callback] is called once for each chain of imports leading to [uri] until |
| 1403 /// [callback] returns `false`. | 1505 /// [callback] returns `false`. |
| 1404 void forEachImportChain(Uri uri, | 1506 void forEachImportChain(Uri uri, |
| 1405 {bool callback(Link<Uri> importChainReversed)}); | 1507 {bool callback(Link<Uri> importChainReversed)}); |
| 1406 } | 1508 } |
| 1407 | 1509 |
| 1408 class _LoadedLibraries implements LoadedLibraries { | 1510 class _LoadedLibraries implements LoadedLibraries { |
| 1409 final _LibraryLoaderTask task; | |
| 1410 final LibraryElement rootLibrary; | 1511 final LibraryElement rootLibrary; |
| 1411 final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; | 1512 final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; |
| 1412 final List<LibraryElement> _newLibraries; | 1513 final List<LibraryElement> _newLibraries; |
| 1413 | 1514 |
| 1414 _LoadedLibraries(this.rootLibrary, this._newLibraries, this.task) { | 1515 _LoadedLibraries(this.rootLibrary, this._newLibraries) { |
| 1415 _newLibraries.forEach((LibraryElement loadedLibrary) { | 1516 _newLibraries.forEach((LibraryElement loadedLibrary) { |
| 1416 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; | 1517 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; |
| 1417 }); | 1518 }); |
| 1418 assert(rootLibrary != null); | 1519 assert(rootLibrary != null); |
| 1419 } | 1520 } |
| 1420 | 1521 |
| 1421 bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri); | 1522 bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri); |
| 1422 | 1523 |
| 1423 LibraryElement getLibrary(Uri uri) => loadedLibraries[uri]; | 1524 LibraryElement getLibrary(Uri uri) => loadedLibraries[uri]; |
| 1424 | 1525 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1497 suffixChainMap[library] = suffixes; | 1598 suffixChainMap[library] = suffixes; |
| 1498 return; | 1599 return; |
| 1499 } | 1600 } |
| 1500 | 1601 |
| 1501 computeSuffixes(rootLibrary, const Link<Uri>()); | 1602 computeSuffixes(rootLibrary, const Link<Uri>()); |
| 1502 } | 1603 } |
| 1503 | 1604 |
| 1504 String toString() => 'root=$rootLibrary,libraries=${_newLibraries}'; | 1605 String toString() => 'root=$rootLibrary,libraries=${_newLibraries}'; |
| 1505 } | 1606 } |
| 1506 | 1607 |
| 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 |
| 1507 // TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems | 1634 // TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems |
| 1508 // rather low-level. It might be more practical to split the library-loading | 1635 // rather low-level. It might be more practical to split the library-loading |
| 1509 // task itself. The task would continue to do the work of recursively loading | 1636 // task itself. The task would continue to do the work of recursively loading |
| 1510 // dependencies, but it can delegate to a set of subloaders how to do the actual | 1637 // dependencies, but it can delegate to a set of subloaders how to do the actual |
| 1511 // loading. We would then have a list of subloaders that use different | 1638 // loading. We would then have a list of subloaders that use different |
| 1512 // implementations: in-memory cache, deserialization, scanning from files. | 1639 // implementations: in-memory cache, deserialization, scanning from files. |
| 1513 // | 1640 // |
| 1514 // For example, the API might look like this: | 1641 // For example, the API might look like this: |
| 1515 // | 1642 // |
| 1516 // /// APIs to create [LibraryElement] and [CompilationUnitElements] given it's | 1643 // /// APIs to create [LibraryElement] and [CompilationUnitElements] given it's |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1550 } | 1677 } |
| 1551 | 1678 |
| 1552 /// API used by the library loader to synchronously scan a library or | 1679 /// API used by the library loader to synchronously scan a library or |
| 1553 /// compilation unit and ensure that their library tags are computed. | 1680 /// compilation unit and ensure that their library tags are computed. |
| 1554 abstract class ElementScanner { | 1681 abstract class ElementScanner { |
| 1555 void scanLibrary(LibraryElement library); | 1682 void scanLibrary(LibraryElement library); |
| 1556 void scanUnit(CompilationUnitElement unit); | 1683 void scanUnit(CompilationUnitElement unit); |
| 1557 } | 1684 } |
| 1558 | 1685 |
| 1559 const _reuseLibrarySubtaskName = "Reuse library"; | 1686 const _reuseLibrarySubtaskName = "Reuse library"; |
| OLD | NEW |