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.dart'; | 9 import 'common.dart'; |
| 10 import 'common/names.dart' show | 10 import 'common/names.dart' show |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 import 'elements/modelx.dart' show | 23 import 'elements/modelx.dart' show |
| 24 CompilationUnitElementX, | 24 CompilationUnitElementX, |
| 25 DeferredLoaderGetterElementX, | 25 DeferredLoaderGetterElementX, |
| 26 ErroneousElementX, | 26 ErroneousElementX, |
| 27 ExportElementX, | 27 ExportElementX, |
| 28 ImportElementX, | 28 ImportElementX, |
| 29 LibraryElementX, | 29 LibraryElementX, |
| 30 LibraryDependencyElementX, | 30 LibraryDependencyElementX, |
| 31 PrefixElementX, | 31 PrefixElementX, |
| 32 SyntheticImportElement; | 32 SyntheticImportElement; |
| 33 | 33 import 'environment.dart'; |
| 34 import 'script.dart'; | 34 import 'script.dart'; |
| 35 import 'serialization/serialization.dart' show LibraryDeserializer; | |
| 35 import 'tree/tree.dart'; | 36 import 'tree/tree.dart'; |
| 36 import 'util/util.dart' show | 37 import 'util/util.dart' show |
| 37 Link, | 38 Link, |
| 38 LinkBuilder; | 39 LinkBuilder; |
| 39 | 40 |
| 40 /** | 41 /** |
| 41 * [CompilerTask] for loading libraries and setting up the import/export scopes. | 42 * [CompilerTask] for loading libraries and setting up the import/export scopes. |
| 42 * | 43 * |
| 43 * The library loader uses four different kinds of URIs in different parts of | 44 * The library loader uses four different kinds of URIs in different parts of |
| 44 * the loading process. | 45 * the loading process. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 98 * as when loaded through the dart URI. | 99 * as when loaded through the dart URI. |
| 99 * | 100 * |
| 100 * ## Readable URI ## | 101 * ## Readable URI ## |
| 101 * | 102 * |
| 102 * A 'readable URI' is an absolute URI whose scheme is either 'package' or | 103 * A 'readable URI' is an absolute URI whose scheme is either 'package' or |
| 103 * something supported by the input provider, normally 'file'. Dart URIs such as | 104 * something supported by the input provider, normally 'file'. Dart URIs such as |
| 104 * 'dart:core' and 'dart:_js_helper' are not readable themselves but are instead | 105 * 'dart:core' and 'dart:_js_helper' are not readable themselves but are instead |
| 105 * resolved into a readable URI using the library root URI provided from the | 106 * resolved into a readable URI using the library root URI provided from the |
| 106 * command line and the list of platform libraries found in | 107 * command line and the list of platform libraries found in |
| 107 * 'sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart'. This is done | 108 * 'sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart'. This is done |
| 108 * through the [Compiler.translateResolvedUri] method which checks whether a | 109 * through a [ResolvedUriTranslator] provided from the compiler. The translator |
| 109 * library by that name exists and in case of internal libraries whether access | 110 * checks whether a library by that name exists and in case of internal |
| 110 * is granted. | 111 * libraries whether access is granted. |
| 111 * | 112 * |
| 112 * ## Resource URI ## | 113 * ## Resource URI ## |
| 113 * | 114 * |
| 114 * A 'resource URI' is an absolute URI with a scheme supported by the input | 115 * A 'resource URI' is an absolute URI with a scheme supported by the input |
| 115 * provider. For the standard implementation this means a URI with the 'file' | 116 * provider. For the standard implementation this means a URI with the 'file' |
| 116 * scheme. Readable URIs are converted into resource URIs as part of the | 117 * scheme. Readable URIs are converted into resource URIs as part of the |
| 117 * [Compiler.readScript] method. In the standard implementation the package URIs | 118 * [Compiler.readScript] method. In the standard implementation the package URIs |
| 118 * are converted to file URIs using the package root URI provided on the | 119 * are converted to file URIs using the package root URI provided on the |
| 119 * command line as base. If the package root URI is | 120 * command line as base. If the package root URI is |
| 120 * 'file:///current/working/dir/' then the package URI 'package:foo/bar.dart' | 121 * 'file:///current/working/dir/' then the package URI 'package:foo/bar.dart' |
| 121 * will be resolved to the resource URI | 122 * will be resolved to the resource URI |
| 122 * 'file:///current/working/dir/foo/bar.dart'. | 123 * 'file:///current/working/dir/foo/bar.dart'. |
| 123 * | 124 * |
| 124 * The distinction between readable URI and resource URI is necessary to ensure | 125 * The distinction between readable URI and resource URI is necessary to ensure |
| 125 * that these imports | 126 * that these imports |
| 126 * | 127 * |
| 127 * import 'package:foo.dart' as a; | 128 * import 'package:foo.dart' as a; |
| 128 * import 'packages/foo.dart' as b; | 129 * import 'packages/foo.dart' as b; |
| 129 * | 130 * |
| 130 * do _not_ resolve to the same library when the package root URI happens to | 131 * do _not_ resolve to the same library when the package root URI happens to |
| 131 * point to the 'packages' folder. | 132 * point to the 'packages' folder. |
| 132 * | 133 * |
| 133 */ | 134 */ |
| 134 abstract class LibraryLoaderTask implements CompilerTask { | 135 abstract class LibraryLoaderTask implements CompilerTask { |
| 135 factory LibraryLoaderTask(Compiler compiler) = _LibraryLoaderTask; | 136 factory LibraryLoaderTask(Compiler compiler, |
| 137 ResolvedUriTranslator uriTranslator, | |
| 138 ScriptLoader scriptLoader, | |
| 139 ElementScanner scriptScanner, | |
| 140 LibraryDeserializer deserializer, | |
| 141 LibraryLoaderListener listener, | |
| 142 Environment environment) = _LibraryLoaderTask; | |
| 136 | 143 |
| 137 /// Returns all libraries that have been loaded. | 144 /// Returns all libraries that have been loaded. |
| 138 Iterable<LibraryElement> get libraries; | 145 Iterable<LibraryElement> get libraries; |
| 139 | 146 |
| 140 /// Looks up the library with the [canonicalUri]. | 147 /// Looks up the library with the [canonicalUri]. |
| 141 LibraryElement lookupLibrary(Uri canonicalUri); | 148 LibraryElement lookupLibrary(Uri canonicalUri); |
| 142 | 149 |
| 143 /// Loads the library specified by the [resolvedUri] and returns its | 150 /// Loads the library specified by the [resolvedUri] and returns its |
| 144 /// [LibraryElement]. | 151 /// [LibraryElement]. |
| 145 /// | 152 /// |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 * A list of combinators represented as a list of element names to exclude. | 259 * A list of combinators represented as a list of element names to exclude. |
| 253 */ | 260 */ |
| 254 class HideFilter extends CombinatorFilter { | 261 class HideFilter extends CombinatorFilter { |
| 255 final Set<String> excludedNames; | 262 final Set<String> excludedNames; |
| 256 | 263 |
| 257 HideFilter(this.excludedNames); | 264 HideFilter(this.excludedNames); |
| 258 | 265 |
| 259 bool exclude(Element element) => excludedNames.contains(element.name); | 266 bool exclude(Element element) => excludedNames.contains(element.name); |
| 260 } | 267 } |
| 261 | 268 |
| 262 /** | 269 /// Implementation class for [LibraryLoaderTask]. The distinction between |
| 263 * Implementation class for [LibraryLoader]. The distinction between | 270 /// [LibraryLoaderTask] and [_LibraryLoaderTask] is made to hide internal |
| 264 * [LibraryLoader] and [LibraryLoaderTask] is made to hide internal members from | 271 /// members from the [LibraryLoaderTask] interface. |
| 265 * the [LibraryLoader] interface. | |
| 266 */ | |
| 267 class _LibraryLoaderTask extends CompilerTask implements LibraryLoaderTask { | 272 class _LibraryLoaderTask extends CompilerTask implements LibraryLoaderTask { |
| 268 _LibraryLoaderTask(Compiler compiler) : super(compiler); | 273 /// Translates interal uris (like dart:core) to a disk location. |
|
Harry Terkelsen
2016/03/22 21:49:28
s/interal/internal/
Siggi Cherem (dart-lang)
2016/03/23 22:51:05
Done.
| |
| 274 final ResolvedUriTranslator uriTranslator; | |
| 275 | |
| 276 /// Loads the contents of a a script file (a .dart file). Used when loading | |
|
Harry Terkelsen
2016/03/22 21:49:28
s/a a/a/
Siggi Cherem (dart-lang)
2016/03/23 22:51:05
Done.
| |
| 277 /// libraries from source. | |
| 278 final ScriptLoader scriptLoader; | |
| 279 | |
| 280 /// Provides a diet element model from a script file containing information | |
| 281 /// about imports and exports. Used when loading libraries from source. | |
| 282 final ElementScanner scanner; | |
| 283 | |
| 284 /// Provides a diet element model for a library. Used when loading libraries | |
| 285 /// from a serialized form. | |
| 286 final LibraryDeserializer deserializer; | |
| 287 | |
| 288 /// Hooks to inform others about progress done by this loader. | |
| 289 // TODO(sigmund): move away from this. | |
| 290 final LibraryLoaderListener listener; | |
| 291 | |
| 292 /// Definitions provided via the `-D` command line flags. Used to resolve | |
| 293 /// conditional imports. | |
| 294 final Environment environment; | |
| 295 | |
| 296 _LibraryLoaderTask( | |
| 297 Compiler compiler, this.uriTranslator, this.scriptLoader, | |
| 298 this.scanner, this.deserializer, this.listener, this.environment) | |
| 299 // TODO(sigmund): make measurements separate from compiler | |
| 300 : super(compiler); | |
| 269 | 301 |
| 270 String get name => 'LibraryLoader'; | 302 String get name => 'LibraryLoader'; |
| 271 | 303 |
| 272 final Map<Uri, LibraryElement> libraryCanonicalUriMap = | 304 final Map<Uri, LibraryElement> libraryCanonicalUriMap = |
| 273 new Map<Uri, LibraryElement>(); | 305 new Map<Uri, LibraryElement>(); |
| 274 final Map<Uri, LibraryElement> libraryResourceUriMap = | 306 final Map<Uri, LibraryElement> libraryResourceUriMap = |
| 275 new Map<Uri, LibraryElement>(); | 307 new Map<Uri, LibraryElement>(); |
| 276 final Map<String, LibraryElement> libraryNames = | 308 final Map<String, LibraryElement> libraryNames = |
| 277 new Map<String, LibraryElement>(); | 309 new Map<String, LibraryElement>(); |
| 278 | 310 |
| 279 LibraryDependencyHandler currentHandler; | 311 LibraryDependencyHandler currentHandler; |
| 280 | 312 |
| 281 Iterable<LibraryElement> get libraries => libraryCanonicalUriMap.values; | 313 Iterable<LibraryElement> get libraries => libraryCanonicalUriMap.values; |
| 282 | 314 |
| 283 LibraryElement lookupLibrary(Uri canonicalUri) { | 315 LibraryElement lookupLibrary(Uri canonicalUri) { |
| 284 return libraryCanonicalUriMap[canonicalUri]; | 316 return libraryCanonicalUriMap[canonicalUri]; |
| 285 } | 317 } |
| 286 | 318 |
| 287 void reset({bool reuseLibrary(LibraryElement library)}) { | 319 void reset({bool reuseLibrary(LibraryElement library)}) { |
| 288 measure(() { | 320 measure(() { |
| 289 assert(currentHandler == null); | 321 assert(currentHandler == null); |
| 290 | 322 |
| 291 Iterable<LibraryElement> reusedLibraries = null; | 323 Iterable<LibraryElement> reusedLibraries = null; |
| 292 if (reuseLibrary != null) { | 324 if (reuseLibrary != null) { |
| 325 // TODO(sigmund): make measurements separate from compiler | |
| 293 reusedLibraries = compiler.reuseLibraryTask.measure(() { | 326 reusedLibraries = compiler.reuseLibraryTask.measure(() { |
| 294 // Call [toList] to force eager calls to [reuseLibrary]. | 327 // Call [toList] to force eager calls to [reuseLibrary]. |
| 295 return libraryCanonicalUriMap.values.where(reuseLibrary).toList(); | 328 return libraryCanonicalUriMap.values.where(reuseLibrary).toList(); |
| 296 }); | 329 }); |
| 297 } | 330 } |
| 298 | 331 |
| 299 resetImplementation(reusedLibraries); | 332 resetImplementation(reusedLibraries); |
| 300 }); | 333 }); |
| 301 } | 334 } |
| 302 | 335 |
| 303 void resetImplementation(Iterable<LibraryElement> reusedLibraries) { | 336 void resetImplementation(Iterable<LibraryElement> reusedLibraries) { |
| 304 measure(() { | 337 measure(() { |
| 305 libraryCanonicalUriMap.clear(); | 338 libraryCanonicalUriMap.clear(); |
| 306 libraryResourceUriMap.clear(); | 339 libraryResourceUriMap.clear(); |
| 307 libraryNames.clear(); | 340 libraryNames.clear(); |
| 308 | 341 |
| 309 if (reusedLibraries != null) { | 342 if (reusedLibraries != null) { |
| 310 reusedLibraries.forEach(mapLibrary); | 343 reusedLibraries.forEach(mapLibrary); |
| 311 } | 344 } |
| 312 }); | 345 }); |
| 313 } | 346 } |
| 314 | 347 |
| 315 Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) { | 348 Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) { |
| 316 return measure(() { | 349 return measure(() { |
| 317 assert(currentHandler == null); | 350 assert(currentHandler == null); |
| 318 | 351 |
| 319 Future<LibraryElement> wrapper(LibraryElement library) { | 352 wrapper(lib) => reuseLibrary(lib).then((reuse) => reuse ? lib : null); |
| 320 try { | |
| 321 return reuseLibrary(library).then( | |
| 322 (bool reuse) => reuse ? library : null); | |
| 323 } catch (exception, trace) { | |
| 324 compiler.diagnoseCrashInUserCode( | |
| 325 'Uncaught exception in reuseLibrary', exception, trace); | |
| 326 rethrow; | |
| 327 } | |
| 328 } | |
| 329 | |
| 330 List<Future<LibraryElement>> reusedLibrariesFuture = | 353 List<Future<LibraryElement>> reusedLibrariesFuture = |
| 354 // TODO(sigmund): make measurements separate from compiler | |
| 331 compiler.reuseLibraryTask.measure( | 355 compiler.reuseLibraryTask.measure( |
| 332 () => libraryCanonicalUriMap.values.map(wrapper).toList()); | 356 () => libraryCanonicalUriMap.values.map(wrapper).toList()); |
| 333 | 357 |
| 334 return Future.wait(reusedLibrariesFuture).then( | 358 return Future.wait(reusedLibrariesFuture).then( |
| 335 (List<LibraryElement> reusedLibraries) { | 359 (List<LibraryElement> reusedLibraries) { |
| 336 resetImplementation(reusedLibraries.where((e) => e != null)); | 360 resetImplementation(reusedLibraries.where((e) => e != null)); |
| 337 }); | 361 }); |
| 338 }); | 362 }); |
| 339 } | 363 } |
| 340 | 364 |
| 341 /// Insert [library] in the internal maps. Used for compiler reuse. | 365 /// Insert [library] in the internal maps. Used for compiler reuse. |
| 342 void mapLibrary(LibraryElement library) { | 366 void mapLibrary(LibraryElement library) { |
| 343 libraryCanonicalUriMap[library.canonicalUri] = library; | 367 libraryCanonicalUriMap[library.canonicalUri] = library; |
| 344 | 368 |
| 345 Uri resourceUri = library.entryCompilationUnit.script.resourceUri; | 369 Uri resourceUri = library.entryCompilationUnit.script.resourceUri; |
| 346 libraryResourceUriMap[resourceUri] = library; | 370 libraryResourceUriMap[resourceUri] = library; |
| 347 | 371 |
| 348 if (library.hasLibraryName) { | 372 if (library.hasLibraryName) { |
| 349 String name = library.libraryName; | 373 String name = library.libraryName; |
| 350 libraryNames[name] = library; | 374 libraryNames[name] = library; |
| 351 } | 375 } |
| 352 } | 376 } |
| 353 | 377 |
| 354 Future<LibraryElement> loadLibrary( | 378 Future<LibraryElement> loadLibrary(Uri resolvedUri, |
| 355 Uri resolvedUri, | |
| 356 {bool skipFileWithPartOfTag: false}) { | 379 {bool skipFileWithPartOfTag: false}) { |
| 357 return measure(() { | 380 return measure(() { |
| 358 assert(currentHandler == null); | 381 assert(currentHandler == null); |
| 359 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the | 382 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the |
| 360 // loading of a library cluster. | 383 // loading of a library cluster. |
| 361 currentHandler = new LibraryDependencyHandler(this); | 384 currentHandler = new LibraryDependencyHandler(this); |
| 362 return createLibrary(currentHandler, null, resolvedUri, | 385 return createLibrary(currentHandler, null, resolvedUri, |
| 363 skipFileWithPartOfTag: skipFileWithPartOfTag) | 386 skipFileWithPartOfTag: skipFileWithPartOfTag) |
| 364 .then((LibraryElement library) { | 387 .then((LibraryElement library) { |
| 365 if (library == null) { | 388 if (library == null) { |
| 366 currentHandler = null; | 389 currentHandler = null; |
| 367 return null; | 390 return null; |
| 368 } | 391 } |
| 369 return reporter.withCurrentElement(library, () { | 392 return reporter.withCurrentElement(library, () { |
| 370 return measure(() { | 393 return measure(() { |
| 371 currentHandler.computeExports(); | 394 currentHandler.computeExports(); |
| 372 LoadedLibraries loadedLibraries = new _LoadedLibraries( | 395 LoadedLibraries loadedLibraries = new _LoadedLibraries( |
| 373 library, | 396 library, |
| 374 currentHandler.newLibraries, | 397 currentHandler.newLibraries, |
| 375 currentHandler.nodeMap, | 398 currentHandler.nodeMap, |
| 376 this); | 399 this); |
| 377 currentHandler = null; | 400 currentHandler = null; |
| 378 return compiler.onLibrariesLoaded(loadedLibraries) | 401 return listener.onLibrariesLoaded(loadedLibraries) |
| 379 .then((_) => library); | 402 .then((_) => library); |
| 380 }); | 403 }); |
| 381 }); | 404 }); |
| 382 }); | 405 }); |
| 383 }); | 406 }); |
| 384 } | 407 } |
| 385 | 408 |
| 386 /** | 409 /** |
| 387 * Processes the library tags in [library]. | 410 * Processes the library tags in [library]. |
| 388 * | 411 * |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 402 return reporter.withCurrentElement(library, () { | 425 return reporter.withCurrentElement(library, () { |
| 403 | 426 |
| 404 Uri computeUri(LibraryDependency node) { | 427 Uri computeUri(LibraryDependency node) { |
| 405 StringNode uriNode = node.uri; | 428 StringNode uriNode = node.uri; |
| 406 if (node.conditionalUris != null) { | 429 if (node.conditionalUris != null) { |
| 407 for (ConditionalUri conditionalUri in node.conditionalUris) { | 430 for (ConditionalUri conditionalUri in node.conditionalUris) { |
| 408 String key = conditionalUri.key.slowNameString; | 431 String key = conditionalUri.key.slowNameString; |
| 409 String value = conditionalUri.value == null | 432 String value = conditionalUri.value == null |
| 410 ? "true" | 433 ? "true" |
| 411 : conditionalUri.value.dartString.slowToString(); | 434 : conditionalUri.value.dartString.slowToString(); |
| 412 String actual = compiler.fromEnvironment(key); | 435 String actual = environment.valueOf(key); |
| 413 if (value == actual) { | 436 if (value == actual) { |
| 414 uriNode = conditionalUri.uri; | 437 uriNode = conditionalUri.uri; |
| 415 break; | 438 break; |
| 416 } | 439 } |
| 417 } | 440 } |
| 418 } | 441 } |
| 419 String tagUriString = uriNode.dartString.slowToString(); | 442 String tagUriString = uriNode.dartString.slowToString(); |
| 420 try { | 443 try { |
| 421 return Uri.parse(tagUriString); | 444 return Uri.parse(tagUriString); |
| 422 } on FormatException { | 445 } on FormatException { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 465 Part part = tag; | 488 Part part = tag; |
| 466 StringNode uri = part.uri; | 489 StringNode uri = part.uri; |
| 467 Uri resolvedUri = base.resolve(uri.dartString.slowToString()); | 490 Uri resolvedUri = base.resolve(uri.dartString.slowToString()); |
| 468 tagState.checkTag(TagState.PART, part, reporter); | 491 tagState.checkTag(TagState.PART, part, reporter); |
| 469 return scanPart(part, resolvedUri, library); | 492 return scanPart(part, resolvedUri, library); |
| 470 } else { | 493 } else { |
| 471 reporter.internalError(tag, "Unhandled library tag."); | 494 reporter.internalError(tag, "Unhandled library tag."); |
| 472 } | 495 } |
| 473 }); | 496 }); |
| 474 }).then((_) { | 497 }).then((_) { |
| 475 return compiler.onLibraryScanned(library, handler); | 498 return listener.onLibraryScanned(library, handler); |
| 476 }).then((_) { | 499 }).then((_) { |
| 477 return reporter.withCurrentElement(library, () { | 500 return reporter.withCurrentElement(library, () { |
| 478 checkDuplicatedLibraryName(library); | 501 checkDuplicatedLibraryName(library); |
| 479 | 502 |
| 480 // Import dart:core if not already imported. | 503 // Import dart:core if not already imported. |
| 481 if (!importsDartCore && library.canonicalUri != Uris.dart_core) { | 504 if (!importsDartCore && library.canonicalUri != Uris.dart_core) { |
| 482 return createLibrary(handler, null, Uris.dart_core) | 505 return createLibrary(handler, null, Uris.dart_core) |
| 483 .then((LibraryElement coreLibrary) { | 506 .then((LibraryElement coreLibrary) { |
| 484 handler.registerDependency(library, | 507 handler.registerDependency(library, |
| 485 new SyntheticImportElement( | 508 new SyntheticImportElement( |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 542 } | 565 } |
| 543 } | 566 } |
| 544 } | 567 } |
| 545 | 568 |
| 546 /** | 569 /** |
| 547 * Handle a part tag in the scope of [library]. The [resolvedUri] given is | 570 * Handle a part tag in the scope of [library]. The [resolvedUri] given is |
| 548 * used as is, any URI resolution should be done beforehand. | 571 * used as is, any URI resolution should be done beforehand. |
| 549 */ | 572 */ |
| 550 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) { | 573 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) { |
| 551 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri); | 574 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri); |
| 552 Uri readableUri = compiler.translateResolvedUri(library, resolvedUri, part); | 575 Uri readableUri = uriTranslator.translate(library, resolvedUri, part); |
| 553 if (readableUri == null) return new Future.value(); | 576 if (readableUri == null) return new Future.value(); |
| 554 return reporter.withCurrentElement(library, () { | 577 return reporter.withCurrentElement(library, () { |
| 555 return compiler.readScript(part, readableUri). | 578 return scriptLoader.readScript(readableUri, part).then((Script script) { |
| 556 then((Script sourceScript) { | 579 if (script == null) return; |
| 557 if (sourceScript == null) return; | 580 return createUnitSync(script, library); |
| 558 | 581 }); |
| 559 CompilationUnitElementX unit = | |
| 560 new CompilationUnitElementX(sourceScript, library); | |
| 561 reporter.withCurrentElement(unit, () { | |
| 562 compiler.scanner.scan(unit); | |
| 563 if (unit.partTag == null && !sourceScript.isSynthesized) { | |
| 564 reporter.reportErrorMessage( | |
| 565 unit, MessageKind.MISSING_PART_OF_TAG); | |
| 566 } | |
| 567 }); | |
| 568 }); | |
| 569 }); | 582 }); |
| 570 } | 583 } |
| 571 | 584 |
| 572 /** | 585 /** |
| 573 * Handle an import/export tag by loading the referenced library and | 586 * Handle an import/export tag by loading the referenced library and |
| 574 * registering its dependency in [handler] for the computation of the import/ | 587 * registering its dependency in [handler] for the computation of the import/ |
| 575 * export scope. If the tag does not contain a valid URI, then its dependency | 588 * export scope. If the tag does not contain a valid URI, then its dependency |
| 576 * is not registered in [handler]. | 589 * is not registered in [handler]. |
| 577 */ | 590 */ |
| 578 Future<Null> registerLibraryFromImportExport( | 591 Future<Null> registerLibraryFromImportExport( |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 594 | 607 |
| 595 /// Loads the deserialized [library] with the [handler]. | 608 /// Loads the deserialized [library] with the [handler]. |
| 596 /// | 609 /// |
| 597 /// All libraries imported or exported transitively from [library] will be | 610 /// All libraries imported or exported transitively from [library] will be |
| 598 /// loaded as well. | 611 /// loaded as well. |
| 599 Future<LibraryElement> loadDeserializedLibrary( | 612 Future<LibraryElement> loadDeserializedLibrary( |
| 600 LibraryDependencyHandler handler, | 613 LibraryDependencyHandler handler, |
| 601 LibraryElement library) { | 614 LibraryElement library) { |
| 602 libraryCanonicalUriMap[library.canonicalUri] = library; | 615 libraryCanonicalUriMap[library.canonicalUri] = library; |
| 603 handler.registerNewLibrary(library); | 616 handler.registerNewLibrary(library); |
| 604 return compiler.onLibraryScanned(library, handler).then((_) { | 617 return listener.onLibraryScanned(library, handler).then((_) { |
| 605 return Future.forEach(library.imports, (ImportElement import) { | 618 return Future.forEach(library.imports, (ImportElement import) { |
| 606 return createLibrary(handler, library, import.uri); | 619 return createLibrary(handler, library, import.uri); |
| 607 }).then((_) { | 620 }).then((_) { |
| 608 return Future.forEach(library.exports, (ExportElement export) { | 621 return Future.forEach(library.exports, (ExportElement export) { |
| 609 return createLibrary(handler, library, export.uri); | 622 return createLibrary(handler, library, export.uri); |
| 610 }).then((_) => library); | 623 }).then((_) => library); |
| 611 }); | 624 }); |
| 612 }); | 625 }); |
| 613 } | 626 } |
| 614 | 627 |
| 628 Future<Script> _readScript(Spannable spannable, | |
| 629 Uri readableUri, Uri resolvedUri) { | |
| 630 if (readableUri == null) { | |
| 631 return new Future.value(new Script.synthetic(resolvedUri)); | |
| 632 } else { | |
| 633 return scriptLoader.readScript(readableUri, spannable); | |
| 634 } | |
| 635 } | |
| 636 | |
| 615 /** | 637 /** |
| 616 * Create (or reuse) a library element for the library specified by the | 638 * Create (or reuse) a library element for the library specified by the |
| 617 * [resolvedUri]. | 639 * [resolvedUri]. |
| 618 * | 640 * |
| 619 * If a new library is created, the [handler] is notified. | 641 * If a new library is created, the [handler] is notified. |
| 620 */ | 642 */ |
| 621 Future<LibraryElement> createLibrary( | 643 Future<LibraryElement> createLibrary( |
| 622 LibraryDependencyHandler handler, | 644 LibraryDependencyHandler handler, |
| 623 LibraryElement importingLibrary, | 645 LibraryElement importingLibrary, |
| 624 Uri resolvedUri, | 646 Uri resolvedUri, |
| 625 {Spannable node, | 647 {Spannable node, |
| 626 bool skipFileWithPartOfTag: false}) { | 648 bool skipFileWithPartOfTag: false}) { |
| 627 Uri readableUri = | 649 Uri readableUri = |
| 628 compiler.translateResolvedUri(importingLibrary, resolvedUri, node); | 650 uriTranslator.translate(importingLibrary, resolvedUri, node); |
| 629 LibraryElement library = libraryCanonicalUriMap[resolvedUri]; | 651 LibraryElement library = libraryCanonicalUriMap[resolvedUri]; |
| 630 if (library != null) { | 652 if (library != null) { |
| 631 return new Future.value(library); | 653 return new Future.value(library); |
| 632 } | 654 } |
| 633 library = compiler.serialization.readLibrary(resolvedUri); | 655 library = deserializer.readLibrary(resolvedUri); |
| 634 if (library != null) { | 656 if (library != null) { |
| 635 return loadDeserializedLibrary(handler, library); | 657 return loadDeserializedLibrary(handler, library); |
| 636 } | 658 } |
| 637 var readScript = compiler.readScript; | |
| 638 if (readableUri == null) { | |
| 639 readableUri = resolvedUri; | |
| 640 readScript = compiler.synthesizeScript; | |
| 641 } | |
| 642 return reporter.withCurrentElement(importingLibrary, () { | 659 return reporter.withCurrentElement(importingLibrary, () { |
| 643 return readScript(node, readableUri).then((Script script) { | 660 return _readScript(node, readableUri, resolvedUri).then((Script script) { |
| 644 if (script == null) return null; | 661 if (script == null) return null; |
| 645 LibraryElement element = | 662 LibraryElement element = |
| 646 createLibrarySync(handler, script, resolvedUri); | 663 createLibrarySync(handler, script, resolvedUri); |
| 647 CompilationUnitElementX compilationUnit = element.entryCompilationUnit; | 664 CompilationUnitElementX compilationUnit = element.entryCompilationUnit; |
| 648 if (compilationUnit.partTag != null) { | 665 if (compilationUnit.partTag != null) { |
| 649 if (skipFileWithPartOfTag) { | 666 if (skipFileWithPartOfTag) { |
| 650 // TODO(johnniwinther): Avoid calling [Compiler.onLibraryCreated] | 667 // TODO(johnniwinther): Avoid calling [listener.onLibraryCreated] |
| 651 // for this library. | 668 // for this library. |
| 652 libraryCanonicalUriMap.remove(resolvedUri); | 669 libraryCanonicalUriMap.remove(resolvedUri); |
| 653 return null; | 670 return null; |
| 654 } | 671 } |
| 655 if (importingLibrary == null) { | 672 if (importingLibrary == null) { |
| 656 DiagnosticMessage error = reporter.withCurrentElement( | 673 DiagnosticMessage error = reporter.withCurrentElement( |
| 657 compilationUnit, | 674 compilationUnit, |
| 658 () => reporter.createMessage( | 675 () => reporter.createMessage( |
| 659 compilationUnit.partTag, MessageKind.MAIN_HAS_PART_OF)); | 676 compilationUnit.partTag, MessageKind.MAIN_HAS_PART_OF)); |
| 660 reporter.reportError(error); | 677 reporter.reportError(error); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 674 return processLibraryTags(handler, element).then((_) { | 691 return processLibraryTags(handler, element).then((_) { |
| 675 reporter.withCurrentElement(element, () { | 692 reporter.withCurrentElement(element, () { |
| 676 handler.registerLibraryExports(element); | 693 handler.registerLibraryExports(element); |
| 677 }); | 694 }); |
| 678 return element; | 695 return element; |
| 679 }); | 696 }); |
| 680 }); | 697 }); |
| 681 }); | 698 }); |
| 682 } | 699 } |
| 683 | 700 |
| 684 LibraryElement createLibrarySync( | 701 LibraryElement createLibrarySync(LibraryDependencyHandler handler, |
| 685 LibraryDependencyHandler handler, | 702 Script script, Uri resolvedUri) { |
| 686 Script script, | |
| 687 Uri resolvedUri) { | |
| 688 LibraryElement element = new LibraryElementX(script, resolvedUri); | 703 LibraryElement element = new LibraryElementX(script, resolvedUri); |
| 689 return reporter.withCurrentElement(element, () { | 704 return reporter.withCurrentElement(element, () { |
| 690 if (handler != null) { | 705 if (handler != null) { |
| 691 handler.registerNewLibrary(element); | 706 handler.registerNewLibrary(element); |
| 692 libraryCanonicalUriMap[resolvedUri] = element; | 707 libraryCanonicalUriMap[resolvedUri] = element; |
| 693 } | 708 } |
| 694 compiler.scanner.scanLibrary(element); | 709 scanner.scanLibrary(element); |
| 695 return element; | 710 return element; |
| 696 }); | 711 }); |
| 697 } | 712 } |
| 713 | |
| 714 CompilationUnitElement createUnitSync(Script script, LibraryElement library) { | |
| 715 CompilationUnitElementX unit = new CompilationUnitElementX(script, library); | |
| 716 reporter.withCurrentElement(unit, () { | |
| 717 scanner.scanUnit(unit); | |
| 718 if (unit.partTag == null && !script.isSynthesized) { | |
| 719 reporter.reportErrorMessage(unit, MessageKind.MISSING_PART_OF_TAG); | |
| 720 } | |
| 721 }); | |
| 722 return unit; | |
| 723 } | |
| 698 } | 724 } |
| 699 | 725 |
| 700 | 726 |
| 701 /// A state machine for checking script tags come in the correct order. | 727 /// A state machine for checking script tags come in the correct order. |
| 702 class TagState { | 728 class TagState { |
| 703 /// Initial state. | 729 /// Initial state. |
| 704 static const int NO_TAG_SEEN = 0; | 730 static const int NO_TAG_SEEN = 0; |
| 705 | 731 |
| 706 /// Passed to [checkTag] when a library declaration (the syntax "library | 732 /// Passed to [checkTag] when a library declaration (the syntax "library |
| 707 /// name;") has been seen. Not an actual state. | 733 /// name;") has been seen. Not an actual state. |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1167 * Newly loaded libraries and their corresponding node in the library | 1193 * Newly loaded libraries and their corresponding node in the library |
| 1168 * dependency graph. Libraries that have already been fully loaded are not | 1194 * dependency graph. Libraries that have already been fully loaded are not |
| 1169 * part of the dependency graph of this handler since their export scopes have | 1195 * part of the dependency graph of this handler since their export scopes have |
| 1170 * already been computed. | 1196 * already been computed. |
| 1171 */ | 1197 */ |
| 1172 Map<LibraryElement, LibraryDependencyNode> nodeMap = | 1198 Map<LibraryElement, LibraryDependencyNode> nodeMap = |
| 1173 new Map<LibraryElement, LibraryDependencyNode>(); | 1199 new Map<LibraryElement, LibraryDependencyNode>(); |
| 1174 | 1200 |
| 1175 LibraryDependencyHandler(this.task); | 1201 LibraryDependencyHandler(this.task); |
| 1176 | 1202 |
| 1177 Compiler get compiler => task.compiler; | |
| 1178 | |
| 1179 DiagnosticReporter get reporter => task.reporter; | 1203 DiagnosticReporter get reporter => task.reporter; |
| 1180 | 1204 |
| 1181 /// The libraries created with this handler. | 1205 /// The libraries created with this handler. |
| 1182 Iterable<LibraryElement> get newLibraries => _newLibraries; | 1206 Iterable<LibraryElement> get newLibraries => _newLibraries; |
| 1183 | 1207 |
| 1184 /** | 1208 /** |
| 1185 * Performs a fixed-point computation on the export scopes of all registered | 1209 * Performs a fixed-point computation on the export scopes of all registered |
| 1186 * libraries and creates the import/export of the libraries based on the | 1210 * libraries and creates the import/export of the libraries based on the |
| 1187 * fixed-point. | 1211 * fixed-point. |
| 1188 */ | 1212 */ |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1261 assert(invariant(library, importingNode != null, | 1285 assert(invariant(library, importingNode != null, |
| 1262 message: "$library has not been registered")); | 1286 message: "$library has not been registered")); |
| 1263 importingNode.registerImportDependency(libraryDependency, loadedLibrary); | 1287 importingNode.registerImportDependency(libraryDependency, loadedLibrary); |
| 1264 } | 1288 } |
| 1265 } | 1289 } |
| 1266 | 1290 |
| 1267 /** | 1291 /** |
| 1268 * Registers [library] for the processing of its import/export scope. | 1292 * Registers [library] for the processing of its import/export scope. |
| 1269 */ | 1293 */ |
| 1270 void registerNewLibrary(LibraryElement library) { | 1294 void registerNewLibrary(LibraryElement library) { |
| 1271 compiler.onLibraryCreated(library); | 1295 task.listener.onLibraryCreated(library); |
| 1272 _newLibraries.add(library); | 1296 _newLibraries.add(library); |
| 1273 if (!library.exportsHandled) { | 1297 if (!library.exportsHandled) { |
| 1274 nodeMap[library] = new LibraryDependencyNode(library); | 1298 nodeMap[library] = new LibraryDependencyNode(library); |
| 1275 } | 1299 } |
| 1276 } | 1300 } |
| 1277 | 1301 |
| 1278 /** | 1302 /** |
| 1279 * Registers all top-level entities of [library] as starting point for the | 1303 * Registers all top-level entities of [library] as starting point for the |
| 1280 * fixed-point computation of the import/export scopes. | 1304 * fixed-point computation of the import/export scopes. |
| 1281 */ | 1305 */ |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1413 } | 1437 } |
| 1414 suffixChainMap[library] = suffixes; | 1438 suffixChainMap[library] = suffixes; |
| 1415 return; | 1439 return; |
| 1416 } | 1440 } |
| 1417 | 1441 |
| 1418 computeSuffixes(rootLibrary, const Link<Uri>()); | 1442 computeSuffixes(rootLibrary, const Link<Uri>()); |
| 1419 } | 1443 } |
| 1420 | 1444 |
| 1421 String toString() => 'root=$rootLibrary,libraries=${loadedLibraries.keys}'; | 1445 String toString() => 'root=$rootLibrary,libraries=${loadedLibraries.keys}'; |
| 1422 } | 1446 } |
| 1447 | |
| 1448 /// API used by the library loader to translate internal SDK uri's into file | |
|
Harry Terkelsen
2016/03/22 21:49:28
Be consistent with "uri's" or "URIs"
Siggi Cherem (dart-lang)
2016/03/23 22:51:05
Done.
| |
| 1449 /// system readable URIs. | |
| 1450 abstract class ResolvedUriTranslator { | |
| 1451 // TODO(sigmund): move here the comments from library loader. | |
| 1452 /// Translate the resolved [uri] in the context of [importingLibrary]. | |
| 1453 /// | |
| 1454 /// Use [spannable] for error reporting. | |
| 1455 Uri translate( | |
| 1456 LibraryElement importingLibrary, Uri uri, [Spannable spannable]); | |
| 1457 } | |
| 1458 | |
| 1459 | |
| 1460 // TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems | |
| 1461 // rather low-level. It might be more practical to split the library-loading | |
| 1462 // task itself. The task would continue to do the work of recursively loading | |
| 1463 // dependencies, but it can delegate to a set of subloaders how to do the actual | |
| 1464 // loading. We would then have a list of subloaders that use different | |
| 1465 // implementations: in-memory cache, deserialization, scanning from files. | |
| 1466 // | |
| 1467 // For example, the API might look like this: | |
| 1468 // | |
| 1469 // /// APIs to create [LibraryElement] and [CompilationUnitElements] given it's | |
| 1470 // /// URI. | |
| 1471 // abstract class SubLoader { | |
| 1472 // /// Return the library corresponding to the script at [uri]. | |
| 1473 // /// | |
| 1474 // /// Use [spannable] for error reporting. | |
| 1475 // Future<LibraryElement> createLibrary(Uri uri, [Spannable spannable]); | |
| 1476 // | |
| 1477 // /// Return the compilation unit at [uri] that is a part of [library]. | |
| 1478 // Future<CompilationUnitElement> createUnit(Uri uri, LibraryElement library, | |
| 1479 // [Spannable spannable]); | |
| 1480 // } | |
| 1481 // | |
| 1482 // /// A [SubLoader] that parses a serialized form of the element model to | |
| 1483 // /// produce the results. | |
| 1484 // class DeserializingUnitElementCreator implements SubLoader { | |
| 1485 // ... | |
| 1486 // } | |
| 1487 // | |
| 1488 // /// A [SubLoader] that finds the script sources and does a diet parse | |
| 1489 // /// on them to produces the results. | |
| 1490 // class ScanningUnitElementCreator implements SubLoader { | |
| 1491 // ... | |
| 1492 // } | |
| 1493 // | |
| 1494 // Each subloader would internally create what they need (a scanner, a | |
| 1495 // deserializer), and we wouldn't need to create abstractions to pass in | |
| 1496 // something that is only used by the loader. | |
| 1497 | |
| 1498 /// API used by the library loader to request scripts from the compiler system. | |
| 1499 abstract class ScriptLoader { | |
| 1500 /// Load script from a readable [uri], report any errors using the location of | |
| 1501 /// the given [spannable]. | |
| 1502 Future<Script> readScript(Uri uri, [Spannable spannable]); | |
| 1503 } | |
| 1504 | |
| 1505 /// API used byt he library loader to sychronously scan a library or compilation | |
|
Harry Terkelsen
2016/03/22 21:49:28
byt he
sychronously
Siggi Cherem (dart-lang)
2016/03/23 22:51:05
Done.
| |
| 1506 /// unit and ensure that their library tags are computed. | |
| 1507 abstract class ElementScanner { | |
| 1508 void scanLibrary(LibraryElement library); | |
| 1509 void scanUnit(CompilationUnitElement unit); | |
| 1510 } | |
| 1511 | |
| 1512 | |
| 1513 /// TODO(sigmund): remove this abstraction. Ideally the loader can produce the | |
| 1514 /// LoadedLibraries results once, and the compiler and choose what to do with | |
| 1515 /// it instead. | |
| 1516 abstract class LibraryLoaderListener { | |
|
Harry Terkelsen
2016/03/22 21:49:28
Maybe the loader can just publish a stream of libr
Siggi Cherem (dart-lang)
2016/03/23 22:51:05
Might be worth looking into a similar idea in the
| |
| 1517 /// Called after a request to load a library. The [results] will include all | |
| 1518 /// transitive libraries loaded as a result of the initial request. | |
| 1519 Future onLibrariesLoaded(LoadedLibraries results); | |
| 1520 | |
| 1521 /// Called whenever a library element is created. | |
| 1522 void onLibraryCreated(LibraryElement library); | |
| 1523 | |
| 1524 /// Called whenever a library is scanned from a script file. | |
| 1525 Future onLibraryScanned(LibraryElement library, LibraryLoader loader); | |
| 1526 } | |
| OLD | NEW |