Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: pkg/compiler/lib/src/library_loader.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 Uris;
11 Uris; 11 import 'common/tasks.dart' show CompilerTask;
12 import 'common/tasks.dart' show 12 import 'compiler.dart' show Compiler;
13 CompilerTask; 13 import 'elements/elements.dart'
14 import 'compiler.dart' show 14 show
15 Compiler; 15 CompilationUnitElement,
16 import 'elements/elements.dart' show 16 Element,
17 CompilationUnitElement, 17 ImportElement,
18 Element, 18 ExportElement,
19 ImportElement, 19 LibraryElement,
20 ExportElement, 20 PrefixElement;
21 LibraryElement, 21 import 'elements/modelx.dart'
22 PrefixElement; 22 show
23 import 'elements/modelx.dart' show 23 CompilationUnitElementX,
24 CompilationUnitElementX, 24 DeferredLoaderGetterElementX,
25 DeferredLoaderGetterElementX, 25 ErroneousElementX,
26 ErroneousElementX, 26 ExportElementX,
27 ExportElementX, 27 ImportElementX,
28 ImportElementX, 28 LibraryElementX,
29 LibraryElementX, 29 LibraryDependencyElementX,
30 LibraryDependencyElementX, 30 PrefixElementX,
31 PrefixElementX, 31 SyntheticImportElement;
32 SyntheticImportElement;
33 import 'environment.dart'; 32 import 'environment.dart';
34 import 'script.dart'; 33 import 'script.dart';
35 import 'serialization/serialization.dart' show LibraryDeserializer; 34 import 'serialization/serialization.dart' show LibraryDeserializer;
36 import 'tree/tree.dart'; 35 import 'tree/tree.dart';
37 import 'util/util.dart' show 36 import 'util/util.dart' show Link, LinkBuilder;
38 Link,
39 LinkBuilder;
40 37
41 /** 38 /**
42 * [CompilerTask] for loading libraries and setting up the import/export scopes. 39 * [CompilerTask] for loading libraries and setting up the import/export scopes.
43 * 40 *
44 * The library loader uses four different kinds of URIs in different parts of 41 * The library loader uses four different kinds of URIs in different parts of
45 * the loading process. 42 * the loading process.
46 * 43 *
47 * ## User URI ## 44 * ## User URI ##
48 * 45 *
49 * A 'user URI' is a URI provided by the user in code and as the main entry URI 46 * A 'user URI' is a URI provided by the user in code and as the main entry URI
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 * that these imports 123 * that these imports
127 * 124 *
128 * import 'package:foo.dart' as a; 125 * import 'package:foo.dart' as a;
129 * import 'packages/foo.dart' as b; 126 * import 'packages/foo.dart' as b;
130 * 127 *
131 * do _not_ resolve to the same library when the package root URI happens to 128 * do _not_ resolve to the same library when the package root URI happens to
132 * point to the 'packages' folder. 129 * point to the 'packages' folder.
133 * 130 *
134 */ 131 */
135 abstract class LibraryLoaderTask implements CompilerTask { 132 abstract class LibraryLoaderTask implements CompilerTask {
136 factory LibraryLoaderTask(Compiler compiler, 133 factory LibraryLoaderTask(
134 Compiler compiler,
137 ResolvedUriTranslator uriTranslator, 135 ResolvedUriTranslator uriTranslator,
138 ScriptLoader scriptLoader, 136 ScriptLoader scriptLoader,
139 ElementScanner scriptScanner, 137 ElementScanner scriptScanner,
140 LibraryDeserializer deserializer, 138 LibraryDeserializer deserializer,
141 LibraryLoaderListener listener, 139 LibraryLoaderListener listener,
142 Environment environment) = _LibraryLoaderTask; 140 Environment environment) = _LibraryLoaderTask;
143 141
144 /// Returns all libraries that have been loaded. 142 /// Returns all libraries that have been loaded.
145 Iterable<LibraryElement> get libraries; 143 Iterable<LibraryElement> get libraries;
146 144
147 /// Looks up the library with the [canonicalUri]. 145 /// Looks up the library with the [canonicalUri].
148 LibraryElement lookupLibrary(Uri canonicalUri); 146 LibraryElement lookupLibrary(Uri canonicalUri);
149 147
150 /// Loads the library specified by the [resolvedUri] and returns its 148 /// Loads the library specified by the [resolvedUri] and returns its
151 /// [LibraryElement]. 149 /// [LibraryElement].
152 /// 150 ///
153 /// If the library is not already loaded, the method creates the 151 /// If the library is not already loaded, the method creates the
154 /// [LibraryElement] for the library and computes the import/export scope, 152 /// [LibraryElement] for the library and computes the import/export scope,
155 /// loading and computing the import/export scopes of all required libraries 153 /// loading and computing the import/export scopes of all required libraries
156 /// in the process. The method handles cyclic dependency between libraries. 154 /// in the process. The method handles cyclic dependency between libraries.
157 /// 155 ///
158 /// If [skipFileWithPartOfTag] is `true`, `null` is returned if the 156 /// If [skipFileWithPartOfTag] is `true`, `null` is returned if the
159 /// compilation unit for [resolvedUri] contains a `part of` tag. This is only 157 /// compilation unit for [resolvedUri] contains a `part of` tag. This is only
160 /// used for analysis through [Compiler.analyzeUri]. 158 /// used for analysis through [Compiler.analyzeUri].
161 Future<LibraryElement> loadLibrary( 159 Future<LibraryElement> loadLibrary(Uri resolvedUri,
162 Uri resolvedUri,
163 {bool skipFileWithPartOfTag: false}); 160 {bool skipFileWithPartOfTag: false});
164 161
165 /// Reset the library loader task to prepare for compilation. If provided, 162 /// Reset the library loader task to prepare for compilation. If provided,
166 /// libraries matching [reuseLibrary] are reused. 163 /// libraries matching [reuseLibrary] are reused.
167 /// 164 ///
168 /// This method is used for incremental compilation. 165 /// This method is used for incremental compilation.
169 void reset({bool reuseLibrary(LibraryElement library)}); 166 void reset({bool reuseLibrary(LibraryElement library)});
170 167
171 /// Asynchronous version of [reset]. 168 /// Asynchronous version of [reset].
172 Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)); 169 Future resetAsync(Future<bool> reuseLibrary(LibraryElement library));
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 final LibraryDeserializer deserializer; 283 final LibraryDeserializer deserializer;
287 284
288 /// Hooks to inform others about progress done by this loader. 285 /// Hooks to inform others about progress done by this loader.
289 // TODO(sigmund): move away from this. 286 // TODO(sigmund): move away from this.
290 final LibraryLoaderListener listener; 287 final LibraryLoaderListener listener;
291 288
292 /// Definitions provided via the `-D` command line flags. Used to resolve 289 /// Definitions provided via the `-D` command line flags. Used to resolve
293 /// conditional imports. 290 /// conditional imports.
294 final Environment environment; 291 final Environment environment;
295 292
296 _LibraryLoaderTask( 293 _LibraryLoaderTask(Compiler compiler, this.uriTranslator, this.scriptLoader,
297 Compiler compiler, this.uriTranslator, this.scriptLoader,
298 this.scanner, this.deserializer, this.listener, this.environment) 294 this.scanner, this.deserializer, this.listener, this.environment)
299 // TODO(sigmund): make measurements separate from compiler 295 // TODO(sigmund): make measurements separate from compiler
300 : super(compiler); 296 : super(compiler);
301 297
302 String get name => 'LibraryLoader'; 298 String get name => 'LibraryLoader';
303 299
304 final Map<Uri, LibraryElement> libraryCanonicalUriMap = 300 final Map<Uri, LibraryElement> libraryCanonicalUriMap =
305 new Map<Uri, LibraryElement>(); 301 new Map<Uri, LibraryElement>();
306 final Map<Uri, LibraryElement> libraryResourceUriMap = 302 final Map<Uri, LibraryElement> libraryResourceUriMap =
307 new Map<Uri, LibraryElement>(); 303 new Map<Uri, LibraryElement>();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) { 344 Future resetAsync(Future<bool> reuseLibrary(LibraryElement library)) {
349 return measure(() { 345 return measure(() {
350 assert(currentHandler == null); 346 assert(currentHandler == null);
351 347
352 wrapper(lib) => reuseLibrary(lib).then((reuse) => reuse ? lib : null); 348 wrapper(lib) => reuseLibrary(lib).then((reuse) => reuse ? lib : null);
353 List<Future<LibraryElement>> reusedLibrariesFuture = 349 List<Future<LibraryElement>> reusedLibrariesFuture =
354 // TODO(sigmund): make measurements separate from compiler 350 // TODO(sigmund): make measurements separate from compiler
355 compiler.reuseLibraryTask.measure( 351 compiler.reuseLibraryTask.measure(
356 () => libraryCanonicalUriMap.values.map(wrapper).toList()); 352 () => libraryCanonicalUriMap.values.map(wrapper).toList());
357 353
358 return Future.wait(reusedLibrariesFuture).then( 354 return Future
359 (List<LibraryElement> reusedLibraries) { 355 .wait(reusedLibrariesFuture)
360 resetImplementation(reusedLibraries.where((e) => e != null)); 356 .then((List<LibraryElement> reusedLibraries) {
361 }); 357 resetImplementation(reusedLibraries.where((e) => e != null));
358 });
362 }); 359 });
363 } 360 }
364 361
365 /// Insert [library] in the internal maps. Used for compiler reuse. 362 /// Insert [library] in the internal maps. Used for compiler reuse.
366 void mapLibrary(LibraryElement library) { 363 void mapLibrary(LibraryElement library) {
367 libraryCanonicalUriMap[library.canonicalUri] = library; 364 libraryCanonicalUriMap[library.canonicalUri] = library;
368 365
369 Uri resourceUri = library.entryCompilationUnit.script.resourceUri; 366 Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
370 libraryResourceUriMap[resourceUri] = library; 367 libraryResourceUriMap[resourceUri] = library;
371 368
372 if (library.hasLibraryName) { 369 if (library.hasLibraryName) {
373 String name = library.libraryName; 370 String name = library.libraryName;
374 libraryNames[name] = library; 371 libraryNames[name] = library;
375 } 372 }
376 } 373 }
377 374
378 Future<LibraryElement> loadLibrary(Uri resolvedUri, 375 Future<LibraryElement> loadLibrary(Uri resolvedUri,
379 {bool skipFileWithPartOfTag: false}) { 376 {bool skipFileWithPartOfTag: false}) {
380 return measure(() { 377 return measure(() {
381 assert(currentHandler == null); 378 assert(currentHandler == null);
382 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the 379 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the
383 // loading of a library cluster. 380 // loading of a library cluster.
384 currentHandler = new LibraryDependencyHandler(this); 381 currentHandler = new LibraryDependencyHandler(this);
385 return createLibrary(currentHandler, null, resolvedUri, 382 return createLibrary(currentHandler, null, resolvedUri,
386 skipFileWithPartOfTag: skipFileWithPartOfTag) 383 skipFileWithPartOfTag: skipFileWithPartOfTag)
387 .then((LibraryElement library) { 384 .then((LibraryElement library) {
388 if (library == null) { 385 if (library == null) {
389 currentHandler = null; 386 currentHandler = null;
390 return null; 387 return null;
391 } 388 }
392 return reporter.withCurrentElement(library, () { 389 return reporter.withCurrentElement(library, () {
393 return measure(() { 390 return measure(() {
394 currentHandler.computeExports(); 391 currentHandler.computeExports();
395 LoadedLibraries loadedLibraries = new _LoadedLibraries( 392 LoadedLibraries loadedLibraries = new _LoadedLibraries(library,
396 library, 393 currentHandler.newLibraries, currentHandler.nodeMap, this);
397 currentHandler.newLibraries,
398 currentHandler.nodeMap,
399 this);
400 currentHandler = null; 394 currentHandler = null;
401 return listener.onLibrariesLoaded(loadedLibraries) 395 return listener
396 .onLibrariesLoaded(loadedLibraries)
402 .then((_) => library); 397 .then((_) => library);
403 }); 398 });
404 }); 399 });
405 }); 400 });
406 }); 401 });
407 } 402 }
408 403
409 /** 404 /**
410 * Processes the library tags in [library]. 405 * Processes the library tags in [library].
411 * 406 *
412 * The imported/exported libraries are loaded and processed recursively but 407 * The imported/exported libraries are loaded and processed recursively but
413 * the import/export scopes are not set up. 408 * the import/export scopes are not set up.
414 */ 409 */
415 Future processLibraryTags(LibraryDependencyHandler handler, 410 Future processLibraryTags(
416 LibraryElementX library) { 411 LibraryDependencyHandler handler, LibraryElementX library) {
417 TagState tagState = new TagState(); 412 TagState tagState = new TagState();
418 413
419 bool importsDartCore = false; 414 bool importsDartCore = false;
420 LinkBuilder<LibraryDependencyElementX> libraryDependencies = 415 LinkBuilder<LibraryDependencyElementX> libraryDependencies =
421 new LinkBuilder<LibraryDependencyElementX>(); 416 new LinkBuilder<LibraryDependencyElementX>();
422 Uri base = library.entryCompilationUnit.script.readableUri; 417 Uri base = library.entryCompilationUnit.script.readableUri;
423 418
424 return Future.forEach(library.tags, (LibraryTag tag) { 419 return Future.forEach(library.tags, (LibraryTag tag) {
425 return reporter.withCurrentElement(library, () { 420 return reporter.withCurrentElement(library, () {
426
427 Uri computeUri(LibraryDependency node) { 421 Uri computeUri(LibraryDependency node) {
428 StringNode uriNode = node.uri; 422 StringNode uriNode = node.uri;
429 if (node.conditionalUris != null) { 423 if (node.conditionalUris != null) {
430 for (ConditionalUri conditionalUri in node.conditionalUris) { 424 for (ConditionalUri conditionalUri in node.conditionalUris) {
431 String key = conditionalUri.key.slowNameString; 425 String key = conditionalUri.key.slowNameString;
432 String value = conditionalUri.value == null 426 String value = conditionalUri.value == null
433 ? "true" 427 ? "true"
434 : conditionalUri.value.dartString.slowToString(); 428 : conditionalUri.value.dartString.slowToString();
435 String actual = environment.valueOf(key); 429 String actual = environment.valueOf(key);
436 if (value == actual) { 430 if (value == actual) {
437 uriNode = conditionalUri.uri; 431 uriNode = conditionalUri.uri;
438 break; 432 break;
439 } 433 }
440 } 434 }
441 } 435 }
442 String tagUriString = uriNode.dartString.slowToString(); 436 String tagUriString = uriNode.dartString.slowToString();
443 try { 437 try {
444 return Uri.parse(tagUriString); 438 return Uri.parse(tagUriString);
445 } on FormatException { 439 } on FormatException {
446 reporter.reportErrorMessage( 440 reporter.reportErrorMessage(
447 node.uri, 441 node.uri, MessageKind.INVALID_URI, {'uri': tagUriString});
448 MessageKind.INVALID_URI, {'uri': tagUriString});
449 return null; 442 return null;
450 } 443 }
451 } 444 }
452 445
453 if (tag.isImport) { 446 if (tag.isImport) {
454 Uri uri = computeUri(tag); 447 Uri uri = computeUri(tag);
455 if (uri == null) { 448 if (uri == null) {
456 // Skip this erroneous import. 449 // Skip this erroneous import.
457 return new Future.value(); 450 return new Future.value();
458 } 451 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 }).then((_) { 490 }).then((_) {
498 return listener.onLibraryScanned(library, handler); 491 return listener.onLibraryScanned(library, handler);
499 }).then((_) { 492 }).then((_) {
500 return reporter.withCurrentElement(library, () { 493 return reporter.withCurrentElement(library, () {
501 checkDuplicatedLibraryName(library); 494 checkDuplicatedLibraryName(library);
502 495
503 // Import dart:core if not already imported. 496 // Import dart:core if not already imported.
504 if (!importsDartCore && library.canonicalUri != Uris.dart_core) { 497 if (!importsDartCore && library.canonicalUri != Uris.dart_core) {
505 return createLibrary(handler, null, Uris.dart_core) 498 return createLibrary(handler, null, Uris.dart_core)
506 .then((LibraryElement coreLibrary) { 499 .then((LibraryElement coreLibrary) {
507 handler.registerDependency(library, 500 handler.registerDependency(
501 library,
508 new SyntheticImportElement( 502 new SyntheticImportElement(
509 library.entryCompilationUnit, Uris.dart_core), 503 library.entryCompilationUnit, Uris.dart_core),
510 coreLibrary); 504 coreLibrary);
511 }); 505 });
512 } 506 }
513 }); 507 });
514 }).then((_) { 508 }).then((_) {
515 return Future.forEach(libraryDependencies.toList(), 509 return Future.forEach(libraryDependencies.toList(),
516 (LibraryDependencyElementX libraryDependency) { 510 (LibraryDependencyElementX libraryDependency) {
517 return reporter.withCurrentElement(library, () { 511 return reporter.withCurrentElement(library, () {
518 return registerLibraryFromImportExport( 512 return registerLibraryFromImportExport(
519 handler, library, libraryDependency); 513 handler, library, libraryDependency);
520 }); 514 });
521 }); 515 });
522 }); 516 });
523 } 517 }
524 518
525 void checkDuplicatedLibraryName(LibraryElement library) { 519 void checkDuplicatedLibraryName(LibraryElement library) {
526 if (library.isInternalLibrary) return; 520 if (library.isInternalLibrary) return;
527 Uri resourceUri = library.entryCompilationUnit.script.resourceUri; 521 Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
528 LibraryElement existing = 522 LibraryElement existing =
529 libraryResourceUriMap.putIfAbsent(resourceUri, () => library); 523 libraryResourceUriMap.putIfAbsent(resourceUri, () => library);
530 if (!identical(existing, library)) { 524 if (!identical(existing, library)) {
531 if (library.hasLibraryName) { 525 if (library.hasLibraryName) {
532 reporter.withCurrentElement(library, () { 526 reporter.withCurrentElement(library, () {
533 reporter.reportWarningMessage( 527 reporter.reportWarningMessage(
534 library, 528 library, MessageKind.DUPLICATED_LIBRARY_RESOURCE, {
535 MessageKind.DUPLICATED_LIBRARY_RESOURCE, 529 'libraryName': library.libraryName,
536 {'libraryName': library.libraryName, 530 'resourceUri': resourceUri,
537 'resourceUri': resourceUri, 531 'canonicalUri1': library.canonicalUri,
538 'canonicalUri1': library.canonicalUri, 532 'canonicalUri2': existing.canonicalUri
539 'canonicalUri2': existing.canonicalUri}); 533 });
540 }); 534 });
541 } else { 535 } else {
542 reporter.reportHintMessage( 536 reporter.reportHintMessage(library, MessageKind.DUPLICATED_RESOURCE, {
543 library, 537 'resourceUri': resourceUri,
544 MessageKind.DUPLICATED_RESOURCE, 538 'canonicalUri1': library.canonicalUri,
545 {'resourceUri': resourceUri, 539 'canonicalUri2': existing.canonicalUri
546 'canonicalUri1': library.canonicalUri, 540 });
547 'canonicalUri2': existing.canonicalUri});
548 } 541 }
549 } else if (library.hasLibraryName) { 542 } else if (library.hasLibraryName) {
550 String name = library.libraryName; 543 String name = library.libraryName;
551 existing = libraryNames.putIfAbsent(name, () => library); 544 existing = libraryNames.putIfAbsent(name, () => library);
552 if (!identical(existing, library)) { 545 if (!identical(existing, library)) {
553 reporter.withCurrentElement(library, () { 546 reporter.withCurrentElement(library, () {
554 reporter.reportWarningMessage( 547 reporter.reportWarningMessage(library,
555 library, 548 MessageKind.DUPLICATED_LIBRARY_NAME, {'libraryName': name});
556 MessageKind.DUPLICATED_LIBRARY_NAME,
557 {'libraryName': name});
558 }); 549 });
559 reporter.withCurrentElement(existing, () { 550 reporter.withCurrentElement(existing, () {
560 reporter.reportWarningMessage( 551 reporter.reportWarningMessage(existing,
561 existing, 552 MessageKind.DUPLICATED_LIBRARY_NAME, {'libraryName': name});
562 MessageKind.DUPLICATED_LIBRARY_NAME,
563 {'libraryName': name});
564 }); 553 });
565 } 554 }
566 } 555 }
567 } 556 }
568 557
569 /** 558 /**
570 * Handle a part tag in the scope of [library]. The [resolvedUri] given is 559 * Handle a part tag in the scope of [library]. The [resolvedUri] given is
571 * used as is, any URI resolution should be done beforehand. 560 * used as is, any URI resolution should be done beforehand.
572 */ 561 */
573 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) { 562 Future scanPart(Part part, Uri resolvedUri, LibraryElement library) {
574 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri); 563 if (!resolvedUri.isAbsolute) throw new ArgumentError(resolvedUri);
575 Uri readableUri = uriTranslator.translate(library, resolvedUri, part); 564 Uri readableUri = uriTranslator.translate(library, resolvedUri, part);
576 if (readableUri == null) return new Future.value(); 565 if (readableUri == null) return new Future.value();
577 return reporter.withCurrentElement(library, () { 566 return reporter.withCurrentElement(library, () {
578 return scriptLoader.readScript(readableUri, part).then((Script script) { 567 return scriptLoader.readScript(readableUri, part).then((Script script) {
579 if (script == null) return; 568 if (script == null) return;
580 createUnitSync(script, library); 569 createUnitSync(script, library);
581 }); 570 });
582 }); 571 });
583 } 572 }
584 573
585 /** 574 /**
586 * Handle an import/export tag by loading the referenced library and 575 * Handle an import/export tag by loading the referenced library and
587 * registering its dependency in [handler] for the computation of the import/ 576 * registering its dependency in [handler] for the computation of the import/
588 * export scope. If the tag does not contain a valid URI, then its dependency 577 * export scope. If the tag does not contain a valid URI, then its dependency
589 * is not registered in [handler]. 578 * is not registered in [handler].
590 */ 579 */
591 Future<Null> registerLibraryFromImportExport( 580 Future<Null> registerLibraryFromImportExport(LibraryDependencyHandler handler,
592 LibraryDependencyHandler handler, 581 LibraryElement library, LibraryDependencyElementX libraryDependency) {
593 LibraryElement library,
594 LibraryDependencyElementX libraryDependency) {
595 Uri base = library.canonicalUri; 582 Uri base = library.canonicalUri;
596 Uri resolvedUri = base.resolveUri(libraryDependency.uri); 583 Uri resolvedUri = base.resolveUri(libraryDependency.uri);
597 return createLibrary(handler, library, resolvedUri, node: libraryDependency) 584 return createLibrary(handler, library, resolvedUri, node: libraryDependency)
598 .then((LibraryElement loadedLibrary) { 585 .then((LibraryElement loadedLibrary) {
599 if (loadedLibrary == null) return; 586 if (loadedLibrary == null) return;
600 reporter.withCurrentElement(library, () { 587 reporter.withCurrentElement(library, () {
601 libraryDependency.libraryDependency = loadedLibrary; 588 libraryDependency.libraryDependency = loadedLibrary;
602 handler.registerDependency( 589 handler.registerDependency(library, libraryDependency, loadedLibrary);
603 library, libraryDependency, loadedLibrary); 590 });
604 }); 591 });
605 });
606 } 592 }
607 593
608 /// Loads the deserialized [library] with the [handler]. 594 /// Loads the deserialized [library] with the [handler].
609 /// 595 ///
610 /// All libraries imported or exported transitively from [library] will be 596 /// All libraries imported or exported transitively from [library] will be
611 /// loaded as well. 597 /// loaded as well.
612 Future<LibraryElement> loadDeserializedLibrary( 598 Future<LibraryElement> loadDeserializedLibrary(
613 LibraryDependencyHandler handler, 599 LibraryDependencyHandler handler, LibraryElement library) {
614 LibraryElement library) {
615 libraryCanonicalUriMap[library.canonicalUri] = library; 600 libraryCanonicalUriMap[library.canonicalUri] = library;
616 handler.registerNewLibrary(library); 601 handler.registerNewLibrary(library);
617 return listener.onLibraryScanned(library, handler).then((_) { 602 return listener.onLibraryScanned(library, handler).then((_) {
618 return Future.forEach(library.imports, (ImportElement import) { 603 return Future.forEach(library.imports, (ImportElement import) {
619 return createLibrary(handler, library, import.uri); 604 return createLibrary(handler, library, import.uri);
620 }).then((_) { 605 }).then((_) {
621 return Future.forEach(library.exports, (ExportElement export) { 606 return Future.forEach(library.exports, (ExportElement export) {
622 return createLibrary(handler, library, export.uri); 607 return createLibrary(handler, library, export.uri);
623 }).then((_) => library); 608 }).then((_) => library);
624 }); 609 });
625 }); 610 });
626 } 611 }
627 612
628 Future<Script> _readScript(Spannable spannable, 613 Future<Script> _readScript(
629 Uri readableUri, Uri resolvedUri) { 614 Spannable spannable, Uri readableUri, Uri resolvedUri) {
630 if (readableUri == null) { 615 if (readableUri == null) {
631 return new Future.value(new Script.synthetic(resolvedUri)); 616 return new Future.value(new Script.synthetic(resolvedUri));
632 } else { 617 } else {
633 return scriptLoader.readScript(readableUri, spannable); 618 return scriptLoader.readScript(readableUri, spannable);
634 } 619 }
635 } 620 }
636 621
637 /** 622 /**
638 * Create (or reuse) a library element for the library specified by the 623 * Create (or reuse) a library element for the library specified by the
639 * [resolvedUri]. 624 * [resolvedUri].
640 * 625 *
641 * If a new library is created, the [handler] is notified. 626 * If a new library is created, the [handler] is notified.
642 */ 627 */
643 Future<LibraryElement> createLibrary( 628 Future<LibraryElement> createLibrary(LibraryDependencyHandler handler,
644 LibraryDependencyHandler handler, 629 LibraryElement importingLibrary, Uri resolvedUri,
645 LibraryElement importingLibrary, 630 {Spannable node, bool skipFileWithPartOfTag: false}) {
646 Uri resolvedUri,
647 {Spannable node,
648 bool skipFileWithPartOfTag: false}) {
649 Uri readableUri = 631 Uri readableUri =
650 uriTranslator.translate(importingLibrary, resolvedUri, node); 632 uriTranslator.translate(importingLibrary, resolvedUri, node);
651 LibraryElement library = libraryCanonicalUriMap[resolvedUri]; 633 LibraryElement library = libraryCanonicalUriMap[resolvedUri];
652 if (library != null) { 634 if (library != null) {
653 return new Future.value(library); 635 return new Future.value(library);
654 } 636 }
655 library = deserializer.readLibrary(resolvedUri); 637 library = deserializer.readLibrary(resolvedUri);
656 if (library != null) { 638 if (library != null) {
657 return loadDeserializedLibrary(handler, library); 639 return loadDeserializedLibrary(handler, library);
658 } 640 }
(...skipping 17 matching lines...) Expand all
676 compilationUnit.partTag, MessageKind.MAIN_HAS_PART_OF)); 658 compilationUnit.partTag, MessageKind.MAIN_HAS_PART_OF));
677 reporter.reportError(error); 659 reporter.reportError(error);
678 } else { 660 } else {
679 DiagnosticMessage error = reporter.withCurrentElement( 661 DiagnosticMessage error = reporter.withCurrentElement(
680 compilationUnit, 662 compilationUnit,
681 () => reporter.createMessage( 663 () => reporter.createMessage(
682 compilationUnit.partTag, MessageKind.IMPORT_PART_OF)); 664 compilationUnit.partTag, MessageKind.IMPORT_PART_OF));
683 DiagnosticMessage info = reporter.withCurrentElement( 665 DiagnosticMessage info = reporter.withCurrentElement(
684 importingLibrary, 666 importingLibrary,
685 () => reporter.createMessage( 667 () => reporter.createMessage(
686 node, 668 node, MessageKind.IMPORT_PART_OF_HERE));
687 MessageKind.IMPORT_PART_OF_HERE));
688 reporter.reportError(error, [info]); 669 reporter.reportError(error, [info]);
689 } 670 }
690 } 671 }
691 return processLibraryTags(handler, element).then((_) { 672 return processLibraryTags(handler, element).then((_) {
692 reporter.withCurrentElement(element, () { 673 reporter.withCurrentElement(element, () {
693 handler.registerLibraryExports(element); 674 handler.registerLibraryExports(element);
694 }); 675 });
695 return element; 676 return element;
696 }); 677 });
697 }); 678 });
698 }); 679 });
699 } 680 }
700 681
701 LibraryElement createLibrarySync(LibraryDependencyHandler handler, 682 LibraryElement createLibrarySync(
702 Script script, Uri resolvedUri) { 683 LibraryDependencyHandler handler, Script script, Uri resolvedUri) {
703 LibraryElement element = new LibraryElementX(script, resolvedUri); 684 LibraryElement element = new LibraryElementX(script, resolvedUri);
704 return reporter.withCurrentElement(element, () { 685 return reporter.withCurrentElement(element, () {
705 if (handler != null) { 686 if (handler != null) {
706 handler.registerNewLibrary(element); 687 handler.registerNewLibrary(element);
707 libraryCanonicalUriMap[resolvedUri] = element; 688 libraryCanonicalUriMap[resolvedUri] = element;
708 } 689 }
709 scanner.scanLibrary(element); 690 scanner.scanLibrary(element);
710 return element; 691 return element;
711 }); 692 });
712 } 693 }
713 694
714 CompilationUnitElement createUnitSync(Script script, LibraryElement library) { 695 CompilationUnitElement createUnitSync(Script script, LibraryElement library) {
715 CompilationUnitElementX unit = new CompilationUnitElementX(script, library); 696 CompilationUnitElementX unit = new CompilationUnitElementX(script, library);
716 reporter.withCurrentElement(unit, () { 697 reporter.withCurrentElement(unit, () {
717 scanner.scanUnit(unit); 698 scanner.scanUnit(unit);
718 if (unit.partTag == null && !script.isSynthesized) { 699 if (unit.partTag == null && !script.isSynthesized) {
719 reporter.reportErrorMessage(unit, MessageKind.MISSING_PART_OF_TAG); 700 reporter.reportErrorMessage(unit, MessageKind.MISSING_PART_OF_TAG);
720 } 701 }
721 }); 702 });
722 return unit; 703 return unit;
723 } 704 }
724 } 705 }
725 706
726
727 /// A state machine for checking script tags come in the correct order. 707 /// A state machine for checking script tags come in the correct order.
728 class TagState { 708 class TagState {
729 /// Initial state. 709 /// Initial state.
730 static const int NO_TAG_SEEN = 0; 710 static const int NO_TAG_SEEN = 0;
731 711
732 /// Passed to [checkTag] when a library declaration (the syntax "library 712 /// Passed to [checkTag] when a library declaration (the syntax "library
733 /// name;") has been seen. Not an actual state. 713 /// name;") has been seen. Not an actual state.
734 static const int LIBRARY = 1; 714 static const int LIBRARY = 1;
735 715
736 /// The state after the first library declaration. 716 /// The state after the first library declaration.
737 static const int AFTER_LIBRARY_DECLARATION = 2; 717 static const int AFTER_LIBRARY_DECLARATION = 2;
738 718
739 /// The state after a import or export declaration has been seen, but before 719 /// The state after a import or export declaration has been seen, but before
740 /// a part tag has been seen. 720 /// a part tag has been seen.
741 static const int IMPORT_OR_EXPORT = 3; 721 static const int IMPORT_OR_EXPORT = 3;
742 722
743 /// The state after a part tag has been seen. 723 /// The state after a part tag has been seen.
744 static const int PART = 4; 724 static const int PART = 4;
745 725
746 /// Encodes transition function for state machine. 726 /// Encodes transition function for state machine.
747 static const List<int> NEXT = const <int>[ 727 static const List<int> NEXT = const <int>[
748 NO_TAG_SEEN, 728 NO_TAG_SEEN,
749 AFTER_LIBRARY_DECLARATION, // Only one library tag is allowed. 729 AFTER_LIBRARY_DECLARATION, // Only one library tag is allowed.
750 IMPORT_OR_EXPORT, 730 IMPORT_OR_EXPORT,
751 IMPORT_OR_EXPORT, 731 IMPORT_OR_EXPORT,
752 PART, 732 PART,
753 ]; 733 ];
754 734
755 int tagState = TagState.NO_TAG_SEEN; 735 int tagState = TagState.NO_TAG_SEEN;
756 736
757 bool hasLibraryDeclaration = false; 737 bool hasLibraryDeclaration = false;
758 738
759 /// If [value] is less than [tagState] complain. Regardless, update 739 /// If [value] is less than [tagState] complain. Regardless, update
760 /// [tagState] using transition function for state machine. 740 /// [tagState] using transition function for state machine.
761 void checkTag(int value, LibraryTag tag, DiagnosticReporter reporter) { 741 void checkTag(int value, LibraryTag tag, DiagnosticReporter reporter) {
762 if (tagState > value) { 742 if (tagState > value) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 */ 777 */
798 class ImportLink { 778 class ImportLink {
799 final ImportElementX import; 779 final ImportElementX import;
800 final LibraryElement importedLibrary; 780 final LibraryElement importedLibrary;
801 781
802 ImportLink(this.import, this.importedLibrary); 782 ImportLink(this.import, this.importedLibrary);
803 783
804 /** 784 /**
805 * Imports the library into the [importingLibrary]. 785 * Imports the library into the [importingLibrary].
806 */ 786 */
807 void importLibrary(DiagnosticReporter reporter, 787 void importLibrary(
808 LibraryElementX importingLibrary) { 788 DiagnosticReporter reporter, LibraryElementX importingLibrary) {
809 assert(invariant(importingLibrary, 789 assert(invariant(importingLibrary, importedLibrary.exportsHandled,
810 importedLibrary.exportsHandled, 790 message: 'Exports not handled on $importedLibrary'));
811 message: 'Exports not handled on $importedLibrary'));
812 Import tag = import.node; 791 Import tag = import.node;
813 CombinatorFilter combinatorFilter = 792 CombinatorFilter combinatorFilter = new CombinatorFilter.fromTag(tag);
814 new CombinatorFilter.fromTag(tag);
815 if (tag != null && tag.prefix != null) { 793 if (tag != null && tag.prefix != null) {
816 String prefix = tag.prefix.source; 794 String prefix = tag.prefix.source;
817 Element existingElement = importingLibrary.find(prefix); 795 Element existingElement = importingLibrary.find(prefix);
818 PrefixElementX prefixElement; 796 PrefixElementX prefixElement;
819 if (existingElement == null || !existingElement.isPrefix) { 797 if (existingElement == null || !existingElement.isPrefix) {
820 prefixElement = new PrefixElementX( 798 prefixElement = new PrefixElementX(
821 prefix, 799 prefix,
822 importingLibrary.entryCompilationUnit, 800 importingLibrary.entryCompilationUnit,
823 tag.getBeginToken(), 801 tag.getBeginToken(),
824 tag.isDeferred ? import : null); 802 tag.isDeferred ? import : null);
825 } else { 803 } else {
826 prefixElement = existingElement; 804 prefixElement = existingElement;
827 } 805 }
828 importingLibrary.addToScope(prefixElement, reporter); 806 importingLibrary.addToScope(prefixElement, reporter);
829 importedLibrary.forEachExport((Element element) { 807 importedLibrary.forEachExport((Element element) {
830 if (combinatorFilter.exclude(element)) return; 808 if (combinatorFilter.exclude(element)) return;
831 prefixElement.addImport(element, import, reporter); 809 prefixElement.addImport(element, import, reporter);
832 }); 810 });
833 import.prefix = prefixElement; 811 import.prefix = prefixElement;
834 if (prefixElement.isDeferred) { 812 if (prefixElement.isDeferred) {
835 prefixElement.addImport( 813 prefixElement.addImport(
836 new DeferredLoaderGetterElementX(prefixElement), 814 new DeferredLoaderGetterElementX(prefixElement), import, reporter);
837 import, reporter);
838 } 815 }
839 } else { 816 } else {
840 importedLibrary.forEachExport((Element element) { 817 importedLibrary.forEachExport((Element element) {
841 reporter.withCurrentElement(importingLibrary, () { 818 reporter.withCurrentElement(importingLibrary, () {
842 if (combinatorFilter.exclude(element)) return; 819 if (combinatorFilter.exclude(element)) return;
843 importingLibrary.addImport(element, import, reporter); 820 importingLibrary.addImport(element, import, reporter);
844 }); 821 });
845 }); 822 });
846 } 823 }
847 } 824 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 * exports performed in [LibraryDependencyHandler.computeExports]. 857 * exports performed in [LibraryDependencyHandler.computeExports].
881 */ 858 */
882 class LibraryDependencyNode { 859 class LibraryDependencyNode {
883 final LibraryElementX library; 860 final LibraryElementX library;
884 861
885 // TODO(ahe): Remove [hashCodeCounter] and [hashCode] when 862 // TODO(ahe): Remove [hashCodeCounter] and [hashCode] when
886 // VM implementation of Object.hashCode is not slow. 863 // VM implementation of Object.hashCode is not slow.
887 final int hashCode = ++hashCodeCounter; 864 final int hashCode = ++hashCodeCounter;
888 static int hashCodeCounter = 0; 865 static int hashCodeCounter = 0;
889 866
890
891 /** 867 /**
892 * A linked list of the import tags that import [library] mapped to the 868 * A linked list of the import tags that import [library] mapped to the
893 * corresponding libraries. This is used to propagate exports into imports 869 * corresponding libraries. This is used to propagate exports into imports
894 * after the export scopes have been computed. 870 * after the export scopes have been computed.
895 */ 871 */
896 Link<ImportLink> imports = const Link<ImportLink>(); 872 Link<ImportLink> imports = const Link<ImportLink>();
897 873
898 /// A linked list of all libraries directly exported by [library]. 874 /// A linked list of all libraries directly exported by [library].
899 Link<LibraryElement> exports = const Link<LibraryElement>(); 875 Link<LibraryElement> exports = const Link<LibraryElement>();
900 876
(...skipping 21 matching lines...) Expand all
922 */ 898 */
923 Map<Element, Link<ExportElement>> pendingExportMap = 899 Map<Element, Link<ExportElement>> pendingExportMap =
924 <Element, Link<ExportElement>>{}; 900 <Element, Link<ExportElement>>{};
925 901
926 LibraryDependencyNode(this.library); 902 LibraryDependencyNode(this.library);
927 903
928 /** 904 /**
929 * Registers that the library of this node imports [importLibrary] through the 905 * Registers that the library of this node imports [importLibrary] through the
930 * [import] tag. 906 * [import] tag.
931 */ 907 */
932 void registerImportDependency(ImportElementX import, 908 void registerImportDependency(
933 LibraryElement importedLibrary) { 909 ImportElementX import, LibraryElement importedLibrary) {
934 imports = imports.prepend(new ImportLink(import, importedLibrary)); 910 imports = imports.prepend(new ImportLink(import, importedLibrary));
935 } 911 }
936 912
937 /** 913 /**
938 * Registers that the library of this node is exported by 914 * Registers that the library of this node is exported by
939 * [exportingLibraryNode] through the [export] tag. 915 * [exportingLibraryNode] through the [export] tag.
940 */ 916 */
941 void registerExportDependency(ExportElementX export, 917 void registerExportDependency(
942 LibraryDependencyNode exportingLibraryNode) { 918 ExportElementX export, LibraryDependencyNode exportingLibraryNode) {
943 // Register the exported library in the exporting library node. 919 // Register the exported library in the exporting library node.
944 exportingLibraryNode.exports = 920 exportingLibraryNode.exports =
945 exportingLibraryNode.exports.prepend(library); 921 exportingLibraryNode.exports.prepend(library);
946 // Register the export in the exported library node. 922 // Register the export in the exported library node.
947 dependencies = 923 dependencies =
948 dependencies.prepend(new ExportLink(export, exportingLibraryNode)); 924 dependencies.prepend(new ExportLink(export, exportingLibraryNode));
949 } 925 }
950 926
951 /** 927 /**
952 * Registers all non-private locally declared members of the library of this 928 * Registers all non-private locally declared members of the library of this
953 * node to be exported. This forms the basis for the work-list computation of 929 * node to be exported. This forms the basis for the work-list computation of
954 * the export scopes performed in [LibraryDependencyHandler.computeExports]. 930 * the export scopes performed in [LibraryDependencyHandler.computeExports].
955 */ 931 */
956 void registerInitialExports() { 932 void registerInitialExports() {
957 for (Element element in library.getNonPrivateElementsInScope()) { 933 for (Element element in library.getNonPrivateElementsInScope()) {
958 pendingExportMap[element] = const Link<ExportElement>(); 934 pendingExportMap[element] = const Link<ExportElement>();
959 } 935 }
960 } 936 }
961 937
962 /// Register the already computed export scope of [exportedLibraryElement] to 938 /// Register the already computed export scope of [exportedLibraryElement] to
963 /// export from the library of this node through the [export] declaration 939 /// export from the library of this node through the [export] declaration
964 /// with the given combination [filter]. 940 /// with the given combination [filter].
965 /// 941 ///
966 /// Additionally, check that all names in the show/hide combinators are in the 942 /// Additionally, check that all names in the show/hide combinators are in the
967 /// export scope of [exportedLibraryElement]. 943 /// export scope of [exportedLibraryElement].
968 void registerHandledExports(DiagnosticReporter reporter, 944 void registerHandledExports(
969 LibraryElement exportedLibraryElement, 945 DiagnosticReporter reporter,
970 ExportElementX export, 946 LibraryElement exportedLibraryElement,
971 CombinatorFilter filter) { 947 ExportElementX export,
948 CombinatorFilter filter) {
972 assert(invariant(library, exportedLibraryElement.exportsHandled)); 949 assert(invariant(library, exportedLibraryElement.exportsHandled));
973 exportedLibraryElement.forEachExport((Element exportedElement) { 950 exportedLibraryElement.forEachExport((Element exportedElement) {
974 if (!filter.exclude(exportedElement)) { 951 if (!filter.exclude(exportedElement)) {
975 Link<ExportElement> exports = 952 Link<ExportElement> exports = pendingExportMap.putIfAbsent(
976 pendingExportMap.putIfAbsent(exportedElement, 953 exportedElement, () => const Link<ExportElement>());
977 () => const Link<ExportElement>());
978 pendingExportMap[exportedElement] = exports.prepend(export); 954 pendingExportMap[exportedElement] = exports.prepend(export);
979 } 955 }
980 }); 956 });
981 if (!reporter.options.suppressHints) { 957 if (!reporter.options.suppressHints) {
982 reporter.withCurrentElement(library, () { 958 reporter.withCurrentElement(library, () {
983 checkLibraryDependency(reporter, export.node, exportedLibraryElement); 959 checkLibraryDependency(reporter, export.node, exportedLibraryElement);
984 }); 960 });
985 } 961 }
986 } 962 }
987 963
(...skipping 20 matching lines...) Expand all
1008 Map<Element, Link<ExportElement>> pendingExports = 984 Map<Element, Link<ExportElement>> pendingExports =
1009 new Map<Element, Link<ExportElement>>.from(pendingExportMap); 985 new Map<Element, Link<ExportElement>>.from(pendingExportMap);
1010 pendingExportMap.clear(); 986 pendingExportMap.clear();
1011 return pendingExports; 987 return pendingExports;
1012 } 988 }
1013 989
1014 /** 990 /**
1015 * Adds [element] to the export scope for this node. If the [element] name 991 * Adds [element] to the export scope for this node. If the [element] name
1016 * is a duplicate, an error element is inserted into the export scope. 992 * is a duplicate, an error element is inserted into the export scope.
1017 */ 993 */
1018 Element addElementToExportScope( 994 Element addElementToExportScope(DiagnosticReporter reporter, Element element,
1019 DiagnosticReporter reporter,
1020 Element element,
1021 Link<ExportElement> exports) { 995 Link<ExportElement> exports) {
1022 String name = element.name; 996 String name = element.name;
1023 DiagnosticMessage error; 997 DiagnosticMessage error;
1024 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; 998 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
1025 999
1026 void createDuplicateExportMessage( 1000 void createDuplicateExportMessage(
1027 Element duplicate, 1001 Element duplicate, Link<ExportElement> duplicateExports) {
1028 Link<ExportElement> duplicateExports) {
1029 assert(invariant(library, !duplicateExports.isEmpty, 1002 assert(invariant(library, !duplicateExports.isEmpty,
1030 message: "No export for $duplicate from ${duplicate.library} " 1003 message: "No export for $duplicate from ${duplicate.library} "
1031 "in $library.")); 1004 "in $library."));
1032 reporter.withCurrentElement(library, () { 1005 reporter.withCurrentElement(library, () {
1033 for (ExportElement export in duplicateExports) { 1006 for (ExportElement export in duplicateExports) {
1034 if (error == null) { 1007 if (error == null) {
1035 error = reporter.createMessage( 1008 error = reporter.createMessage(
1036 export, 1009 export, MessageKind.DUPLICATE_EXPORT, {'name': name});
1037 MessageKind.DUPLICATE_EXPORT,
1038 {'name': name});
1039 } else { 1010 } else {
1040 infos.add(reporter.createMessage( 1011 infos.add(reporter.createMessage(
1041 export, 1012 export, MessageKind.DUPLICATE_EXPORT_CONT, {'name': name}));
1042 MessageKind.DUPLICATE_EXPORT_CONT,
1043 {'name': name}));
1044 } 1013 }
1045 } 1014 }
1046 }); 1015 });
1047 } 1016 }
1048 1017
1049 void createDuplicateExportDeclMessage( 1018 void createDuplicateExportDeclMessage(
1050 Element duplicate, 1019 Element duplicate, Link<ExportElement> duplicateExports) {
1051 Link<ExportElement> duplicateExports) {
1052 assert(invariant(library, !duplicateExports.isEmpty, 1020 assert(invariant(library, !duplicateExports.isEmpty,
1053 message: "No export for $duplicate from ${duplicate.library} " 1021 message: "No export for $duplicate from ${duplicate.library} "
1054 "in $library.")); 1022 "in $library."));
1055 infos.add(reporter.createMessage( 1023 infos.add(reporter.createMessage(
1056 duplicate, 1024 duplicate,
1057 MessageKind.DUPLICATE_EXPORT_DECL, 1025 MessageKind.DUPLICATE_EXPORT_DECL,
1058 {'name': name, 'uriString': duplicateExports.head.uri})); 1026 {'name': name, 'uriString': duplicateExports.head.uri}));
1059 } 1027 }
1060 1028
1061 Element existingElement = exportScope[name]; 1029 Element existingElement = exportScope[name];
1062 if (existingElement != null && existingElement != element) { 1030 if (existingElement != null && existingElement != element) {
1063 if (existingElement.isMalformed) { 1031 if (existingElement.isMalformed) {
1064 createDuplicateExportMessage(element, exports); 1032 createDuplicateExportMessage(element, exports);
1065 createDuplicateExportDeclMessage(element, exports); 1033 createDuplicateExportDeclMessage(element, exports);
1066 element = existingElement; 1034 element = existingElement;
1067 } else if (existingElement.library == library) { 1035 } else if (existingElement.library == library) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 }); 1101 });
1134 for (ExportLink exportLink in dependencies) { 1102 for (ExportLink exportLink in dependencies) {
1135 reporter.withCurrentElement(exportLink.exportNode.library, () { 1103 reporter.withCurrentElement(exportLink.exportNode.library, () {
1136 checkLibraryDependency(reporter, exportLink.export.node, library); 1104 checkLibraryDependency(reporter, exportLink.export.node, library);
1137 }); 1105 });
1138 } 1106 }
1139 } 1107 }
1140 1108
1141 /// Check that all names in the show/hide combinators of [tag] are in the 1109 /// Check that all names in the show/hide combinators of [tag] are in the
1142 /// export scope of [library]. 1110 /// export scope of [library].
1143 void checkLibraryDependency( 1111 void checkLibraryDependency(DiagnosticReporter reporter,
1144 DiagnosticReporter reporter, 1112 LibraryDependency tag, LibraryElement library) {
1145 LibraryDependency tag,
1146 LibraryElement library) {
1147 if (tag == null || tag.combinators == null) return; 1113 if (tag == null || tag.combinators == null) return;
1148 for (Combinator combinator in tag.combinators) { 1114 for (Combinator combinator in tag.combinators) {
1149 for (Identifier identifier in combinator.identifiers) { 1115 for (Identifier identifier in combinator.identifiers) {
1150 String name = identifier.source; 1116 String name = identifier.source;
1151 Element element = library.findExported(name); 1117 Element element = library.findExported(name);
1152 if (element == null) { 1118 if (element == null) {
1153 if (combinator.isHide) { 1119 if (combinator.isHide) {
1154 if (library.isPackageLibrary && 1120 if (library.isPackageLibrary &&
1155 reporter.options.hidePackageWarnings) { 1121 reporter.options.hidePackageWarnings) {
1156 // Only report hide hint on packages if we show warnings on these: 1122 // Only report hide hint on packages if we show warnings on these:
1157 // The hide may be non-empty in some versions of the package, in 1123 // The hide may be non-empty in some versions of the package, in
1158 // which case you shouldn't remove the combinator. 1124 // which case you shouldn't remove the combinator.
1159 continue; 1125 continue;
1160 } 1126 }
1161 reporter.reportHintMessage( 1127 reporter.reportHintMessage(identifier, MessageKind.EMPTY_HIDE,
1162 identifier, 1128 {'uri': library.canonicalUri, 'name': name});
1163 MessageKind.EMPTY_HIDE,
1164 {'uri': library.canonicalUri,
1165 'name': name});
1166 } else { 1129 } else {
1167 reporter.reportHintMessage( 1130 reporter.reportHintMessage(identifier, MessageKind.EMPTY_SHOW,
1168 identifier, 1131 {'uri': library.canonicalUri, 'name': name});
1169 MessageKind.EMPTY_SHOW,
1170 {'uri': library.canonicalUri,
1171 'name': name});
1172 } 1132 }
1173 } 1133 }
1174 } 1134 }
1175 } 1135 }
1176 } 1136 }
1177
1178 } 1137 }
1179 1138
1180 /** 1139 /**
1181 * Helper class used for computing the possibly cyclic import/export scopes of 1140 * Helper class used for computing the possibly cyclic import/export scopes of
1182 * a set of libraries. 1141 * a set of libraries.
1183 * 1142 *
1184 * This class is used by [ScannerTask.scanLibrary] to collect all newly loaded 1143 * This class is used by [ScannerTask.scanLibrary] to collect all newly loaded
1185 * libraries and to compute their import/export scopes through a fixed-point 1144 * libraries and to compute their import/export scopes through a fixed-point
1186 * algorithm. 1145 * algorithm.
1187 */ 1146 */
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 // elements. So we must propagate local elements first. We 1180 // elements. So we must propagate local elements first. We
1222 // ensure this by pulling the pending exports before 1181 // ensure this by pulling the pending exports before
1223 // propagating. This enforces that we handle exports 1182 // propagating. This enforces that we handle exports
1224 // breadth-first, with locally defined elements being level 0. 1183 // breadth-first, with locally defined elements being level 0.
1225 nodeMap.forEach((_, LibraryDependencyNode node) { 1184 nodeMap.forEach((_, LibraryDependencyNode node) {
1226 Map<Element, Link<ExportElement>> pendingExports = 1185 Map<Element, Link<ExportElement>> pendingExports =
1227 node.pullPendingExports(); 1186 node.pullPendingExports();
1228 tasks[node] = pendingExports; 1187 tasks[node] = pendingExports;
1229 }); 1188 });
1230 tasks.forEach((LibraryDependencyNode node, 1189 tasks.forEach((LibraryDependencyNode node,
1231 Map<Element, Link<ExportElement>> pendingExports) { 1190 Map<Element, Link<ExportElement>> pendingExports) {
1232 pendingExports.forEach((Element element, Link<ExportElement> exports) { 1191 pendingExports.forEach((Element element, Link<ExportElement> exports) {
1233 element = node.addElementToExportScope(reporter, element, exports); 1192 element = node.addElementToExportScope(reporter, element, exports);
1234 if (node.propagateElement(element)) { 1193 if (node.propagateElement(element)) {
1235 changed = true; 1194 changed = true;
1236 } 1195 }
1237 }); 1196 });
1238 }); 1197 });
1239 } 1198 }
1240 1199
1241 // Setup export scopes. These have to be set before computing the import 1200 // Setup export scopes. These have to be set before computing the import
(...skipping 10 matching lines...) Expand all
1252 1211
1253 if (!reporter.options.suppressHints) { 1212 if (!reporter.options.suppressHints) {
1254 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) { 1213 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
1255 node.checkCombinators(reporter); 1214 node.checkCombinators(reporter);
1256 }); 1215 });
1257 } 1216 }
1258 } 1217 }
1259 1218
1260 /// Registers that [library] depends on [loadedLibrary] through 1219 /// Registers that [library] depends on [loadedLibrary] through
1261 /// [libraryDependency]. 1220 /// [libraryDependency].
1262 void registerDependency(LibraryElementX library, 1221 void registerDependency(
1263 LibraryDependencyElementX libraryDependency, 1222 LibraryElementX library,
1264 LibraryElement loadedLibrary) { 1223 LibraryDependencyElementX libraryDependency,
1224 LibraryElement loadedLibrary) {
1265 if (libraryDependency.isExport) { 1225 if (libraryDependency.isExport) {
1266 // [loadedLibrary] is exported by [library]. 1226 // [loadedLibrary] is exported by [library].
1267 LibraryDependencyNode exportingNode = nodeMap[library]; 1227 LibraryDependencyNode exportingNode = nodeMap[library];
1268 if (loadedLibrary.exportsHandled) { 1228 if (loadedLibrary.exportsHandled) {
1269 // Export scope already computed on [loadedLibrary]. 1229 // Export scope already computed on [loadedLibrary].
1270 CombinatorFilter combinatorFilter = 1230 CombinatorFilter combinatorFilter =
1271 new CombinatorFilter.fromTag(libraryDependency.node); 1231 new CombinatorFilter.fromTag(libraryDependency.node);
1272 exportingNode.registerHandledExports( 1232 exportingNode.registerHandledExports(
1273 reporter, loadedLibrary, libraryDependency, combinatorFilter); 1233 reporter, loadedLibrary, libraryDependency, combinatorFilter);
1274 return; 1234 return;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 1289
1330 /// Applies all imports chains of [uri] in this bulk to [callback]. 1290 /// Applies all imports chains of [uri] in this bulk to [callback].
1331 /// 1291 ///
1332 /// The argument [importChainReversed] to [callback] contains the chain of 1292 /// The argument [importChainReversed] to [callback] contains the chain of
1333 /// imports uris that lead to importing [uri] starting in [uri] and ending in 1293 /// imports uris that lead to importing [uri] starting in [uri] and ending in
1334 /// [rootUri]. 1294 /// [rootUri].
1335 /// 1295 ///
1336 /// [callback] is called once for each chain of imports leading to [uri] until 1296 /// [callback] is called once for each chain of imports leading to [uri] until
1337 /// [callback] returns `false`. 1297 /// [callback] returns `false`.
1338 void forEachImportChain(Uri uri, 1298 void forEachImportChain(Uri uri,
1339 {bool callback(Link<Uri> importChainReversed)}); 1299 {bool callback(Link<Uri> importChainReversed)});
1340 } 1300 }
1341 1301
1342 class _LoadedLibraries implements LoadedLibraries { 1302 class _LoadedLibraries implements LoadedLibraries {
1343 final _LibraryLoaderTask task; 1303 final _LibraryLoaderTask task;
1344 final LibraryElement rootLibrary; 1304 final LibraryElement rootLibrary;
1345 final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{}; 1305 final Map<Uri, LibraryElement> loadedLibraries = <Uri, LibraryElement>{};
1346 final Map<LibraryElement, LibraryDependencyNode> nodeMap; 1306 final Map<LibraryElement, LibraryDependencyNode> nodeMap;
1347 1307
1348 _LoadedLibraries( 1308 _LoadedLibraries(this.rootLibrary, Iterable<LibraryElement> libraries,
1349 this.rootLibrary, 1309 this.nodeMap, this.task) {
1350 Iterable<LibraryElement> libraries,
1351 this.nodeMap,
1352 this.task) {
1353 libraries.forEach((LibraryElement loadedLibrary) { 1310 libraries.forEach((LibraryElement loadedLibrary) {
1354 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary; 1311 loadedLibraries[loadedLibrary.canonicalUri] = loadedLibrary;
1355 }); 1312 });
1356 } 1313 }
1357 1314
1358 Uri get rootUri => rootLibrary.canonicalUri; 1315 Uri get rootUri => rootLibrary.canonicalUri;
1359 1316
1360 bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri); 1317 bool containsLibrary(Uri uri) => loadedLibraries.containsKey(uri);
1361 1318
1362 LibraryElement getLibrary(Uri uri) => loadedLibraries[uri]; 1319 LibraryElement getLibrary(Uri uri) => loadedLibraries[uri];
1363 1320
1364 void forEachLibrary(f(LibraryElement library)) => nodeMap.keys.forEach(f); 1321 void forEachLibrary(f(LibraryElement library)) => nodeMap.keys.forEach(f);
1365 1322
1366 void forEachImportChain(Uri targetUri, 1323 void forEachImportChain(Uri targetUri,
1367 {bool callback(Link<Uri> importChainReversed)}) { 1324 {bool callback(Link<Uri> importChainReversed)}) {
1368 bool aborted = false; 1325 bool aborted = false;
1369 1326
1370 /// Map from libraries to the set of (unreversed) paths to [uri]. 1327 /// Map from libraries to the set of (unreversed) paths to [uri].
1371 Map<LibraryElement, Iterable<Link<Uri>>> suffixChainMap = 1328 Map<LibraryElement, Iterable<Link<Uri>>> suffixChainMap =
1372 <LibraryElement, Iterable<Link<Uri>>>{}; 1329 <LibraryElement, Iterable<Link<Uri>>>{};
1373 1330
1374 /// Computes the set of (unreversed) paths to [targetUri]. 1331 /// Computes the set of (unreversed) paths to [targetUri].
1375 /// 1332 ///
1376 /// Finds all paths (suffixes) from the current library to [uri] and stores 1333 /// Finds all paths (suffixes) from the current library to [uri] and stores
1377 /// it in [suffixChainMap]. 1334 /// it in [suffixChainMap].
1378 /// 1335 ///
1379 /// For every found suffix it prepends the given [prefix] and the canonical 1336 /// For every found suffix it prepends the given [prefix] and the canonical
1380 /// uri of [library] and invokes the [callback] with the concatenated chain. 1337 /// uri of [library] and invokes the [callback] with the concatenated chain.
1381 void computeSuffixes(LibraryElement library, 1338 void computeSuffixes(LibraryElement library, Link<Uri> prefix) {
1382 Link<Uri> prefix) {
1383 if (aborted) return; 1339 if (aborted) return;
1384 1340
1385 Uri canonicalUri = library.canonicalUri; 1341 Uri canonicalUri = library.canonicalUri;
1386 prefix = prefix.prepend(canonicalUri); 1342 prefix = prefix.prepend(canonicalUri);
1387 if (suffixChainMap.containsKey(library)) return; 1343 if (suffixChainMap.containsKey(library)) return;
1388 suffixChainMap[library] = const <Link<Uri>>[]; 1344 suffixChainMap[library] = const <Link<Uri>>[];
1389 List<Link<Uri>> suffixes = []; 1345 List<Link<Uri>> suffixes = [];
1390 if (targetUri != canonicalUri) { 1346 if (targetUri != canonicalUri) {
1391 LibraryDependencyNode node = nodeMap[library]; 1347 LibraryDependencyNode node = nodeMap[library];
1392 1348
(...skipping 28 matching lines...) Expand all
1421 } 1377 }
1422 1378
1423 for (ImportLink import in node.imports.reverse()) { 1379 for (ImportLink import in node.imports.reverse()) {
1424 processLibrary(import.importedLibrary); 1380 processLibrary(import.importedLibrary);
1425 if (aborted) return; 1381 if (aborted) return;
1426 } 1382 }
1427 for (LibraryElement exportedLibrary in node.exports.reverse()) { 1383 for (LibraryElement exportedLibrary in node.exports.reverse()) {
1428 processLibrary(exportedLibrary); 1384 processLibrary(exportedLibrary);
1429 if (aborted) return; 1385 if (aborted) return;
1430 } 1386 }
1431 } else { // Here `targetUri == canonicalUri`. 1387 } else {
1388 // Here `targetUri == canonicalUri`.
1432 if (!callback(prefix)) { 1389 if (!callback(prefix)) {
1433 aborted = true; 1390 aborted = true;
1434 return; 1391 return;
1435 } 1392 }
1436 suffixes.add(const Link<Uri>().prepend(canonicalUri)); 1393 suffixes.add(const Link<Uri>().prepend(canonicalUri));
1437 } 1394 }
1438 suffixChainMap[library] = suffixes; 1395 suffixChainMap[library] = suffixes;
1439 return; 1396 return;
1440 } 1397 }
1441 1398
1442 computeSuffixes(rootLibrary, const Link<Uri>()); 1399 computeSuffixes(rootLibrary, const Link<Uri>());
1443 } 1400 }
1444 1401
1445 String toString() => 'root=$rootLibrary,libraries=${loadedLibraries.keys}'; 1402 String toString() => 'root=$rootLibrary,libraries=${loadedLibraries.keys}';
1446 } 1403 }
1447 1404
1448 /// API used by the library loader to translate internal SDK URIs into file 1405 /// API used by the library loader to translate internal SDK URIs into file
1449 /// system readable URIs. 1406 /// system readable URIs.
1450 abstract class ResolvedUriTranslator { 1407 abstract class ResolvedUriTranslator {
1451 // TODO(sigmund): move here the comments from library loader. 1408 // TODO(sigmund): move here the comments from library loader.
1452 /// Translate the resolved [uri] in the context of [importingLibrary]. 1409 /// Translate the resolved [uri] in the context of [importingLibrary].
1453 /// 1410 ///
1454 /// Use [spannable] for error reporting. 1411 /// Use [spannable] for error reporting.
1455 Uri translate( 1412 Uri translate(LibraryElement importingLibrary, Uri uri,
1456 LibraryElement importingLibrary, Uri uri, [Spannable spannable]); 1413 [Spannable spannable]);
1457 } 1414 }
1458 1415
1459
1460 // TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems 1416 // TODO(sigmund): remove ScriptLoader & ElementScanner. Such abstraction seems
1461 // rather low-level. It might be more practical to split the library-loading 1417 // 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 1418 // 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 1419 // 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 1420 // loading. We would then have a list of subloaders that use different
1465 // implementations: in-memory cache, deserialization, scanning from files. 1421 // implementations: in-memory cache, deserialization, scanning from files.
1466 // 1422 //
1467 // For example, the API might look like this: 1423 // For example, the API might look like this:
1468 // 1424 //
1469 // /// APIs to create [LibraryElement] and [CompilationUnitElements] given it's 1425 // /// APIs to create [LibraryElement] and [CompilationUnitElements] given it's
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 Future<Script> readScript(Uri uri, [Spannable spannable]); 1458 Future<Script> readScript(Uri uri, [Spannable spannable]);
1503 } 1459 }
1504 1460
1505 /// API used by the library loader to synchronously scan a library or 1461 /// API used by the library loader to synchronously scan a library or
1506 /// compilation unit and ensure that their library tags are computed. 1462 /// compilation unit and ensure that their library tags are computed.
1507 abstract class ElementScanner { 1463 abstract class ElementScanner {
1508 void scanLibrary(LibraryElement library); 1464 void scanLibrary(LibraryElement library);
1509 void scanUnit(CompilationUnitElement unit); 1465 void scanUnit(CompilationUnitElement unit);
1510 } 1466 }
1511 1467
1512
1513 /// TODO(sigmund): remove this abstraction. Ideally the loader can produce the 1468 /// TODO(sigmund): remove this abstraction. Ideally the loader can produce the
1514 /// LoadedLibraries results once, and the compiler and choose what to do with 1469 /// LoadedLibraries results once, and the compiler and choose what to do with
1515 /// it instead. 1470 /// it instead.
1516 abstract class LibraryLoaderListener { 1471 abstract class LibraryLoaderListener {
1517 /// Called after a request to load a library. The [results] will include all 1472 /// Called after a request to load a library. The [results] will include all
1518 /// transitive libraries loaded as a result of the initial request. 1473 /// transitive libraries loaded as a result of the initial request.
1519 Future onLibrariesLoaded(LoadedLibraries results); 1474 Future onLibrariesLoaded(LoadedLibraries results);
1520 1475
1521 /// Called whenever a library element is created. 1476 /// Called whenever a library element is created.
1522 void onLibraryCreated(LibraryElement library); 1477 void onLibraryCreated(LibraryElement library);
1523 1478
1524 /// Called whenever a library is scanned from a script file. 1479 /// Called whenever a library is scanned from a script file.
1525 Future onLibraryScanned(LibraryElement library, LibraryLoader loader); 1480 Future onLibraryScanned(LibraryElement library, LibraryLoader loader);
1526 } 1481 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/type_test_registry.dart ('k') | pkg/compiler/lib/src/mirror_renamer/mirror_renamer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698