Chromium Code Reviews| 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; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 DeferredLoaderGetterElementX, | 22 DeferredLoaderGetterElementX, |
| 23 ErroneousElementX, | 23 ErroneousElementX, |
| 24 ExportElementX, | 24 ExportElementX, |
| 25 ImportElementX, | 25 ImportElementX, |
| 26 LibraryElementX, | 26 LibraryElementX, |
| 27 LibraryDependencyElementX, | 27 LibraryDependencyElementX, |
| 28 PrefixElementX, | 28 PrefixElementX, |
| 29 SyntheticImportElement; | 29 SyntheticImportElement; |
| 30 import 'enqueue.dart' show DeferredAction; | 30 import 'enqueue.dart' show DeferredAction; |
| 31 import 'environment.dart'; | 31 import 'environment.dart'; |
| 32 import 'io/source_file.dart' show SourceFile; | |
| 33 import 'patch_parser.dart' show PatchParserTask; | |
| 32 import 'resolved_uri_translator.dart'; | 34 import 'resolved_uri_translator.dart'; |
| 33 import 'script.dart'; | 35 import 'script.dart'; |
| 34 import 'serialization/serialization.dart' show LibraryDeserializer; | 36 import 'serialization/serialization.dart' show LibraryDeserializer; |
| 35 import 'tree/tree.dart'; | 37 import 'tree/tree.dart'; |
| 36 import 'util/util.dart' show Link, LinkBuilder; | 38 import 'util/util.dart' show Link, LinkBuilder; |
| 37 | 39 |
| 40 import 'package:front_end/src/fasta/scanner.dart' show Token; | |
| 41 | |
| 38 typedef Future<Iterable<LibraryElement>> ReuseLibrariesFunction( | 42 typedef Future<Iterable<LibraryElement>> ReuseLibrariesFunction( |
| 39 Iterable<LibraryElement> libraries); | 43 Iterable<LibraryElement> libraries); |
| 40 | 44 |
| 45 typedef Uri PatchResolverFunction(String dartLibraryPath); | |
| 46 | |
| 41 /** | 47 /** |
| 42 * [CompilerTask] for loading libraries and setting up the import/export scopes. | 48 * [CompilerTask] for loading libraries and setting up the import/export scopes. |
| 43 * | 49 * |
| 44 * The library loader uses four different kinds of URIs in different parts of | 50 * The library loader uses four different kinds of URIs in different parts of |
| 45 * the loading process. | 51 * the loading process. |
| 46 * | 52 * |
| 47 * ## User URI ## | 53 * ## User URI ## |
| 48 * | 54 * |
| 49 * A 'user URI' is a URI provided by the user in code and as the main entry URI | 55 * A 'user URI' is a URI provided by the user in code and as the main entry URI |
| 50 * at the command line. These generally come in 3 versions: | 56 * at the command line. These generally come in 3 versions: |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 * do _not_ resolve to the same library when the package root URI happens to | 137 * do _not_ resolve to the same library when the package root URI happens to |
| 132 * point to the 'packages' folder. | 138 * point to the 'packages' folder. |
| 133 * | 139 * |
| 134 */ | 140 */ |
| 135 abstract class LibraryLoaderTask implements LibraryProvider, CompilerTask { | 141 abstract class LibraryLoaderTask implements LibraryProvider, CompilerTask { |
| 136 factory LibraryLoaderTask( | 142 factory LibraryLoaderTask( |
| 137 ResolvedUriTranslator uriTranslator, | 143 ResolvedUriTranslator uriTranslator, |
| 138 ScriptLoader scriptLoader, | 144 ScriptLoader scriptLoader, |
| 139 ElementScanner scriptScanner, | 145 ElementScanner scriptScanner, |
| 140 LibraryDeserializer deserializer, | 146 LibraryDeserializer deserializer, |
| 141 LibraryLoaderListener listener, | 147 PatchResolverFunction patchResolverFunc, |
| 148 PatchParserTask patchParser, | |
| 142 Environment environment, | 149 Environment environment, |
| 143 DiagnosticReporter reporter, | 150 DiagnosticReporter reporter, |
| 144 Measurer measurer) = _LibraryLoaderTask; | 151 Measurer measurer) = _LibraryLoaderTask; |
| 145 | 152 |
| 146 /// Returns all libraries that have been loaded. | 153 /// Returns all libraries that have been loaded. |
| 147 Iterable<LibraryElement> get libraries; | 154 Iterable<LibraryElement> get libraries; |
| 148 | 155 |
| 149 /// Loads the library specified by the [resolvedUri] and returns its | 156 /// Loads the library specified by the [resolvedUri] and returns the |
| 150 /// [LibraryElement]. | 157 /// [LoadedLibraries] that were loaded to load the specified uri. The |
| 158 /// [LibraryElement] itself can be found by calling | |
| 159 /// `loadedLibraries.rootLibrary` | |
|
Siggi Cherem (dart-lang)
2017/03/24 17:40:28
nit: add a `.` at the end.
Emily Fortuna
2017/03/24 18:30:19
Done.
| |
| 151 /// | 160 /// |
| 152 /// If the library is not already loaded, the method creates the | 161 /// If the library is not already loaded, the method creates the |
| 153 /// [LibraryElement] for the library and computes the import/export scope, | 162 /// [LibraryElement] for the library and computes the import/export scope, |
| 154 /// loading and computing the import/export scopes of all required libraries | 163 /// loading and computing the import/export scopes of all required libraries |
| 155 /// in the process. The method handles cyclic dependency between libraries. | 164 /// in the process. The method handles cyclic dependency between libraries. |
| 156 /// | 165 /// |
| 157 /// If [skipFileWithPartOfTag] is `true`, `null` is returned if the | 166 /// If [skipFileWithPartOfTag] is `true`, `null` is returned if the |
| 158 /// compilation unit for [resolvedUri] contains a `part of` tag. This is only | 167 /// compilation unit for [resolvedUri] contains a `part of` tag. This is only |
| 159 /// used for analysis through [Compiler.analyzeUri]. | 168 /// used for analysis through [Compiler.analyzeUri]. |
| 160 Future<LibraryElement> loadLibrary(Uri resolvedUri, | 169 Future<LoadedLibraries> loadLibrary(Uri resolvedUri, |
| 161 {bool skipFileWithPartOfTag: false}); | 170 {bool skipFileWithPartOfTag: false}); |
| 162 | 171 |
| 163 /// Reset the library loader task to prepare for compilation. If provided, | 172 /// Reset the library loader task to prepare for compilation. If provided, |
| 164 /// libraries matching [reuseLibrary] are reused. | 173 /// libraries matching [reuseLibrary] are reused. |
| 165 /// | 174 /// |
| 166 /// This method is used for incremental compilation. | 175 /// This method is used for incremental compilation. |
| 167 void reset({bool reuseLibrary(LibraryElement library)}); | 176 void reset({bool reuseLibrary(LibraryElement library)}); |
| 168 | 177 |
| 169 /// Asynchronous version of [reset]. | 178 /// Asynchronous version of [reset]. |
| 170 Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)); | 179 Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)); |
| 171 | 180 |
| 172 /// Similar to [resetAsync] but [reuseLibrary] maps all libraries to a list | 181 /// Similar to [resetAsync] but [reuseLibrary] maps all libraries to a list |
| 173 /// of libraries that can be reused. | 182 /// of libraries that can be reused. |
| 174 Future<Null> resetLibraries(ReuseLibrariesFunction reuseLibraries); | 183 Future<Null> resetLibraries(ReuseLibrariesFunction reuseLibraries); |
| 175 | 184 |
| 176 // TODO(johnniwinther): Move these to a separate interface. | 185 // TODO(johnniwinther): Move these to a separate interface. |
| 177 /// Register a deferred action to be performed during resolution. | 186 /// Register a deferred action to be performed during resolution. |
| 178 void registerDeferredAction(DeferredAction action); | 187 void registerDeferredAction(DeferredAction action); |
| 179 | 188 |
| 180 /// Returns the deferred actions registered since the last call to | 189 /// Returns the deferred actions registered since the last call to |
| 181 /// [pullDeferredActions]. | 190 /// [pullDeferredActions]. |
| 182 Iterable<DeferredAction> pullDeferredActions(); | 191 Iterable<DeferredAction> pullDeferredActions(); |
| 192 | |
| 193 /// The locations of js patch-files relative to the sdk-descriptors. | |
| 194 static const _patchLocations = const <String, String>{ | |
| 195 "async": "_internal/js_runtime/lib/async_patch.dart", | |
| 196 "collection": "_internal/js_runtime/lib/collection_patch.dart", | |
| 197 "convert": "_internal/js_runtime/lib/convert_patch.dart", | |
| 198 "core": "_internal/js_runtime/lib/core_patch.dart", | |
| 199 "developer": "_internal/js_runtime/lib/developer_patch.dart", | |
| 200 "io": "_internal/js_runtime/lib/io_patch.dart", | |
| 201 "isolate": "_internal/js_runtime/lib/isolate_patch.dart", | |
| 202 "math": "_internal/js_runtime/lib/math_patch.dart", | |
| 203 "mirrors": "_internal/js_runtime/lib/mirrors_patch.dart", | |
| 204 "typed_data": "_internal/js_runtime/lib/typed_data_patch.dart", | |
| 205 "_internal": "_internal/js_runtime/lib/internal_patch.dart" | |
| 206 }; | |
| 207 | |
| 208 /// Returns the location of the patch-file associated with [libraryName] | |
| 209 /// resolved from [plaformConfigUri]. | |
| 210 /// | |
| 211 /// Returns null if there is none. | |
| 212 static Uri resolvePatchUri(String libraryName, Uri platformConfigUri) { | |
| 213 String patchLocation = _patchLocations[libraryName]; | |
| 214 if (patchLocation == null) return null; | |
| 215 return platformConfigUri.resolve(patchLocation); | |
| 216 } | |
| 183 } | 217 } |
| 184 | 218 |
| 185 /// Interface for an entity that provide libraries. For instance from normal | 219 /// Interface for an entity that provide libraries. For instance from normal |
| 186 /// library loading or from deserialization. | 220 /// library loading or from deserialization. |
| 187 // TODO(johnniwinther): Use this to integrate deserialized libraries better. | 221 // TODO(johnniwinther): Use this to integrate deserialized libraries better. |
| 188 abstract class LibraryProvider { | 222 abstract class LibraryProvider { |
| 189 /// Looks up the library with the [canonicalUri]. | 223 /// Looks up the library with the [canonicalUri]. |
| 190 LibraryElement lookupLibrary(Uri canonicalUri); | 224 LibraryElement lookupLibrary(Uri canonicalUri); |
| 191 } | 225 } |
| 192 | 226 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 296 final ScriptLoader scriptLoader; | 330 final ScriptLoader scriptLoader; |
| 297 | 331 |
| 298 /// Provides a diet element model from a script file containing information | 332 /// Provides a diet element model from a script file containing information |
| 299 /// about imports and exports. Used when loading libraries from source. | 333 /// about imports and exports. Used when loading libraries from source. |
| 300 final ElementScanner scanner; | 334 final ElementScanner scanner; |
| 301 | 335 |
| 302 /// Provides a diet element model for a library. Used when loading libraries | 336 /// Provides a diet element model for a library. Used when loading libraries |
| 303 /// from a serialized form. | 337 /// from a serialized form. |
| 304 final LibraryDeserializer deserializer; | 338 final LibraryDeserializer deserializer; |
| 305 | 339 |
| 306 /// Hooks to inform others about progress done by this loader. | |
| 307 // TODO(sigmund): move away from this. | |
| 308 final LibraryLoaderListener listener; | |
| 309 | |
| 310 /// Definitions provided via the `-D` command line flags. Used to resolve | 340 /// Definitions provided via the `-D` command line flags. Used to resolve |
| 311 /// conditional imports. | 341 /// conditional imports. |
| 312 final Environment environment; | 342 final Environment environment; |
| 313 | 343 |
| 344 // TODO(efortuna): Don't pass PatchParserTask here. | |
| 345 final PatchParserTask _patchParserTask; | |
| 346 | |
| 347 /// Function that accepts the string name of a library and returns the | |
| 348 /// path to the corresponding patch file. This is a function that is passed in | |
| 349 /// because our test mock_compiler subclasses compiler. | |
| 350 // TODO(efortuna): Refactor mock_compiler to not do this. | |
|
Siggi Cherem (dart-lang)
2017/03/24 17:40:27
thanks for documenting so nicely the issue :)
I h
Emily Fortuna
2017/03/24 18:30:19
makes sense. upcoming CL!
| |
| 351 final PatchResolverFunction _patchResolverFunc; | |
| 352 | |
| 314 List<DeferredAction> _deferredActions = <DeferredAction>[]; | 353 List<DeferredAction> _deferredActions = <DeferredAction>[]; |
| 315 | 354 |
| 316 final DiagnosticReporter reporter; | 355 final DiagnosticReporter reporter; |
| 317 | 356 |
| 318 _LibraryLoaderTask( | 357 _LibraryLoaderTask( |
| 319 this.uriTranslator, | 358 this.uriTranslator, |
| 320 this.scriptLoader, | 359 this.scriptLoader, |
| 321 this.scanner, | 360 this.scanner, |
| 322 this.deserializer, | 361 this.deserializer, |
| 323 this.listener, | 362 this._patchResolverFunc, |
| 363 this._patchParserTask, | |
| 324 this.environment, | 364 this.environment, |
| 325 this.reporter, | 365 this.reporter, |
| 326 Measurer measurer) | 366 Measurer measurer) |
| 327 : super(measurer); | 367 : super(measurer); |
| 328 | 368 |
| 329 String get name => 'LibraryLoader'; | 369 String get name => 'LibraryLoader'; |
| 330 | 370 |
| 331 final Map<Uri, LibraryElement> libraryCanonicalUriMap = | 371 final Map<Uri, LibraryElement> libraryCanonicalUriMap = |
| 332 new Map<Uri, LibraryElement>(); | 372 new Map<Uri, LibraryElement>(); |
| 333 final Map<Uri, LibraryElement> libraryResourceUriMap = | 373 final Map<Uri, LibraryElement> libraryResourceUriMap = |
| 334 new Map<Uri, LibraryElement>(); | 374 new Map<Uri, LibraryElement>(); |
| 335 final Map<String, LibraryElement> libraryNames = | 375 final Map<String, LibraryElement> libraryNames = |
| 336 new Map<String, LibraryElement>(); | 376 new Map<String, LibraryElement>(); |
| 337 | 377 |
| 338 LibraryDependencyHandler currentHandler; | |
| 339 | |
| 340 Iterable<LibraryElement> get libraries => libraryCanonicalUriMap.values; | 378 Iterable<LibraryElement> get libraries => libraryCanonicalUriMap.values; |
| 341 | 379 |
| 342 LibraryElement lookupLibrary(Uri canonicalUri) { | 380 LibraryElement lookupLibrary(Uri canonicalUri) { |
| 343 return libraryCanonicalUriMap[canonicalUri]; | 381 return libraryCanonicalUriMap[canonicalUri]; |
| 344 } | 382 } |
| 345 | 383 |
| 346 void reset({bool reuseLibrary(LibraryElement library)}) { | 384 void reset({bool reuseLibrary(LibraryElement library)}) { |
| 347 measure(() { | 385 measure(() { |
| 348 assert(currentHandler == null); | |
| 349 | |
| 350 Iterable<LibraryElement> reusedLibraries = null; | 386 Iterable<LibraryElement> reusedLibraries = null; |
| 351 if (reuseLibrary != null) { | 387 if (reuseLibrary != null) { |
| 352 reusedLibraries = measureSubtask(_reuseLibrarySubtaskName, () { | 388 reusedLibraries = measureSubtask(_reuseLibrarySubtaskName, () { |
| 353 // Call [toList] to force eager calls to [reuseLibrary]. | 389 // Call [toList] to force eager calls to [reuseLibrary]. |
| 354 return libraryCanonicalUriMap.values.where(reuseLibrary).toList(); | 390 return libraryCanonicalUriMap.values.where(reuseLibrary).toList(); |
| 355 }); | 391 }); |
| 356 } | 392 } |
| 357 | 393 |
| 358 resetImplementation(reusedLibraries); | 394 resetImplementation(reusedLibraries); |
| 359 }); | 395 }); |
| 360 } | 396 } |
| 361 | 397 |
| 362 void resetImplementation(Iterable<LibraryElement> reusedLibraries) { | 398 void resetImplementation(Iterable<LibraryElement> reusedLibraries) { |
| 363 measure(() { | 399 measure(() { |
| 364 libraryCanonicalUriMap.clear(); | 400 libraryCanonicalUriMap.clear(); |
| 365 libraryResourceUriMap.clear(); | 401 libraryResourceUriMap.clear(); |
| 366 libraryNames.clear(); | 402 libraryNames.clear(); |
| 367 | 403 |
| 368 if (reusedLibraries != null) { | 404 if (reusedLibraries != null) { |
| 369 reusedLibraries.forEach(mapLibrary); | 405 reusedLibraries.forEach(mapLibrary); |
| 370 } | 406 } |
| 371 }); | 407 }); |
| 372 } | 408 } |
| 373 | 409 |
| 374 Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) { | 410 Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) { |
| 375 return measure(() { | 411 return measure(() { |
| 376 assert(currentHandler == null); | |
| 377 | |
| 378 Future<LibraryElement> wrapper(LibraryElement library) { | 412 Future<LibraryElement> wrapper(LibraryElement library) { |
| 379 try { | 413 try { |
| 380 return reuseLibrary(library) | 414 return reuseLibrary(library) |
| 381 .then((bool reuse) => reuse ? library : null); | 415 .then((bool reuse) => reuse ? library : null); |
| 382 } catch (exception, trace) { | 416 } catch (exception, trace) { |
| 383 reporter.onCrashInUserCode( | 417 reporter.onCrashInUserCode( |
| 384 'Uncaught exception in reuseLibrary', exception, trace); | 418 'Uncaught exception in reuseLibrary', exception, trace); |
| 385 rethrow; | 419 rethrow; |
| 386 } | 420 } |
| 387 } | 421 } |
| 388 | 422 |
| 389 List<Future<LibraryElement>> reusedLibrariesFuture = measureSubtask( | 423 List<Future<LibraryElement>> reusedLibrariesFuture = measureSubtask( |
| 390 _reuseLibrarySubtaskName, | 424 _reuseLibrarySubtaskName, |
| 391 () => libraryCanonicalUriMap.values.map(wrapper).toList()); | 425 () => libraryCanonicalUriMap.values.map(wrapper).toList()); |
| 392 | 426 |
| 393 return Future | 427 return Future |
| 394 .wait(reusedLibrariesFuture) | 428 .wait(reusedLibrariesFuture) |
| 395 .then((Iterable<LibraryElement> reusedLibraries) { | 429 .then((Iterable<LibraryElement> reusedLibraries) { |
| 396 resetImplementation(reusedLibraries.where((e) => e != null)); | 430 resetImplementation(reusedLibraries.where((e) => e != null)); |
| 397 }); | 431 }); |
| 398 }); | 432 }); |
| 399 } | 433 } |
| 400 | 434 |
| 401 Future<Null> resetLibraries( | 435 Future<Null> resetLibraries( |
| 402 Future<Iterable<LibraryElement>> reuseLibraries( | 436 Future<Iterable<LibraryElement>> reuseLibraries( |
| 403 Iterable<LibraryElement> libraries)) { | 437 Iterable<LibraryElement> libraries)) { |
| 404 assert(currentHandler == null); | |
| 405 return measureSubtask(_reuseLibrarySubtaskName, () { | 438 return measureSubtask(_reuseLibrarySubtaskName, () { |
| 406 return new Future<Iterable<LibraryElement>>(() { | 439 return new Future<Iterable<LibraryElement>>(() { |
| 407 // Wrap in Future to shield against errors in user code. | 440 // Wrap in Future to shield against errors in user code. |
| 408 return reuseLibraries(libraryCanonicalUriMap.values); | 441 return reuseLibraries(libraryCanonicalUriMap.values); |
| 409 }).catchError((exception, StackTrace trace) { | 442 }).catchError((exception, StackTrace trace) { |
| 410 reporter.onCrashInUserCode( | 443 reporter.onCrashInUserCode( |
| 411 'Uncaught exception in reuseLibraries', exception, trace); | 444 'Uncaught exception in reuseLibraries', exception, trace); |
| 412 throw exception; // Async rethrow. | 445 throw exception; // Async rethrow. |
| 413 }).then((Iterable<LibraryElement> reusedLibraries) { | 446 }).then((Iterable<LibraryElement> reusedLibraries) { |
| 414 measure(() { | 447 measure(() { |
| 415 resetImplementation(reusedLibraries); | 448 resetImplementation(reusedLibraries); |
| 416 }); | 449 }); |
| 417 }); | 450 }); |
| 418 }); | 451 }); |
| 419 } | 452 } |
| 420 | 453 |
| 421 /// Insert [library] in the internal maps. Used for compiler reuse. | 454 /// Insert [library] in the internal maps. Used for compiler reuse. |
| 422 void mapLibrary(LibraryElement library) { | 455 void mapLibrary(LibraryElement library) { |
| 423 libraryCanonicalUriMap[library.canonicalUri] = library; | 456 libraryCanonicalUriMap[library.canonicalUri] = library; |
| 424 | 457 |
| 425 Uri resourceUri = library.entryCompilationUnit.script.resourceUri; | 458 Uri resourceUri = library.entryCompilationUnit.script.resourceUri; |
| 426 libraryResourceUriMap[resourceUri] = library; | 459 libraryResourceUriMap[resourceUri] = library; |
| 427 | 460 |
| 428 if (library.hasLibraryName) { | 461 if (library.hasLibraryName) { |
| 429 String name = library.libraryName; | 462 String name = library.libraryName; |
| 430 libraryNames[name] = library; | 463 libraryNames[name] = library; |
| 431 } | 464 } |
| 432 } | 465 } |
| 433 | 466 |
| 434 Future<LibraryElement> loadLibrary(Uri resolvedUri, | 467 Future<LoadedLibraries> loadLibrary(Uri resolvedUri, |
| 435 {bool skipFileWithPartOfTag: false}) { | 468 {bool skipFileWithPartOfTag: false}) async { |
|
Siggi Cherem (dart-lang)
2017/03/24 17:40:28
seems like you don't need async here
Emily Fortuna
2017/03/24 18:30:19
Done.
| |
| 436 return measure(() { | 469 return measure(() async { |
| 437 assert(currentHandler == null); | 470 LibraryDependencyHandler loader = new LibraryDependencyHandler(this); |
|
Siggi Cherem (dart-lang)
2017/03/24 17:40:27
nit: maybe rename loader as handler?
Emily Fortuna
2017/03/24 18:30:19
Done.
| |
| 438 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the | 471 LibraryElement library = await createLibrary( |
| 439 // loading of a library cluster. | 472 loader, null, resolvedUri, NO_LOCATION_SPANNABLE, |
| 440 currentHandler = new LibraryDependencyHandler(this); | 473 skipFileWithPartOfTag: skipFileWithPartOfTag); |
| 441 return createLibrary( | 474 if (library == null) { |
|
Siggi Cherem (dart-lang)
2017/03/24 17:40:28
style nit: we don't use the {} on this fast-exit c
Emily Fortuna
2017/03/24 18:30:19
Done.
| |
| 442 currentHandler, null, resolvedUri, NO_LOCATION_SPANNABLE, | 475 return null; |
| 443 skipFileWithPartOfTag: skipFileWithPartOfTag) | 476 } |
| 444 .then((LibraryElement library) { | 477 return reporter.withCurrentElement(library, () { |
| 445 if (library == null) { | 478 return measure(() { |
| 446 currentHandler = null; | 479 loader.computeExports(); |
| 447 return null; | 480 return new _LoadedLibraries(library, loader.newLibraries, this); |
| 448 } | |
| 449 return reporter.withCurrentElement(library, () { | |
| 450 return measure(() { | |
| 451 currentHandler.computeExports(); | |
| 452 LoadedLibraries loadedLibraries = new _LoadedLibraries(library, | |
| 453 currentHandler.newLibraries, currentHandler.nodeMap, this); | |
| 454 currentHandler = null; | |
| 455 return listener | |
| 456 .onLibrariesLoaded(loadedLibraries) | |
| 457 .then((_) => library); | |
| 458 }); | |
| 459 }); | 481 }); |
| 460 }); | 482 }); |
| 461 }); | 483 }); |
| 462 } | 484 } |
| 463 | 485 |
| 464 /** | 486 /** |
| 465 * Processes the library tags in [library]. | 487 * Processes the library tags in [library]. |
| 466 * | 488 * |
| 467 * The imported/exported libraries are loaded and processed recursively but | 489 * The imported/exported libraries are loaded and processed recursively but |
| 468 * the import/export scopes are not set up. | 490 * the import/export scopes are not set up. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 541 Part part = tag; | 563 Part part = tag; |
| 542 StringNode uri = part.uri; | 564 StringNode uri = part.uri; |
| 543 Uri resolvedUri = base.resolve(uri.dartString.slowToString()); | 565 Uri resolvedUri = base.resolve(uri.dartString.slowToString()); |
| 544 tagState.checkTag(TagState.PART, part, reporter); | 566 tagState.checkTag(TagState.PART, part, reporter); |
| 545 return scanPart(part, resolvedUri, library); | 567 return scanPart(part, resolvedUri, library); |
| 546 } else { | 568 } else { |
| 547 reporter.internalError(tag, "Unhandled library tag."); | 569 reporter.internalError(tag, "Unhandled library tag."); |
| 548 } | 570 } |
| 549 }); | 571 }); |
| 550 }).then((_) { | 572 }).then((_) { |
| 551 return listener.onLibraryScanned(library, handler); | |
|
Siggi Cherem (dart-lang)
2017/03/24 17:40:27
woo hoo!
| |
| 552 }).then((_) { | |
| 553 return reporter.withCurrentElement(library, () { | 573 return reporter.withCurrentElement(library, () { |
| 554 checkDuplicatedLibraryName(library); | 574 checkDuplicatedLibraryName(library); |
| 555 | 575 |
| 556 // Import dart:core if not already imported. | 576 // Import dart:core if not already imported. |
| 557 if (!importsDartCore && library.canonicalUri != Uris.dart_core) { | 577 if (!importsDartCore && library.canonicalUri != Uris.dart_core) { |
| 558 return createLibrary(handler, null, Uris.dart_core, library) | 578 return createLibrary(handler, null, Uris.dart_core, library) |
| 559 .then((LibraryElement coreLibrary) { | 579 .then((LibraryElement coreLibrary) { |
| 560 handler.registerDependency( | 580 handler.registerDependency( |
| 561 library, | 581 library, |
| 562 new SyntheticImportElement( | 582 new SyntheticImportElement( |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 652 } | 672 } |
| 653 | 673 |
| 654 /// Loads the deserialized [library] with the [handler]. | 674 /// Loads the deserialized [library] with the [handler]. |
| 655 /// | 675 /// |
| 656 /// All libraries imported or exported transitively from [library] will be | 676 /// All libraries imported or exported transitively from [library] will be |
| 657 /// loaded as well. | 677 /// loaded as well. |
| 658 Future<LibraryElement> loadDeserializedLibrary( | 678 Future<LibraryElement> loadDeserializedLibrary( |
| 659 LibraryDependencyHandler handler, LibraryElement library) { | 679 LibraryDependencyHandler handler, LibraryElement library) { |
| 660 libraryCanonicalUriMap[library.canonicalUri] = library; | 680 libraryCanonicalUriMap[library.canonicalUri] = library; |
| 661 handler.registerNewLibrary(library); | 681 handler.registerNewLibrary(library); |
| 662 return listener.onLibraryScanned(library, handler).then((_) { | 682 return Future.forEach(library.imports, (ImportElement import) { |
| 663 return Future.forEach(library.imports, (ImportElement import) { | 683 Uri resolvedUri = library.canonicalUri.resolveUri(import.uri); |
| 664 Uri resolvedUri = library.canonicalUri.resolveUri(import.uri); | 684 return createLibrary(handler, library, resolvedUri, library); |
| 685 }).then((_) { | |
| 686 return Future.forEach(library.exports, (ExportElement export) { | |
| 687 Uri resolvedUri = library.canonicalUri.resolveUri(export.uri); | |
| 665 return createLibrary(handler, library, resolvedUri, library); | 688 return createLibrary(handler, library, resolvedUri, library); |
| 666 }).then((_) { | 689 }).then((_) { |
| 667 return Future.forEach(library.exports, (ExportElement export) { | 690 // TODO(johnniwinther): Shouldn't there be an [ImportElement] for the |
| 668 Uri resolvedUri = library.canonicalUri.resolveUri(export.uri); | 691 // implicit import of dart:core? |
| 669 return createLibrary(handler, library, resolvedUri, library); | 692 return createLibrary(handler, library, Uris.dart_core, library); |
| 670 }).then((_) { | 693 }).then((_) => library); |
| 671 // TODO(johnniwinther): Shouldn't there be an [ImportElement] for the | |
| 672 // implicit import of dart:core? | |
| 673 return createLibrary(handler, library, Uris.dart_core, library); | |
| 674 }).then((_) => library); | |
| 675 }); | |
| 676 }); | 694 }); |
| 677 } | 695 } |
| 678 | 696 |
| 679 Future<Script> _readScript( | 697 Future<Script> _readScript( |
| 680 Spannable spannable, Uri readableUri, Uri resolvedUri) { | 698 Spannable spannable, Uri readableUri, Uri resolvedUri) { |
| 681 if (readableUri == null) { | 699 if (readableUri == null) { |
| 682 return new Future.value(new Script.synthetic(resolvedUri)); | 700 return new Future.value(new Script.synthetic(resolvedUri)); |
| 683 } else { | 701 } else { |
| 684 return scriptLoader.readScript(readableUri, spannable); | 702 return scriptLoader.readScript(readableUri, spannable); |
| 685 } | 703 } |
| 686 } | 704 } |
| 687 | 705 |
| 688 /** | 706 /** |
| 689 * Create (or reuse) a library element for the library specified by the | 707 * Create (or reuse) a library element for the library specified by the |
| 690 * [resolvedUri]. | 708 * [resolvedUri]. |
| 691 * | 709 * |
| 692 * If a new library is created, the [handler] is notified. | 710 * If a new library is created, the [handler] is notified. |
| 693 */ | 711 */ |
| 694 Future<LibraryElement> createLibrary(LibraryDependencyHandler handler, | 712 Future<LibraryElement> createLibrary(LibraryDependencyHandler handler, |
| 695 LibraryElement importingLibrary, Uri resolvedUri, Spannable spannable, | 713 LibraryElement importingLibrary, Uri resolvedUri, Spannable spannable, |
| 696 {bool skipFileWithPartOfTag: false}) { | 714 {bool skipFileWithPartOfTag: false}) async { |
| 697 Uri readableUri = | 715 Uri readableUri = |
| 698 uriTranslator.translate(importingLibrary, resolvedUri, spannable); | 716 uriTranslator.translate(importingLibrary, resolvedUri, spannable); |
| 699 LibraryElement library = libraryCanonicalUriMap[resolvedUri]; | 717 LibraryElement library = libraryCanonicalUriMap[resolvedUri]; |
| 700 if (library != null) { | 718 if (library != null) { |
| 701 return new Future.value(library); | 719 return new Future.value(library); |
| 702 } | 720 } |
| 703 return deserializer.readLibrary(resolvedUri).then((LibraryElement library) { | 721 library = await deserializer.readLibrary(resolvedUri); |
| 704 if (library != null) { | 722 if (library != null) { |
| 705 return loadDeserializedLibrary(handler, library); | 723 return loadDeserializedLibrary(handler, library); |
| 706 } | 724 } |
| 707 return reporter.withCurrentElement(importingLibrary, () { | 725 return reporter.withCurrentElement(importingLibrary, () { |
| 708 return _readScript(spannable, readableUri, resolvedUri) | 726 return _readScript(spannable, readableUri, resolvedUri) |
| 709 .then((Script script) { | 727 .then((Script script) async { |
| 710 if (script == null) return null; | 728 if (script == null) return null; |
| 711 LibraryElement element = | 729 LibraryElement element = |
| 712 createLibrarySync(handler, script, resolvedUri); | 730 createLibrarySync(handler, script, resolvedUri); |
| 713 CompilationUnitElementX compilationUnit = | 731 CompilationUnitElementX compilationUnit = element.entryCompilationUnit; |
| 714 element.entryCompilationUnit; | 732 if (compilationUnit.partTag != null) { |
| 715 if (compilationUnit.partTag != null) { | 733 if (skipFileWithPartOfTag) { |
| 716 if (skipFileWithPartOfTag) { | 734 // TODO(johnniwinther): Avoid calling |
| 717 // TODO(johnniwinther): Avoid calling [listener.onLibraryCreated] | 735 // [compiler.processLoadedLibraries] with this library. |
| 718 // for this library. | 736 libraryCanonicalUriMap.remove(resolvedUri); |
| 719 libraryCanonicalUriMap.remove(resolvedUri); | 737 return null; |
| 720 return null; | |
| 721 } | |
| 722 if (importingLibrary == null) { | |
| 723 DiagnosticMessage error = reporter.withCurrentElement( | |
| 724 compilationUnit, | |
| 725 () => reporter.createMessage( | |
| 726 compilationUnit.partTag, MessageKind.MAIN_HAS_PART_OF)); | |
| 727 reporter.reportError(error); | |
| 728 } else { | |
| 729 DiagnosticMessage error = reporter.withCurrentElement( | |
| 730 compilationUnit, | |
| 731 () => reporter.createMessage( | |
| 732 compilationUnit.partTag, MessageKind.IMPORT_PART_OF)); | |
| 733 DiagnosticMessage info = reporter.withCurrentElement( | |
| 734 importingLibrary, | |
| 735 () => reporter.createMessage( | |
| 736 spannable, MessageKind.IMPORT_PART_OF_HERE)); | |
| 737 reporter.reportError(error, [info]); | |
| 738 } | |
| 739 } | 738 } |
| 740 return processLibraryTags(handler, element).then((_) { | 739 if (importingLibrary == null) { |
| 741 reporter.withCurrentElement(element, () { | 740 DiagnosticMessage error = reporter.withCurrentElement( |
| 742 handler.registerLibraryExports(element); | 741 compilationUnit, |
| 743 }); | 742 () => reporter.createMessage( |
| 744 return element; | 743 compilationUnit.partTag, MessageKind.MAIN_HAS_PART_OF)); |
| 745 }); | 744 reporter.reportError(error); |
| 745 } else { | |
| 746 DiagnosticMessage error = reporter.withCurrentElement( | |
| 747 compilationUnit, | |
| 748 () => reporter.createMessage( | |
| 749 compilationUnit.partTag, MessageKind.IMPORT_PART_OF)); | |
| 750 DiagnosticMessage info = reporter.withCurrentElement( | |
| 751 importingLibrary, | |
| 752 () => reporter.createMessage( | |
| 753 spannable, MessageKind.IMPORT_PART_OF_HERE)); | |
| 754 reporter.reportError(error, [info]); | |
| 755 } | |
| 756 } | |
| 757 await processLibraryTags(handler, element); | |
| 758 reporter.withCurrentElement(element, () { | |
| 759 handler.registerLibraryExports(element); | |
| 746 }); | 760 }); |
| 761 | |
| 762 if (element.isPlatformLibrary && | |
|
Siggi Cherem (dart-lang)
2017/03/24 17:40:28
so nice to see patching done while loading, yay!
Emily Fortuna
2017/03/24 18:30:20
done! I aaaaaalmost did that in my cleanup process
| |
| 763 // Don't patch library currently disallowed. | |
| 764 !element.isSynthesized && | |
| 765 !element.isPatched && | |
| 766 // Don't patch deserialized libraries. | |
| 767 !deserializer.isDeserialized(element)) { | |
| 768 // Apply patch, if any. | |
| 769 Uri patchUri = _patchResolverFunc(element.canonicalUri.path); | |
| 770 if (patchUri != null) { | |
| 771 await _patchParserTask.patchLibrary(handler, patchUri, element); | |
| 772 } | |
| 773 } | |
| 774 return element; | |
| 747 }); | 775 }); |
| 748 }); | 776 }); |
| 749 } | 777 } |
| 750 | 778 |
| 751 LibraryElement createLibrarySync( | 779 LibraryElement createLibrarySync( |
| 752 LibraryDependencyHandler handler, Script script, Uri resolvedUri) { | 780 LibraryDependencyHandler handler, Script script, Uri resolvedUri) { |
| 753 LibraryElement element = new LibraryElementX(script, resolvedUri); | 781 LibraryElement element = new LibraryElementX(script, resolvedUri); |
| 754 return reporter.withCurrentElement(element, () { | 782 return reporter.withCurrentElement(element, () { |
| 755 if (handler != null) { | 783 if (handler != null) { |
| 756 handler.registerNewLibrary(element); | 784 handler.registerNewLibrary(element); |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1323 assert(invariant(library, importingNode != null, | 1351 assert(invariant(library, importingNode != null, |
| 1324 message: "$library has not been registered")); | 1352 message: "$library has not been registered")); |
| 1325 importingNode.registerImportDependency(libraryDependency, loadedLibrary); | 1353 importingNode.registerImportDependency(libraryDependency, loadedLibrary); |
| 1326 } | 1354 } |
| 1327 } | 1355 } |
| 1328 | 1356 |
| 1329 /** | 1357 /** |
| 1330 * Registers [library] for the processing of its import/export scope. | 1358 * Registers [library] for the processing of its import/export scope. |
| 1331 */ | 1359 */ |
| 1332 void registerNewLibrary(LibraryElement library) { | 1360 void registerNewLibrary(LibraryElement library) { |
| 1333 task.listener.onLibraryCreated(library); | |
| 1334 _newLibraries.add(library); | 1361 _newLibraries.add(library); |
| 1335 if (!library.exportsHandled) { | 1362 if (!library.exportsHandled) { |
| 1336 nodeMap[library] = new LibraryDependencyNode(library); | 1363 nodeMap[library] = new LibraryDependencyNode(library); |
| 1337 } | 1364 } |
| 1338 } | 1365 } |
| 1339 | 1366 |
| 1340 /** | 1367 /** |
| 1341 * Registers all top-level entities of [library] as starting point for the | 1368 * Registers all top-level entities of [library] as starting point for the |
| 1342 * fixed-point computation of the import/export scopes. | 1369 * fixed-point computation of the import/export scopes. |
| 1343 */ | 1370 */ |
| 1344 void registerLibraryExports(LibraryElement library) { | 1371 void registerLibraryExports(LibraryElement library) { |
| 1345 nodeMap[library].registerInitialExports(); | 1372 nodeMap[library].registerInitialExports(); |
| 1346 } | 1373 } |
| 1347 | 1374 |
| 1348 Future processLibraryTags(LibraryElement library) { | 1375 Future processLibraryTags(LibraryElement library) { |
| 1349 return task.processLibraryTags(this, library); | 1376 return task.processLibraryTags(this, library); |
| 1350 } | 1377 } |
| 1351 } | 1378 } |
| 1352 | 1379 |
| 1353 /// Information on the bulk of newly loaded libraries through a call to | 1380 /// Information on the set libraries loaded as a result of a call to |
| 1354 /// [LibraryLoader.loadLibrary]. | 1381 /// [LibraryLoader.loadLibrary]. |
| 1355 abstract class LoadedLibraries { | 1382 abstract class LoadedLibraries { |
| 1356 /// The uri passed to [LibraryLoader.loadLibrary]. | 1383 /// The accesss the library object created corresponding to the library |
| 1357 Uri get rootUri; | 1384 /// passed to [LibraryLoader.loadLibrary]. |
| 1385 LibraryElement get rootLibrary; | |
| 1358 | 1386 |
| 1359 /// 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. |
| 1360 bool containsLibrary(Uri uri); | 1388 bool containsLibrary(Uri uri); |
| 1361 | 1389 |
| 1362 /// 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. |
| 1363 LibraryElement getLibrary(Uri uri); | 1391 LibraryElement getLibrary(Uri uri); |
| 1364 | 1392 |
| 1365 /// Applies all libraries in this bulk to [f]. | 1393 /// Applies all libraries in this bulk to [f]. |
| 1366 void forEachLibrary(f(LibraryElement library)); | 1394 void forEachLibrary(f(LibraryElement library)); |
| 1367 | 1395 |
| 1368 /// Applies all imports chains of [uri] in this bulk to [callback]. | 1396 /// Applies all imports chains of [uri] in this bulk to [callback]. |
| 1369 /// | 1397 /// |
| 1370 /// The argument [importChainReversed] to [callback] contains the chain of | 1398 /// The argument [importChainReversed] to [callback] contains the chain of |
| 1371 /// 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 |
| 1372 /// [rootUri]. | 1400 /// the uri that was passed in with [loadLibrary]. |
| 1373 /// | 1401 /// |
| 1374 /// [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 |
| 1375 /// [callback] returns `false`. | 1403 /// [callback] returns `false`. |
| 1376 void forEachImportChain(Uri uri, | 1404 void forEachImportChain(Uri uri, |
| 1377 {bool callback(Link<Uri> importChainReversed)}); | 1405 {bool callback(Link<Uri> importChainReversed)}); |
| 1378 } | 1406 } |
| 1379 | 1407 |
| 1380 class _LoadedLibraries implements LoadedLibraries { | 1408 class _LoadedLibraries implements LoadedLibraries { |
| 1381 final _LibraryLoaderTask task; | 1409 final _LibraryLoaderTask task; |
| 1382 final LibraryElement rootLibrary; | 1410 final LibraryElement rootLibrary; |
| 1383 final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; | 1411 final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; |
| 1384 final Map<LibraryElement, LibraryDependencyNode> nodeMap; | 1412 final List<LibraryElement> _newLibraries; |
| 1385 | 1413 |
| 1386 _LoadedLibraries(this.rootLibrary, Iterable<LibraryElement> libraries, | 1414 _LoadedLibraries(this.rootLibrary, this._newLibraries, this.task) { |
| 1387 this.nodeMap, this.task) { | 1415 _newLibraries.forEach((LibraryElement loadedLibrary) { |
| 1388 libraries.forEach((LibraryElement loadedLibrary) { | |
| 1389 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; | 1416 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; |
| 1390 }); | 1417 }); |
| 1391 } | 1418 } |
| 1392 | 1419 |
| 1393 Uri get rootUri => rootLibrary.canonicalUri; | |
| 1394 | |
| 1395 bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri); | 1420 bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri); |
| 1396 | 1421 |
| 1397 LibraryElement getLibrary(Uri uri) => loadedLibraries[uri]; | 1422 LibraryElement getLibrary(Uri uri) => loadedLibraries[uri]; |
| 1398 | 1423 |
| 1399 void forEachLibrary(f(LibraryElement library)) => nodeMap.keys.forEach(f); | 1424 void forEachLibrary(f(LibraryElement library)) => _newLibraries.forEach(f); |
| 1400 | 1425 |
| 1401 void forEachImportChain(Uri targetUri, | 1426 void forEachImportChain(Uri targetUri, |
| 1402 {bool callback(Link<Uri> importChainReversed)}) { | 1427 {bool callback(Link<Uri> importChainReversed)}) { |
| 1403 bool aborted = false; | 1428 bool aborted = false; |
| 1404 | 1429 |
| 1405 /// Map from libraries to the set of (unreversed) paths to [uri]. | 1430 /// Map from libraries to the set of (unreversed) paths to [uri]. |
| 1406 Map<LibraryElement, Iterable<Link<Uri>>> suffixChainMap = | 1431 Map<LibraryElement, Iterable<Link<Uri>>> suffixChainMap = |
| 1407 <LibraryElement, Iterable<Link<Uri>>>{}; | 1432 <LibraryElement, Iterable<Link<Uri>>>{}; |
| 1408 | 1433 |
| 1409 /// Computes the set of (unreversed) paths to [targetUri]. | 1434 /// Computes the set of (unreversed) paths to [targetUri]. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1468 } | 1493 } |
| 1469 suffixes.add(const Link<Uri>().prepend(canonicalUri)); | 1494 suffixes.add(const Link<Uri>().prepend(canonicalUri)); |
| 1470 } | 1495 } |
| 1471 suffixChainMap[library] = suffixes; | 1496 suffixChainMap[library] = suffixes; |
| 1472 return; | 1497 return; |
| 1473 } | 1498 } |
| 1474 | 1499 |
| 1475 computeSuffixes(rootLibrary, const Link<Uri>()); | 1500 computeSuffixes(rootLibrary, const Link<Uri>()); |
| 1476 } | 1501 } |
| 1477 | 1502 |
| 1478 String toString() => 'root=$rootLibrary,libraries=${loadedLibraries.keys}'; | 1503 String toString() => 'root=$rootLibrary,libraries=${_newLibraries}'; |
| 1479 } | 1504 } |
| 1480 | 1505 |
| 1481 // TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems | 1506 // TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems |
| 1482 // rather low-level. It might be more practical to split the library-loading | 1507 // rather low-level. It might be more practical to split the library-loading |
| 1483 // task itself. The task would continue to do the work of recursively loading | 1508 // task itself. The task would continue to do the work of recursively loading |
| 1484 // dependencies, but it can delegate to a set of subloaders how to do the actual | 1509 // dependencies, but it can delegate to a set of subloaders how to do the actual |
| 1485 // loading. We would then have a list of subloaders that use different | 1510 // loading. We would then have a list of subloaders that use different |
| 1486 // implementations: in-memory cache, deserialization, scanning from files. | 1511 // implementations: in-memory cache, deserialization, scanning from files. |
| 1487 // | 1512 // |
| 1488 // For example, the API might look like this: | 1513 // For example, the API might look like this: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1521 /// Load script from a readable [uri], report any errors using the location of | 1546 /// Load script from a readable [uri], report any errors using the location of |
| 1522 /// the given [spannable]. | 1547 /// the given [spannable]. |
| 1523 Future<Script> readScript(Uri uri, [Spannable spannable]); | 1548 Future<Script> readScript(Uri uri, [Spannable spannable]); |
| 1524 } | 1549 } |
| 1525 | 1550 |
| 1526 /// API used by the library loader to synchronously scan a library or | 1551 /// API used by the library loader to synchronously scan a library or |
| 1527 /// compilation unit and ensure that their library tags are computed. | 1552 /// compilation unit and ensure that their library tags are computed. |
| 1528 abstract class ElementScanner { | 1553 abstract class ElementScanner { |
| 1529 void scanLibrary(LibraryElement library); | 1554 void scanLibrary(LibraryElement library); |
| 1530 void scanUnit(CompilationUnitElement unit); | 1555 void scanUnit(CompilationUnitElement unit); |
| 1531 } | 1556 Token scanFile(SourceFile file); |
|
Siggi Cherem (dart-lang)
2017/03/24 17:40:27
looks like you don't need scanFile after all? coul
Emily Fortuna
2017/03/24 18:30:20
yes thanks.
| |
| 1532 | |
| 1533 /// TODO(sigmund): remove this abstraction. Ideally the loader can produce the | |
| 1534 /// LoadedLibraries results once, and the compiler and choose what to do with | |
| 1535 /// it instead. | |
| 1536 abstract class LibraryLoaderListener { | |
| 1537 /// Called after a request to load a library. The [results] will include all | |
| 1538 /// transitive libraries loaded as a result of the initial request. | |
| 1539 Future onLibrariesLoaded(LoadedLibraries results); | |
| 1540 | |
| 1541 /// Called whenever a library element is created. | |
| 1542 void onLibraryCreated(LibraryElement library); | |
| 1543 | |
| 1544 /// Called whenever a library is scanned from a script file. | |
| 1545 Future onLibraryScanned(LibraryElement library, LibraryLoader loader); | |
| 1546 } | 1557 } |
| 1547 | 1558 |
| 1548 const _reuseLibrarySubtaskName = "Reuse library"; | 1559 const _reuseLibrarySubtaskName = "Reuse library"; |
| OLD | NEW |