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

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

Issue 1335983004: Add ImportElement and ExportElement (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 5 years, 3 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/names.dart' show 9 import 'common/names.dart' show
10 Uris; 10 Uris;
11 import 'common/tasks.dart' show 11 import 'common/tasks.dart' show
12 CompilerTask; 12 CompilerTask;
13 import 'compiler.dart' show 13 import 'compiler.dart' show
14 Compiler; 14 Compiler;
15 import 'diagnostics/diagnostic_listener.dart'; 15 import 'diagnostics/diagnostic_listener.dart';
16 import 'diagnostics/invariant.dart' show 16 import 'diagnostics/invariant.dart' show
17 invariant; 17 invariant;
18 import 'diagnostics/messages.dart' show 18 import 'diagnostics/messages.dart' show
19 MessageKind; 19 MessageKind;
20 import 'diagnostics/spannable.dart' show
21 Spannable;
20 import 'elements/elements.dart' show 22 import 'elements/elements.dart' show
21 CompilationUnitElement, 23 CompilationUnitElement,
22 Element, 24 Element,
25 ImportElement,
26 ExportElement,
23 LibraryElement, 27 LibraryElement,
24 PrefixElement; 28 PrefixElement;
25 import 'elements/modelx.dart' show 29 import 'elements/modelx.dart' show
26 CompilationUnitElementX, 30 CompilationUnitElementX,
27 DeferredLoaderGetterElementX, 31 DeferredLoaderGetterElementX,
28 ErroneousElementX, 32 ErroneousElementX,
33 ExportElementX,
34 ImportElementX,
29 LibraryElementX, 35 LibraryElementX,
30 PrefixElementX; 36 LibraryDependencyElementX,
37 PrefixElementX,
38 SyntheticImportElement;
39
31 import 'native/native.dart' as native; 40 import 'native/native.dart' as native;
32 import 'script.dart'; 41 import 'script.dart';
33 import 'tree/tree.dart'; 42 import 'tree/tree.dart';
34 import 'util/util.dart' show 43 import 'util/util.dart' show
35 Link, 44 Link,
36 LinkBuilder; 45 LinkBuilder;
37 46
38 /** 47 /**
39 * [CompilerTask] for loading libraries and setting up the import/export scopes. 48 * [CompilerTask] for loading libraries and setting up the import/export scopes.
40 * 49 *
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 }); 339 });
331 } 340 }
332 341
333 /// Insert [library] in the internal maps. Used for compiler reuse. 342 /// Insert [library] in the internal maps. Used for compiler reuse.
334 void mapLibrary(LibraryElement library) { 343 void mapLibrary(LibraryElement library) {
335 libraryCanonicalUriMap[library.canonicalUri] = library; 344 libraryCanonicalUriMap[library.canonicalUri] = library;
336 345
337 Uri resourceUri = library.entryCompilationUnit.script.resourceUri; 346 Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
338 libraryResourceUriMap[resourceUri] = library; 347 libraryResourceUriMap[resourceUri] = library;
339 348
340 String name = library.getLibraryOrScriptName(); 349 String name = library.libraryOrScriptName;
341 libraryNames[name] = library; 350 libraryNames[name] = library;
342 } 351 }
343 352
344 Future<LibraryElement> loadLibrary(Uri resolvedUri) { 353 Future<LibraryElement> loadLibrary(Uri resolvedUri) {
345 return measure(() { 354 return measure(() {
346 assert(currentHandler == null); 355 assert(currentHandler == null);
347 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the 356 // TODO(johnniwinther): Ensure that currentHandler correctly encloses the
348 // loading of a library cluster. 357 // loading of a library cluster.
349 currentHandler = new LibraryDependencyHandler(this); 358 currentHandler = new LibraryDependencyHandler(this);
350 return createLibrary(currentHandler, null, resolvedUri) 359 return createLibrary(currentHandler, null, resolvedUri)
(...skipping 16 matching lines...) Expand all
367 * Processes the library tags in [library]. 376 * Processes the library tags in [library].
368 * 377 *
369 * The imported/exported libraries are loaded and processed recursively but 378 * The imported/exported libraries are loaded and processed recursively but
370 * the import/export scopes are not set up. 379 * the import/export scopes are not set up.
371 */ 380 */
372 Future processLibraryTags(LibraryDependencyHandler handler, 381 Future processLibraryTags(LibraryDependencyHandler handler,
373 LibraryElementX library) { 382 LibraryElementX library) {
374 TagState tagState = new TagState(); 383 TagState tagState = new TagState();
375 384
376 bool importsDartCore = false; 385 bool importsDartCore = false;
377 var libraryDependencies = new LinkBuilder<LibraryDependency>(); 386 LinkBuilder<LibraryDependencyElementX> libraryDependencies =
387 new LinkBuilder<LibraryDependencyElementX>();
378 Uri base = library.entryCompilationUnit.script.readableUri; 388 Uri base = library.entryCompilationUnit.script.readableUri;
379 389
380 return Future.forEach(library.tags, (LibraryTag tag) { 390 return Future.forEach(library.tags, (LibraryTag tag) {
381 return compiler.withCurrentElement(library, () { 391 return compiler.withCurrentElement(library, () {
392
393 Uri computeUri(LibraryDependency node) {
394 String tagUriString = node.uri.dartString.slowToString();
395 try {
396 return Uri.parse(tagUriString);
397 } on FormatException {
398 compiler.reportError(
399 node.uri,
400 MessageKind.INVALID_URI, {'uri': tagUriString});
401 return null;
402 }
403 }
404
382 if (tag.isImport) { 405 if (tag.isImport) {
383 Import import = tag; 406 Uri uri = computeUri(tag);
384 tagState.checkTag(TagState.IMPORT_OR_EXPORT, import, compiler); 407 if (uri == null) {
385 if (import.uri.dartString.slowToString() == 'dart:core') { 408 // Skip this erroneous import.
409 return new Future.value();
410 }
411 // TODO(johnniwinther): Create imports during parsing.
412 ImportElementX import =
413 new ImportElementX(library.entryCompilationUnit, tag, uri);
414 tagState.checkTag(TagState.IMPORT_OR_EXPORT, import.node, compiler);
415 if (import.uri == Uris.dart_core) {
386 importsDartCore = true; 416 importsDartCore = true;
387 } 417 }
418 library.addImportDeclaration(import);
388 libraryDependencies.addLast(import); 419 libraryDependencies.addLast(import);
389 } else if (tag.isExport) { 420 } else if (tag.isExport) {
390 tagState.checkTag(TagState.IMPORT_OR_EXPORT, tag, compiler); 421 Uri uri = computeUri(tag);
391 libraryDependencies.addLast(tag); 422 if (uri == null) {
423 // Skip this erroneous export.
424 return new Future.value();
425 }
426 // TODO(johnniwinther): Create exports during parsing.
427 ExportElementX export =
428 new ExportElementX(library.entryCompilationUnit, tag, uri);
429 tagState.checkTag(TagState.IMPORT_OR_EXPORT, export.node, compiler);
430 library.addExportDeclaration(export);
431 libraryDependencies.addLast(export);
392 } else if (tag.isLibraryName) { 432 } else if (tag.isLibraryName) {
393 tagState.checkTag(TagState.LIBRARY, tag, compiler); 433 tagState.checkTag(TagState.LIBRARY, tag, compiler);
394 if (library.libraryTag == null) { 434 if (library.libraryTag == null) {
395 // Use the first if there are multiple (which is reported as an 435 // Use the first if there are multiple (which is reported as an
396 // error in [TagState.checkTag]). 436 // error in [TagState.checkTag]).
397 library.libraryTag = tag; 437 library.libraryTag = tag;
398 } 438 }
399 } else if (tag.isPart) { 439 } else if (tag.isPart) {
400 Part part = tag; 440 Part part = tag;
401 StringNode uri = part.uri; 441 StringNode uri = part.uri;
402 Uri resolvedUri = base.resolve(uri.dartString.slowToString()); 442 Uri resolvedUri = base.resolve(uri.dartString.slowToString());
403 tagState.checkTag(TagState.PART, part, compiler); 443 tagState.checkTag(TagState.PART, part, compiler);
404 return scanPart(part, resolvedUri, library); 444 return scanPart(part, resolvedUri, library);
405 } else { 445 } else {
406 compiler.internalError(tag, "Unhandled library tag."); 446 compiler.internalError(tag, "Unhandled library tag.");
407 } 447 }
408 }); 448 });
409 }).then((_) { 449 }).then((_) {
410 return compiler.onLibraryScanned(library, handler); 450 return compiler.onLibraryScanned(library, handler);
411 }).then((_) { 451 }).then((_) {
412 return compiler.withCurrentElement(library, () { 452 return compiler.withCurrentElement(library, () {
413 checkDuplicatedLibraryName(library); 453 checkDuplicatedLibraryName(library);
414 454
415 // Import dart:core if not already imported. 455 // Import dart:core if not already imported.
416 if (!importsDartCore && library.canonicalUri != Uris.dart_core) { 456 if (!importsDartCore && library.canonicalUri != Uris.dart_core) {
417 return createLibrary(handler, null, Uris.dart_core) 457 return createLibrary(handler, null, Uris.dart_core)
418 .then((LibraryElement coreLibrary) { 458 .then((LibraryElement coreLibrary) {
419 handler.registerDependency(library, null, coreLibrary); 459 handler.registerDependency(library,
460 new SyntheticImportElement(
461 library.entryCompilationUnit, Uris.dart_core),
462 coreLibrary);
420 }); 463 });
421 } 464 }
422 }); 465 });
423 }).then((_) { 466 }).then((_) {
424 return Future.forEach(libraryDependencies.toList(), (tag) { 467 return Future.forEach(libraryDependencies.toList(),
468 (LibraryDependencyElementX libraryDependency) {
425 return compiler.withCurrentElement(library, () { 469 return compiler.withCurrentElement(library, () {
426 return registerLibraryFromTag(handler, library, tag); 470 return registerLibraryFromImportExport(
471 handler, library, libraryDependency);
427 }); 472 });
428 }); 473 });
429 }); 474 });
430 } 475 }
431 476
432 void checkDuplicatedLibraryName(LibraryElement library) { 477 void checkDuplicatedLibraryName(LibraryElement library) {
433 if (library.isInternalLibrary) return; 478 if (library.isInternalLibrary) return;
434 Uri resourceUri = library.entryCompilationUnit.script.resourceUri; 479 Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
435 LibraryName tag = library.libraryTag;
436 LibraryElement existing = 480 LibraryElement existing =
437 libraryResourceUriMap.putIfAbsent(resourceUri, () => library); 481 libraryResourceUriMap.putIfAbsent(resourceUri, () => library);
438 if (!identical(existing, library)) { 482 if (!identical(existing, library)) {
439 if (tag != null) { 483 if (library.hasLibraryName) {
440 compiler.withCurrentElement(library, () { 484 compiler.withCurrentElement(library, () {
441 compiler.reportWarning(tag.name, 485 compiler.reportWarning(library,
442 MessageKind.DUPLICATED_LIBRARY_RESOURCE, 486 MessageKind.DUPLICATED_LIBRARY_RESOURCE,
443 {'libraryName': tag.name, 487 {'libraryName': library.libraryName,
444 'resourceUri': resourceUri, 488 'resourceUri': resourceUri,
445 'canonicalUri1': library.canonicalUri, 489 'canonicalUri1': library.canonicalUri,
446 'canonicalUri2': existing.canonicalUri}); 490 'canonicalUri2': existing.canonicalUri});
447 }); 491 });
448 } else { 492 } else {
449 compiler.reportHint(library, 493 compiler.reportHint(library,
450 MessageKind.DUPLICATED_RESOURCE, 494 MessageKind.DUPLICATED_RESOURCE,
451 {'resourceUri': resourceUri, 495 {'resourceUri': resourceUri,
452 'canonicalUri1': library.canonicalUri, 496 'canonicalUri1': library.canonicalUri,
453 'canonicalUri2': existing.canonicalUri}); 497 'canonicalUri2': existing.canonicalUri});
454 } 498 }
455 } else if (tag != null) { 499 } else if (library.hasLibraryName) {
456 String name = library.getLibraryOrScriptName(); 500 String name = library.libraryOrScriptName;
457 existing = libraryNames.putIfAbsent(name, () => library); 501 existing = libraryNames.putIfAbsent(name, () => library);
458 if (!identical(existing, library)) { 502 if (!identical(existing, library)) {
459 compiler.withCurrentElement(library, () { 503 compiler.withCurrentElement(library, () {
460 compiler.reportWarning(tag.name, 504 compiler.reportWarning(library,
461 MessageKind.DUPLICATED_LIBRARY_NAME, 505 MessageKind.DUPLICATED_LIBRARY_NAME,
462 {'libraryName': name}); 506 {'libraryName': name});
463 }); 507 });
464 compiler.withCurrentElement(existing, () { 508 compiler.withCurrentElement(existing, () {
465 compiler.reportWarning(existing.libraryTag.name, 509 compiler.reportWarning(existing,
466 MessageKind.DUPLICATED_LIBRARY_NAME, 510 MessageKind.DUPLICATED_LIBRARY_NAME,
467 {'libraryName': name}); 511 {'libraryName': name});
468 }); 512 });
469 } 513 }
470 } 514 }
471 } 515 }
472 516
473 /** 517 /**
474 * Handle a part tag in the scope of [library]. The [resolvedUri] given is 518 * Handle a part tag in the scope of [library]. The [resolvedUri] given is
475 * used as is, any URI resolution should be done beforehand. 519 * used as is, any URI resolution should be done beforehand.
(...skipping 18 matching lines...) Expand all
494 }); 538 });
495 }); 539 });
496 } 540 }
497 541
498 /** 542 /**
499 * Handle an import/export tag by loading the referenced library and 543 * Handle an import/export tag by loading the referenced library and
500 * registering its dependency in [handler] for the computation of the import/ 544 * registering its dependency in [handler] for the computation of the import/
501 * export scope. If the tag does not contain a valid URI, then its dependency 545 * export scope. If the tag does not contain a valid URI, then its dependency
502 * is not registered in [handler]. 546 * is not registered in [handler].
503 */ 547 */
504 Future<Null> registerLibraryFromTag(LibraryDependencyHandler handler, 548 Future<Null> registerLibraryFromImportExport(
505 LibraryElement library, 549 LibraryDependencyHandler handler,
506 LibraryDependency tag) { 550 LibraryElement library,
551 LibraryDependencyElementX libraryDependency) {
507 Uri base = library.canonicalUri; 552 Uri base = library.canonicalUri;
508 String tagUriString = tag.uri.dartString.slowToString(); 553 Uri resolvedUri = base.resolveUri(libraryDependency.uri);
509 Uri resolvedUri; 554 return createLibrary(handler, library, resolvedUri, libraryDependency)
510 try {
511 resolvedUri = base.resolve(tagUriString);
512 } on FormatException {
513 compiler.reportError(
514 tag.uri, MessageKind.INVALID_URI, {'uri': tagUriString});
515 // 'reportError' does not stop necessarily stop compilation
516 return new Future.value();
517 }
518 return createLibrary(handler, library, resolvedUri, tag.uri)
519 .then((LibraryElement loadedLibrary) { 555 .then((LibraryElement loadedLibrary) {
520 if (loadedLibrary == null) return; 556 if (loadedLibrary == null) return;
521 compiler.withCurrentElement(library, () { 557 compiler.withCurrentElement(library, () {
522 handler.registerDependency(library, tag, loadedLibrary); 558 libraryDependency.libraryDependency = loadedLibrary;
559 handler.registerDependency(
560 library, libraryDependency, loadedLibrary);
523 }); 561 });
524 }); 562 });
525 } 563 }
526 564
527 /// Loads the deserialized [library] with the [handler]. 565 /// Loads the deserialized [library] with the [handler].
528 /// 566 ///
529 /// All libraries imported or exported transitively from [library] will be 567 /// All libraries imported or exported transitively from [library] will be
530 /// loaded as well. 568 /// loaded as well.
531 Future<LibraryElement> loadDeserializedLibrary( 569 Future<LibraryElement> loadDeserializedLibrary(
532 LibraryDependencyHandler handler, 570 LibraryDependencyHandler handler,
533 LibraryElement library) { 571 LibraryElement library) {
534 compiler.onLibraryCreated(library); 572 compiler.onLibraryCreated(library);
535 libraryCanonicalUriMap[library.canonicalUri] = library; 573 libraryCanonicalUriMap[library.canonicalUri] = library;
536 return compiler.onLibraryScanned(library, handler).then((_) { 574 return compiler.onLibraryScanned(library, handler).then((_) {
537 return Future.forEach(library.tags, (LibraryTag tag) { 575 return Future.forEach(library.imports, (ImportElement import) {
538 LibraryElement dependency = library.getLibraryFromTag(tag); 576 return createLibrary(handler, library, import.uri);
539 return createLibrary(handler, library, dependency.canonicalUri); 577 }).then((_) {
540 }).then((_) => library); 578 return Future.forEach(library.exports, (ExportElement export) {
579 return createLibrary(handler, library, export.uri);
580 }).then((_) => library);
581 });
541 }); 582 });
542 } 583 }
543 584
544 /** 585 /**
545 * Create (or reuse) a library element for the library specified by the 586 * Create (or reuse) a library element for the library specified by the
546 * [resolvedUri]. 587 * [resolvedUri].
547 * 588 *
548 * If a new library is created, the [handler] is notified. 589 * If a new library is created, the [handler] is notified.
549 */ 590 */
550 Future<LibraryElement> createLibrary(LibraryDependencyHandler handler, 591 Future<LibraryElement> createLibrary(LibraryDependencyHandler handler,
551 LibraryElement importingLibrary, 592 LibraryElement importingLibrary,
552 Uri resolvedUri, 593 Uri resolvedUri,
553 [Node node]) { 594 [Spannable node]) {
554 Uri readableUri = 595 Uri readableUri =
555 compiler.translateResolvedUri(importingLibrary, resolvedUri, node); 596 compiler.translateResolvedUri(importingLibrary, resolvedUri, node);
556 LibraryElement library = libraryCanonicalUriMap[resolvedUri]; 597 LibraryElement library = libraryCanonicalUriMap[resolvedUri];
557 if (library != null) { 598 if (library != null) {
558 return new Future.value(library); 599 return new Future.value(library);
559 } 600 }
560 library = compiler.serialization.readLibrary(resolvedUri); 601 library = compiler.serialization.readLibrary(resolvedUri);
561 if (library != null) { 602 if (library != null) {
562 return loadDeserializedLibrary(handler, library); 603 return loadDeserializedLibrary(handler, library);
563 } 604 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 if (value == LIBRARY) { 705 if (value == LIBRARY) {
665 hasLibraryDeclaration = true; 706 hasLibraryDeclaration = true;
666 } 707 }
667 } 708 }
668 } 709 }
669 710
670 /** 711 /**
671 * An [import] tag and the [importedLibrary] imported through [import]. 712 * An [import] tag and the [importedLibrary] imported through [import].
672 */ 713 */
673 class ImportLink { 714 class ImportLink {
674 final Import import; 715 final ImportElementX import;
675 final LibraryElement importedLibrary; 716 final LibraryElement importedLibrary;
676 717
677 ImportLink(this.import, this.importedLibrary); 718 ImportLink(this.import, this.importedLibrary);
678 719
679 /** 720 /**
680 * Imports the library into the [importingLibrary]. 721 * Imports the library into the [importingLibrary].
681 */ 722 */
682 void importLibrary(Compiler compiler, LibraryElementX importingLibrary) { 723 void importLibrary(Compiler compiler, LibraryElementX importingLibrary) {
683 assert(invariant(importingLibrary, 724 assert(invariant(importingLibrary,
684 importedLibrary.exportsHandled, 725 importedLibrary.exportsHandled,
685 message: 'Exports not handled on $importedLibrary')); 726 message: 'Exports not handled on $importedLibrary'));
686 var combinatorFilter = new CombinatorFilter.fromTag(import); 727 Import tag = import.node;
687 if (import != null && import.prefix != null) { 728 CombinatorFilter combinatorFilter =
688 String prefix = import.prefix.source; 729 new CombinatorFilter.fromTag(tag);
730 if (tag != null && tag.prefix != null) {
731 String prefix = tag.prefix.source;
689 Element existingElement = importingLibrary.find(prefix); 732 Element existingElement = importingLibrary.find(prefix);
690 PrefixElement prefixElement; 733 PrefixElementX prefixElement;
691 if (existingElement == null || !existingElement.isPrefix) { 734 if (existingElement == null || !existingElement.isPrefix) {
692 prefixElement = new PrefixElementX(prefix, 735 prefixElement = new PrefixElementX(
693 importingLibrary.entryCompilationUnit, import.getBeginToken()); 736 prefix,
737 importingLibrary.entryCompilationUnit,
738 tag.getBeginToken(),
739 tag.isDeferred ? import : null);
694 } else { 740 } else {
695 prefixElement = existingElement; 741 prefixElement = existingElement;
696 } 742 }
697 importingLibrary.addToScope(prefixElement, compiler); 743 importingLibrary.addToScope(prefixElement, compiler);
698 importedLibrary.forEachExport((Element element) { 744 importedLibrary.forEachExport((Element element) {
699 if (combinatorFilter.exclude(element)) return; 745 if (combinatorFilter.exclude(element)) return;
700 prefixElement.addImport(element, import, compiler); 746 prefixElement.addImport(element, import, compiler);
701 }); 747 });
702 if (import.isDeferred) { 748 import.prefix = prefixElement;
749 if (prefixElement.isDeferred) {
703 prefixElement.addImport( 750 prefixElement.addImport(
704 new DeferredLoaderGetterElementX(prefixElement), 751 new DeferredLoaderGetterElementX(prefixElement),
705 import, compiler); 752 import, compiler);
706 // TODO(sigurdm): When we remove support for the annotation based
707 // syntax the [PrefixElement] constructor should receive this
708 // information.
709 prefixElement.markAsDeferred(import);
710 } 753 }
711 } else { 754 } else {
712 importedLibrary.forEachExport((Element element) { 755 importedLibrary.forEachExport((Element element) {
713 compiler.withCurrentElement(importingLibrary, () { 756 compiler.withCurrentElement(importingLibrary, () {
714 if (combinatorFilter.exclude(element)) return; 757 if (combinatorFilter.exclude(element)) return;
715 importingLibrary.addImport(element, import, compiler); 758 importingLibrary.addImport(element, import, compiler);
716 }); 759 });
717 }); 760 });
718 } 761 }
719 } 762 }
720 } 763 }
721 764
722 /** 765 /**
723 * The combinator filter computed from an export tag and the library dependency 766 * The combinator filter computed from an export tag and the library dependency
724 * node for the library that declared the export tag. This represents an edge in 767 * node for the library that declared the export tag. This represents an edge in
725 * the library dependency graph. 768 * the library dependency graph.
726 */ 769 */
727 class ExportLink { 770 class ExportLink {
728 final Export export; 771 final ExportElementX export;
729 final CombinatorFilter combinatorFilter; 772 final CombinatorFilter combinatorFilter;
730 final LibraryDependencyNode exportNode; 773 final LibraryDependencyNode exportNode;
731 774
732 ExportLink(Export export, LibraryDependencyNode this.exportNode) 775 ExportLink(ExportElementX export, LibraryDependencyNode this.exportNode)
733 : this.export = export, 776 : this.export = export,
734 this.combinatorFilter = new CombinatorFilter.fromTag(export); 777 this.combinatorFilter = new CombinatorFilter.fromTag(export.node);
735 778
736 /** 779 /**
737 * Exports [element] to the dependent library unless [element] is filtered by 780 * Exports [element] to the dependent library unless [element] is filtered by
738 * the export combinators. Returns [:true:] if the set pending exports of the 781 * the export combinators. Returns [:true:] if the set pending exports of the
739 * dependent library was modified. 782 * dependent library was modified.
740 */ 783 */
741 bool exportElement(Element element) { 784 bool exportElement(Element element) {
742 if (combinatorFilter.exclude(element)) return false; 785 if (combinatorFilter.exclude(element)) return false;
743 return exportNode.addElementToPendingExports(element, export); 786 return exportNode.addElementToPendingExports(element, export);
744 } 787 }
(...skipping 28 matching lines...) Expand all
773 /** 816 /**
774 * A linked list of the export tags the dependent upon this node library. 817 * A linked list of the export tags the dependent upon this node library.
775 * This is used to propagate exports during the computation of export scopes. 818 * This is used to propagate exports during the computation of export scopes.
776 */ 819 */
777 Link<ExportLink> dependencies = const Link<ExportLink>(); 820 Link<ExportLink> dependencies = const Link<ExportLink>();
778 821
779 /** 822 /**
780 * The export scope for [library] which is gradually computed by the work-list 823 * The export scope for [library] which is gradually computed by the work-list
781 * computation in [LibraryDependencyHandler.computeExports]. 824 * computation in [LibraryDependencyHandler.computeExports].
782 */ 825 */
783 Map<String, Element> exportScope = 826 Map<String, Element> exportScope = <String, Element>{};
784 new Map<String, Element>();
785 827
786 /// Map from exported elements to the export directives that exported them. 828 /// Map from exported elements to the export directives that exported them.
787 Map<Element, Link<Export>> exporters = new Map<Element, Link<Export>>(); 829 Map<Element, Link<ExportElement>> exporters =
830 <Element, Link<ExportElement>>{};
788 831
789 /** 832 /**
790 * The set of exported elements that need to be propageted to dependent 833 * The set of exported elements that need to be propageted to dependent
791 * libraries as part of the work-list computation performed in 834 * libraries as part of the work-list computation performed in
792 * [LibraryDependencyHandler.computeExports]. Each export element is mapped 835 * [LibraryDependencyHandler.computeExports]. Each export element is mapped
793 * to a list of exports directives that export it. 836 * to a list of exports directives that export it.
794 */ 837 */
795 Map<Element, Link<Export>> pendingExportMap = 838 Map<Element, Link<ExportElement>> pendingExportMap =
796 new Map<Element, Link<Export>>(); 839 <Element, Link<ExportElement>>{};
797 840
798 LibraryDependencyNode(this.library); 841 LibraryDependencyNode(this.library);
799 842
800 /** 843 /**
801 * Registers that the library of this node imports [importLibrary] through the 844 * Registers that the library of this node imports [importLibrary] through the
802 * [import] tag. 845 * [import] tag.
803 */ 846 */
804 void registerImportDependency(Import import, 847 void registerImportDependency(ImportElementX import,
805 LibraryElement importedLibrary) { 848 LibraryElement importedLibrary) {
806 imports = imports.prepend(new ImportLink(import, importedLibrary)); 849 imports = imports.prepend(new ImportLink(import, importedLibrary));
807 } 850 }
808 851
809 /** 852 /**
810 * Registers that the library of this node is exported by 853 * Registers that the library of this node is exported by
811 * [exportingLibraryNode] through the [export] tag. 854 * [exportingLibraryNode] through the [export] tag.
812 */ 855 */
813 void registerExportDependency(Export export, 856 void registerExportDependency(ExportElementX export,
814 LibraryDependencyNode exportingLibraryNode) { 857 LibraryDependencyNode exportingLibraryNode) {
815 // Register the exported library in the exporting library node. 858 // Register the exported library in the exporting library node.
816 exportingLibraryNode.exports = 859 exportingLibraryNode.exports =
817 exportingLibraryNode.exports.prepend(library); 860 exportingLibraryNode.exports.prepend(library);
818 // Register the export in the exported library node. 861 // Register the export in the exported library node.
819 dependencies = 862 dependencies =
820 dependencies.prepend(new ExportLink(export, exportingLibraryNode)); 863 dependencies.prepend(new ExportLink(export, exportingLibraryNode));
821 } 864 }
822 865
823 /** 866 /**
824 * Registers all non-private locally declared members of the library of this 867 * Registers all non-private locally declared members of the library of this
825 * node to be exported. This forms the basis for the work-list computation of 868 * node to be exported. This forms the basis for the work-list computation of
826 * the export scopes performed in [LibraryDependencyHandler.computeExports]. 869 * the export scopes performed in [LibraryDependencyHandler.computeExports].
827 */ 870 */
828 void registerInitialExports() { 871 void registerInitialExports() {
829 for (Element element in library.getNonPrivateElementsInScope()) { 872 for (Element element in library.getNonPrivateElementsInScope()) {
830 pendingExportMap[element] = const Link<Export>(); 873 pendingExportMap[element] = const Link<ExportElement>();
831 } 874 }
832 } 875 }
833 876
834 void registerHandledExports(LibraryElement exportedLibraryElement, 877 void registerHandledExports(LibraryElement exportedLibraryElement,
835 Export export, 878 ExportElementX export,
836 CombinatorFilter filter) { 879 CombinatorFilter filter) {
837 assert(invariant(library, exportedLibraryElement.exportsHandled)); 880 assert(invariant(library, exportedLibraryElement.exportsHandled));
838 for (Element exportedElement in exportedLibraryElement.exports) { 881 exportedLibraryElement.forEachExport((Element exportedElement) {
839 if (!filter.exclude(exportedElement)) { 882 if (!filter.exclude(exportedElement)) {
840 Link<Export> exports = 883 Link<ExportElement> exports =
841 pendingExportMap.putIfAbsent(exportedElement, 884 pendingExportMap.putIfAbsent(exportedElement,
842 () => const Link<Export>()); 885 () => const Link<ExportElement>());
843 pendingExportMap[exportedElement] = exports.prepend(export); 886 pendingExportMap[exportedElement] = exports.prepend(export);
844 } 887 }
845 } 888 });
846 } 889 }
847 890
848 /** 891 /**
849 * Registers the compute export scope with the node library. 892 * Registers the compute export scope with the node library.
850 */ 893 */
851 void registerExports() { 894 void registerExports() {
852 library.setExports(exportScope.values.toList()); 895 library.setExports(exportScope.values.toList());
853 } 896 }
854 897
855 /** 898 /**
856 * Registers the imports of the node library. 899 * Registers the imports of the node library.
857 */ 900 */
858 void registerImports(Compiler compiler) { 901 void registerImports(Compiler compiler) {
859 for (ImportLink link in imports) { 902 for (ImportLink link in imports) {
860 link.importLibrary(compiler, library); 903 link.importLibrary(compiler, library);
861 } 904 }
862 } 905 }
863 906
864 /** 907 /**
865 * Copies and clears pending export set for this node. 908 * Copies and clears pending export set for this node.
866 */ 909 */
867 Map<Element, Link<Export>> pullPendingExports() { 910 Map<Element, Link<ExportElement>> pullPendingExports() {
868 Map<Element, Link<Export>> pendingExports = 911 Map<Element, Link<ExportElement>> pendingExports =
869 new Map<Element, Link<Export>>.from(pendingExportMap); 912 new Map<Element, Link<ExportElement>>.from(pendingExportMap);
870 pendingExportMap.clear(); 913 pendingExportMap.clear();
871 return pendingExports; 914 return pendingExports;
872 } 915 }
873 916
874 /** 917 /**
875 * Adds [element] to the export scope for this node. If the [element] name 918 * Adds [element] to the export scope for this node. If the [element] name
876 * is a duplicate, an error element is inserted into the export scope. 919 * is a duplicate, an error element is inserted into the export scope.
877 */ 920 */
878 Element addElementToExportScope(Compiler compiler, Element element, 921 Element addElementToExportScope(Compiler compiler, Element element,
879 Link<Export> exports) { 922 Link<ExportElement> exports) {
880 String name = element.name; 923 String name = element.name;
881 924
882 void reportDuplicateExport(Element duplicate, 925 void reportDuplicateExport(Element duplicate,
883 Link<Export> duplicateExports, 926 Link<ExportElement> duplicateExports,
884 {bool reportError: true}) { 927 {bool reportError: true}) {
885 assert(invariant(library, !duplicateExports.isEmpty, 928 assert(invariant(library, !duplicateExports.isEmpty,
886 message: "No export for $duplicate from ${duplicate.library} " 929 message: "No export for $duplicate from ${duplicate.library} "
887 "in $library.")); 930 "in $library."));
888 compiler.withCurrentElement(library, () { 931 compiler.withCurrentElement(library, () {
889 for (Export export in duplicateExports) { 932 for (ExportElement export in duplicateExports) {
890 if (reportError) { 933 if (reportError) {
891 compiler.reportError(export, 934 compiler.reportError(export,
892 MessageKind.DUPLICATE_EXPORT, {'name': name}); 935 MessageKind.DUPLICATE_EXPORT, {'name': name});
893 reportError = false; 936 reportError = false;
894 } else { 937 } else {
895 compiler.reportInfo(export, 938 compiler.reportInfo(export,
896 MessageKind.DUPLICATE_EXPORT_CONT, {'name': name}); 939 MessageKind.DUPLICATE_EXPORT_CONT, {'name': name});
897 } 940 }
898 } 941 }
899 }); 942 });
900 } 943 }
901 944
902 void reportDuplicateExportDecl(Element duplicate, 945 void reportDuplicateExportDecl(Element duplicate,
903 Link<Export> duplicateExports) { 946 Link<ExportElement> duplicateExports) {
904 assert(invariant(library, !duplicateExports.isEmpty, 947 assert(invariant(library, !duplicateExports.isEmpty,
905 message: "No export for $duplicate from ${duplicate.library} " 948 message: "No export for $duplicate from ${duplicate.library} "
906 "in $library.")); 949 "in $library."));
907 compiler.reportInfo(duplicate, MessageKind.DUPLICATE_EXPORT_DECL, 950 compiler.reportInfo(duplicate, MessageKind.DUPLICATE_EXPORT_DECL,
908 {'name': name, 'uriString': duplicateExports.head.uri}); 951 {'name': name, 'uriString': duplicateExports.head.uri});
909 } 952 }
910 953
911 Element existingElement = exportScope[name]; 954 Element existingElement = exportScope[name];
912 if (existingElement != null && existingElement != element) { 955 if (existingElement != null && existingElement != element) {
913 if (existingElement.isErroneous) { 956 if (existingElement.isErroneous) {
914 reportDuplicateExport(element, exports); 957 reportDuplicateExport(element, exports);
915 reportDuplicateExportDecl(element, exports); 958 reportDuplicateExportDecl(element, exports);
916 element = existingElement; 959 element = existingElement;
917 } else if (existingElement.library == library) { 960 } else if (existingElement.library == library) {
918 // Do nothing. [existingElement] hides [element]. 961 // Do nothing. [existingElement] hides [element].
919 } else if (element.library == library) { 962 } else if (element.library == library) {
920 // [element] hides [existingElement]. 963 // [element] hides [existingElement].
921 exportScope[name] = element; 964 exportScope[name] = element;
922 exporters[element] = exports; 965 exporters[element] = exports;
923 } else { 966 } else {
924 // Declared elements hide exported elements. 967 // Declared elements hide exported elements.
925 Link<Export> existingExports = exporters[existingElement]; 968 Link<ExportElement> existingExports = exporters[existingElement];
926 reportDuplicateExport(existingElement, existingExports); 969 reportDuplicateExport(existingElement, existingExports);
927 reportDuplicateExport(element, exports, reportError: false); 970 reportDuplicateExport(element, exports, reportError: false);
928 reportDuplicateExportDecl(existingElement, existingExports); 971 reportDuplicateExportDecl(existingElement, existingExports);
929 reportDuplicateExportDecl(element, exports); 972 reportDuplicateExportDecl(element, exports);
930 element = exportScope[name] = new ErroneousElementX( 973 element = exportScope[name] = new ErroneousElementX(
931 MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library); 974 MessageKind.DUPLICATE_EXPORT, {'name': name}, name, library);
932 } 975 }
933 } else { 976 } else {
934 exportScope[name] = element; 977 exportScope[name] = element;
935 exporters[element] = exports; 978 exporters[element] = exports;
(...skipping 14 matching lines...) Expand all
950 } 993 }
951 } 994 }
952 return change; 995 return change;
953 } 996 }
954 997
955 /** 998 /**
956 * Adds [element] to the pending exports of this node and returns [:true:] if 999 * Adds [element] to the pending exports of this node and returns [:true:] if
957 * the pending export set was modified. The combinators of [export] are used 1000 * the pending export set was modified. The combinators of [export] are used
958 * to filter the element. 1001 * to filter the element.
959 */ 1002 */
960 bool addElementToPendingExports(Element element, Export export) { 1003 bool addElementToPendingExports(Element element, ExportElement export) {
961 bool changed = false; 1004 bool changed = false;
962 if (!identical(exportScope[element.name], element)) { 1005 if (!identical(exportScope[element.name], element)) {
963 Link<Export> exports = pendingExportMap.putIfAbsent(element, () { 1006 Link<ExportElement> exports = pendingExportMap.putIfAbsent(element, () {
964 changed = true; 1007 changed = true;
965 return const Link<Export>(); 1008 return const Link<ExportElement>();
966 }); 1009 });
967 pendingExportMap[element] = exports.prepend(export); 1010 pendingExportMap[element] = exports.prepend(export);
968 } 1011 }
969 return changed; 1012 return changed;
970 } 1013 }
971 } 1014 }
972 1015
973 /** 1016 /**
974 * Helper class used for computing the possibly cyclic import/export scopes of 1017 * Helper class used for computing the possibly cyclic import/export scopes of
975 * a set of libraries. 1018 * a set of libraries.
(...skipping 23 matching lines...) Expand all
999 1042
1000 /** 1043 /**
1001 * Performs a fixed-point computation on the export scopes of all registered 1044 * Performs a fixed-point computation on the export scopes of all registered
1002 * libraries and creates the import/export of the libraries based on the 1045 * libraries and creates the import/export of the libraries based on the
1003 * fixed-point. 1046 * fixed-point.
1004 */ 1047 */
1005 void computeExports() { 1048 void computeExports() {
1006 bool changed = true; 1049 bool changed = true;
1007 while (changed) { 1050 while (changed) {
1008 changed = false; 1051 changed = false;
1009 Map<LibraryDependencyNode, Map<Element, Link<Export>>> tasks = 1052 Map<LibraryDependencyNode, Map<Element, Link<ExportElement>>> tasks =
1010 new Map<LibraryDependencyNode, Map<Element, Link<Export>>>(); 1053 new Map<LibraryDependencyNode, Map<Element, Link<ExportElement>>>();
1011 1054
1012 // Locally defined elements take precedence over exported 1055 // Locally defined elements take precedence over exported
1013 // elements. So we must propagate local elements first. We 1056 // elements. So we must propagate local elements first. We
1014 // ensure this by pulling the pending exports before 1057 // ensure this by pulling the pending exports before
1015 // propagating. This enforces that we handle exports 1058 // propagating. This enforces that we handle exports
1016 // breadth-first, with locally defined elements being level 0. 1059 // breadth-first, with locally defined elements being level 0.
1017 nodeMap.forEach((_, LibraryDependencyNode node) { 1060 nodeMap.forEach((_, LibraryDependencyNode node) {
1018 Map<Element, Link<Export>> pendingExports = node.pullPendingExports(); 1061 Map<Element, Link<ExportElement>> pendingExports =
1062 node.pullPendingExports();
1019 tasks[node] = pendingExports; 1063 tasks[node] = pendingExports;
1020 }); 1064 });
1021 tasks.forEach((LibraryDependencyNode node, 1065 tasks.forEach((LibraryDependencyNode node,
1022 Map<Element, Link<Export>> pendingExports) { 1066 Map<Element, Link<ExportElement>> pendingExports) {
1023 pendingExports.forEach((Element element, Link<Export> exports) { 1067 pendingExports.forEach((Element element, Link<ExportElement> exports) {
1024 element = node.addElementToExportScope(compiler, element, exports); 1068 element = node.addElementToExportScope(compiler, element, exports);
1025 if (node.propagateElement(element)) { 1069 if (node.propagateElement(element)) {
1026 changed = true; 1070 changed = true;
1027 } 1071 }
1028 }); 1072 });
1029 }); 1073 });
1030 } 1074 }
1031 1075
1032 // Setup export scopes. These have to be set before computing the import 1076 // Setup export scopes. These have to be set before computing the import
1033 // scopes to avoid accessing uncomputed export scopes during handling of 1077 // scopes to avoid accessing uncomputed export scopes during handling of
1034 // imports. 1078 // imports.
1035 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) { 1079 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
1036 node.registerExports(); 1080 node.registerExports();
1037 }); 1081 });
1038 1082
1039 // Setup import scopes. 1083 // Setup import scopes.
1040 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) { 1084 nodeMap.forEach((LibraryElement library, LibraryDependencyNode node) {
1041 node.registerImports(compiler); 1085 node.registerImports(compiler);
1042 }); 1086 });
1043 } 1087 }
1044 1088
1045 /** 1089 /// Registers that [library] depends on [loadedLibrary] through
1046 * Registers that [library] depends on [loadedLibrary] through [tag]. 1090 /// [libraryDependency].
1047 */
1048 void registerDependency(LibraryElementX library, 1091 void registerDependency(LibraryElementX library,
1049 LibraryDependency tag, 1092 LibraryDependencyElementX libraryDependency,
1050 LibraryElement loadedLibrary) { 1093 LibraryElement loadedLibrary) {
1051 if (tag != null) { 1094 if (libraryDependency.isExport) {
1052 library.recordResolvedTag(tag, loadedLibrary);
1053 }
1054 if (tag is Export) {
1055 // [loadedLibrary] is exported by [library]. 1095 // [loadedLibrary] is exported by [library].
1056 LibraryDependencyNode exportingNode = nodeMap[library]; 1096 LibraryDependencyNode exportingNode = nodeMap[library];
1057 if (loadedLibrary.exportsHandled) { 1097 if (loadedLibrary.exportsHandled) {
1058 // Export scope already computed on [loadedLibrary]. 1098 // Export scope already computed on [loadedLibrary].
1059 var combinatorFilter = new CombinatorFilter.fromTag(tag); 1099 CombinatorFilter combinatorFilter =
1100 new CombinatorFilter.fromTag(libraryDependency.node);
1060 exportingNode.registerHandledExports( 1101 exportingNode.registerHandledExports(
1061 loadedLibrary, tag, combinatorFilter); 1102 loadedLibrary, libraryDependency, combinatorFilter);
1062 return; 1103 return;
1063 } 1104 }
1064 LibraryDependencyNode exportedNode = nodeMap[loadedLibrary]; 1105 LibraryDependencyNode exportedNode = nodeMap[loadedLibrary];
1065 assert(invariant(loadedLibrary, exportedNode != null, 1106 assert(invariant(loadedLibrary, exportedNode != null,
1066 message: "$loadedLibrary has not been registered")); 1107 message: "$loadedLibrary has not been registered"));
1067 assert(invariant(library, exportingNode != null, 1108 assert(invariant(library, exportingNode != null,
1068 message: "$library has not been registered")); 1109 message: "$library has not been registered"));
1069 exportedNode.registerExportDependency(tag, exportingNode); 1110 exportedNode.registerExportDependency(libraryDependency, exportingNode);
1070 } else if (tag == null || tag is Import) { 1111 } else if (libraryDependency == null || libraryDependency.isImport) {
1071 // [loadedLibrary] is imported by [library]. 1112 // [loadedLibrary] is imported by [library].
1072 LibraryDependencyNode importingNode = nodeMap[library]; 1113 LibraryDependencyNode importingNode = nodeMap[library];
1073 assert(invariant(library, importingNode != null, 1114 assert(invariant(library, importingNode != null,
1074 message: "$library has not been registered")); 1115 message: "$library has not been registered"));
1075 importingNode.registerImportDependency(tag, loadedLibrary); 1116 importingNode.registerImportDependency(libraryDependency, loadedLibrary);
1076 } 1117 }
1077 } 1118 }
1078 1119
1079 /** 1120 /**
1080 * Registers [library] for the processing of its import/export scope. 1121 * Registers [library] for the processing of its import/export scope.
1081 */ 1122 */
1082 void registerNewLibrary(LibraryElement library) { 1123 void registerNewLibrary(LibraryElement library) {
1083 nodeMap[library] = new LibraryDependencyNode(library); 1124 nodeMap[library] = new LibraryDependencyNode(library);
1084 compiler.onLibraryCreated(library); 1125 compiler.onLibraryCreated(library);
1085 } 1126 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 } 1257 }
1217 suffixes.add(const Link<Uri>().prepend(canonicalUri)); 1258 suffixes.add(const Link<Uri>().prepend(canonicalUri));
1218 } 1259 }
1219 suffixChainMap[library] = suffixes; 1260 suffixChainMap[library] = suffixes;
1220 return; 1261 return;
1221 } 1262 }
1222 1263
1223 computeSuffixes(rootLibrary, const Link<Uri>()); 1264 computeSuffixes(rootLibrary, const Link<Uri>());
1224 } 1265 }
1225 } 1266 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart ('k') | pkg/compiler/lib/src/mirrors/dart2js_library_mirror.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698