| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 elements.modelx; | 5 library elements.modelx; |
| 6 | 6 |
| 7 import 'dart:collection' show LinkedHashMap; | 7 import 'dart:collection' show LinkedHashMap; |
| 8 | 8 |
| 9 import 'elements.dart'; | 9 import 'elements.dart'; |
| 10 import '../../compiler.dart' as api; | 10 import '../../compiler.dart' as api; |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 } | 627 } |
| 628 | 628 |
| 629 bool get hasMembers => !localMembers.isEmpty; | 629 bool get hasMembers => !localMembers.isEmpty; |
| 630 | 630 |
| 631 int compareTo(CompilationUnitElement other) { | 631 int compareTo(CompilationUnitElement other) { |
| 632 if (this == other) return 0; | 632 if (this == other) return 0; |
| 633 return '${script.uri}'.compareTo('${other.script.uri}'); | 633 return '${script.uri}'.compareTo('${other.script.uri}'); |
| 634 } | 634 } |
| 635 } | 635 } |
| 636 | 636 |
| 637 class ImportScope { |
| 638 /** |
| 639 * Map for elements imported through import declarations. |
| 640 * |
| 641 * Addition to the map is performed by [addImport]. Lookup is done trough |
| 642 * [find]. |
| 643 */ |
| 644 final Map<SourceString, Element> importScope = |
| 645 new Map<SourceString, Element>(); |
| 646 |
| 647 /** |
| 648 * Adds [element] to the import scope of this library. |
| 649 * |
| 650 * If an element by the same name is already in the imported scope, an |
| 651 * [ErroneousElement] will be put in the imported scope, allowing for |
| 652 * detection of ambiguous uses of imported names. |
| 653 */ |
| 654 void addImport(Element enclosingElement, |
| 655 Element element, |
| 656 Import import, |
| 657 DiagnosticListener listener) { |
| 658 LibraryElementX library = enclosingElement.getLibrary(); |
| 659 Map<Element, Link<Import>> importers = library.importers; |
| 660 importers[element] = |
| 661 importers.putIfAbsent(element, () => const Link<Import>()) |
| 662 .prepend(import); |
| 663 SourceString name = element.name; |
| 664 Element existing = importScope.putIfAbsent(name, () => element); |
| 665 |
| 666 Element createWarnOnUseElement(Spannable spannable, |
| 667 MessageKind messageKind, |
| 668 Element hidingElement, |
| 669 Element hiddenElement) { |
| 670 Uri hiddenUri = hiddenElement.getLibrary().canonicalUri; |
| 671 Uri hidingUri = hidingElement.getLibrary().canonicalUri; |
| 672 return new WarnOnUseElementX( |
| 673 new WrappedMessage( |
| 674 null, // Report on reference to [hidingElement]. |
| 675 messageKind, |
| 676 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), |
| 677 new WrappedMessage( |
| 678 listener.spanFromSpannable(spannable), |
| 679 MessageKind.IMPORTED_HERE, |
| 680 {'name': name}), |
| 681 enclosingElement, hidingElement); |
| 682 } |
| 683 |
| 684 if (existing != element) { |
| 685 if (existing.getLibrary().isPlatformLibrary && |
| 686 !element.getLibrary().isPlatformLibrary) { |
| 687 // [existing] is implicitly hidden. |
| 688 importScope[name] = createWarnOnUseElement( |
| 689 import, MessageKind.HIDDEN_IMPORT, element, existing); |
| 690 } else if (!existing.getLibrary().isPlatformLibrary && |
| 691 element.getLibrary().isPlatformLibrary) { |
| 692 // [element] is implicitly hidden. |
| 693 if (import == null) { |
| 694 // [element] is imported implicitly (probably through dart:core). |
| 695 importScope[name] = createWarnOnUseElement( |
| 696 importers[existing].head, MessageKind.HIDDEN_IMPLICIT_IMPORT, |
| 697 existing, element); |
| 698 } else { |
| 699 importScope[name] = createWarnOnUseElement( |
| 700 import, MessageKind.HIDDEN_IMPORT, existing, element); |
| 701 } |
| 702 } else { |
| 703 importScope[name] = new AmbiguousElementX( |
| 704 MessageKind.DUPLICATE_IMPORT, {'name': name}, |
| 705 enclosingElement, existing, element); |
| 706 } |
| 707 } |
| 708 } |
| 709 |
| 710 Element operator [](SourceString name) => importScope[name]; |
| 711 } |
| 712 |
| 637 class LibraryElementX extends ElementX implements LibraryElement { | 713 class LibraryElementX extends ElementX implements LibraryElement { |
| 638 final Uri canonicalUri; | 714 final Uri canonicalUri; |
| 639 CompilationUnitElement entryCompilationUnit; | 715 CompilationUnitElement entryCompilationUnit; |
| 640 Link<CompilationUnitElement> compilationUnits = | 716 Link<CompilationUnitElement> compilationUnits = |
| 641 const Link<CompilationUnitElement>(); | 717 const Link<CompilationUnitElement>(); |
| 642 Link<LibraryTag> tags = const Link<LibraryTag>(); | 718 Link<LibraryTag> tags = const Link<LibraryTag>(); |
| 643 LibraryName libraryTag; | 719 LibraryName libraryTag; |
| 644 bool canUseNative = false; | 720 bool canUseNative = false; |
| 645 Link<Element> localMembers = const Link<Element>(); | 721 Link<Element> localMembers = const Link<Element>(); |
| 646 final ScopeX localScope = new ScopeX(); | 722 final ScopeX localScope = new ScopeX(); |
| 723 final ImportScope importScope = new ImportScope(); |
| 647 | 724 |
| 648 /** | 725 /** |
| 649 * If this library is patched, [patch] points to the patch library. | 726 * If this library is patched, [patch] points to the patch library. |
| 650 * | 727 * |
| 651 * See [:patch_parser.dart:] for a description of the terminology. | 728 * See [:patch_parser.dart:] for a description of the terminology. |
| 652 */ | 729 */ |
| 653 LibraryElementX patch = null; | 730 LibraryElementX patch = null; |
| 654 | 731 |
| 655 /** | 732 /** |
| 656 * If this is a patch library, [origin] points to the origin library. | 733 * If this is a patch library, [origin] points to the origin library. |
| 657 * | 734 * |
| 658 * See [:patch_parser.dart:] for a description of the terminology. | 735 * See [:patch_parser.dart:] for a description of the terminology. |
| 659 */ | 736 */ |
| 660 final LibraryElementX origin; | 737 final LibraryElementX origin; |
| 661 | 738 |
| 662 /** | |
| 663 * Map for elements imported through import declarations. | |
| 664 * | |
| 665 * Addition to the map is performed by [addImport]. Lookup is done trough | |
| 666 * [find]. | |
| 667 */ | |
| 668 final Map<SourceString, Element> importScope; | |
| 669 | |
| 670 /// A mapping from an imported element to the "import" tag. | 739 /// A mapping from an imported element to the "import" tag. |
| 671 final Map<Element, Link<Import>> importers; | 740 final Map<Element, Link<Import>> importers; |
| 672 | 741 |
| 673 /** | 742 /** |
| 674 * Link for elements exported either through export declarations or through | 743 * Link for elements exported either through export declarations or through |
| 675 * declaration. This field should not be accessed directly but instead through | 744 * declaration. This field should not be accessed directly but instead through |
| 676 * the [exports] getter. | 745 * the [exports] getter. |
| 677 * | 746 * |
| 678 * [LibraryDependencyHandler] sets this field through [setExports] when the | 747 * [LibraryDependencyHandler] sets this field through [setExports] when the |
| 679 * library is loaded. | 748 * library is loaded. |
| 680 */ | 749 */ |
| 681 Link<Element> slotForExports; | 750 Link<Element> slotForExports; |
| 682 | 751 |
| 683 final Map<LibraryDependency, LibraryElement> tagMapping = | 752 final Map<LibraryDependency, LibraryElement> tagMapping = |
| 684 new LinkedHashMap<LibraryDependency, LibraryElement>(); | 753 new LinkedHashMap<LibraryDependency, LibraryElement>(); |
| 685 | 754 |
| 686 LibraryElementX(Script script, [Uri canonicalUri, LibraryElement this.origin]) | 755 LibraryElementX(Script script, [Uri canonicalUri, LibraryElement this.origin]) |
| 687 : this.canonicalUri = ((canonicalUri == null) ? script.uri : canonicalUri), | 756 : this.canonicalUri = ((canonicalUri == null) ? script.uri : canonicalUri), |
| 688 importScope = new Map<SourceString, Element>(), | |
| 689 importers = new Map<Element, Link<Import>>(), | 757 importers = new Map<Element, Link<Import>>(), |
| 690 super(new SourceString(script.name), ElementKind.LIBRARY, null) { | 758 super(new SourceString(script.name), ElementKind.LIBRARY, null) { |
| 691 entryCompilationUnit = new CompilationUnitElementX(script, this); | 759 entryCompilationUnit = new CompilationUnitElementX(script, this); |
| 692 if (isPatch) { | 760 if (isPatch) { |
| 693 origin.patch = this; | 761 origin.patch = this; |
| 694 } | 762 } |
| 695 } | 763 } |
| 696 | 764 |
| 697 bool get isPatched => patch != null; | 765 bool get isPatched => patch != null; |
| 698 bool get isPatch => origin != null; | 766 bool get isPatch => origin != null; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 726 | 794 |
| 727 LibraryElement getLibraryFromTag(LibraryDependency tag) => tagMapping[tag]; | 795 LibraryElement getLibraryFromTag(LibraryDependency tag) => tagMapping[tag]; |
| 728 | 796 |
| 729 /** | 797 /** |
| 730 * Adds [element] to the import scope of this library. | 798 * Adds [element] to the import scope of this library. |
| 731 * | 799 * |
| 732 * If an element by the same name is already in the imported scope, an | 800 * If an element by the same name is already in the imported scope, an |
| 733 * [ErroneousElement] will be put in the imported scope, allowing for detectio
n of ambiguous uses of imported names. | 801 * [ErroneousElement] will be put in the imported scope, allowing for detectio
n of ambiguous uses of imported names. |
| 734 */ | 802 */ |
| 735 void addImport(Element element, Import import, DiagnosticListener listener) { | 803 void addImport(Element element, Import import, DiagnosticListener listener) { |
| 736 importers[element] = | 804 importScope.addImport(this, element, import, listener); |
| 737 importers.putIfAbsent(element, () => const Link<Import>()) | |
| 738 .prepend(import); | |
| 739 SourceString name = element.name; | |
| 740 Element existing = importScope.putIfAbsent(name, () => element); | |
| 741 | |
| 742 Element createWarnOnUseElement(Spannable spannable, | |
| 743 MessageKind messageKind, | |
| 744 Element hidingElement, | |
| 745 Element hiddenElement) { | |
| 746 Uri hiddenUri = hiddenElement.getLibrary().canonicalUri; | |
| 747 Uri hidingUri = hidingElement.getLibrary().canonicalUri; | |
| 748 return new WarnOnUseElementX( | |
| 749 new WrappedMessage( | |
| 750 null, // Report on reference to [hidingElement]. | |
| 751 messageKind, | |
| 752 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), | |
| 753 new WrappedMessage( | |
| 754 listener.spanFromSpannable(spannable), | |
| 755 MessageKind.IMPORTED_HERE, | |
| 756 {'name': name}), | |
| 757 this, hidingElement); | |
| 758 } | |
| 759 | |
| 760 if (existing != element) { | |
| 761 if (existing.getLibrary().isPlatformLibrary && | |
| 762 !element.getLibrary().isPlatformLibrary) { | |
| 763 // [existing] is implicitly hidden. | |
| 764 importScope[name] = createWarnOnUseElement( | |
| 765 import, MessageKind.HIDDEN_IMPORT, element, existing); | |
| 766 } else if (!existing.getLibrary().isPlatformLibrary && | |
| 767 element.getLibrary().isPlatformLibrary) { | |
| 768 // [element] is implicitly hidden. | |
| 769 if (import == null) { | |
| 770 // [element] is imported implicitly (probably through dart:core). | |
| 771 importScope[name] = createWarnOnUseElement( | |
| 772 importers[existing].head, MessageKind.HIDDEN_IMPLICIT_IMPORT, | |
| 773 existing, element); | |
| 774 } else { | |
| 775 importScope[name] = createWarnOnUseElement( | |
| 776 import, MessageKind.HIDDEN_IMPORT, existing, element); | |
| 777 } | |
| 778 } else { | |
| 779 // TODO(johnniwinther): Provide access to the import tags from which | |
| 780 // the elements came. | |
| 781 importScope[name] = new AmbiguousElementX( | |
| 782 MessageKind.DUPLICATE_IMPORT, {'name': name}, | |
| 783 this, existing, element); | |
| 784 } | |
| 785 } | |
| 786 } | 805 } |
| 787 | 806 |
| 788 void addMember(Element element, DiagnosticListener listener) { | 807 void addMember(Element element, DiagnosticListener listener) { |
| 789 localMembers = localMembers.prepend(element); | 808 localMembers = localMembers.prepend(element); |
| 790 addToScope(element, listener); | 809 addToScope(element, listener); |
| 791 } | 810 } |
| 792 | 811 |
| 793 void addToScope(Element element, DiagnosticListener listener) { | 812 void addToScope(Element element, DiagnosticListener listener) { |
| 794 localScope.add(element, listener); | 813 localScope.add(element, listener); |
| 795 } | 814 } |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 } | 944 } |
| 926 } | 945 } |
| 927 | 946 |
| 928 int compareTo(LibraryElement other) { | 947 int compareTo(LibraryElement other) { |
| 929 if (this == other) return 0; | 948 if (this == other) return 0; |
| 930 return getLibraryOrScriptName().compareTo(other.getLibraryOrScriptName()); | 949 return getLibraryOrScriptName().compareTo(other.getLibraryOrScriptName()); |
| 931 } | 950 } |
| 932 } | 951 } |
| 933 | 952 |
| 934 class PrefixElementX extends ElementX implements PrefixElement { | 953 class PrefixElementX extends ElementX implements PrefixElement { |
| 935 Map<SourceString, Element> imported; | |
| 936 Token firstPosition; | 954 Token firstPosition; |
| 937 | 955 |
| 956 final ImportScope importScope = new ImportScope(); |
| 957 |
| 938 PrefixElementX(SourceString prefix, Element enclosing, this.firstPosition) | 958 PrefixElementX(SourceString prefix, Element enclosing, this.firstPosition) |
| 939 : imported = new Map<SourceString, Element>(), | 959 : super(prefix, ElementKind.PREFIX, enclosing); |
| 940 super(prefix, ElementKind.PREFIX, enclosing); | |
| 941 | 960 |
| 942 Element lookupLocalMember(SourceString memberName) => imported[memberName]; | 961 Element lookupLocalMember(SourceString memberName) => importScope[memberName]; |
| 943 | 962 |
| 944 DartType computeType(Compiler compiler) => compiler.types.dynamicType; | 963 DartType computeType(Compiler compiler) => compiler.types.dynamicType; |
| 945 | 964 |
| 946 Token position() => firstPosition; | 965 Token position() => firstPosition; |
| 966 |
| 967 void addImport(Element element, Import import, DiagnosticListener listener) { |
| 968 importScope.addImport(this, element, import, listener); |
| 969 } |
| 947 } | 970 } |
| 948 | 971 |
| 949 class TypedefElementX extends ElementX implements TypedefElement { | 972 class TypedefElementX extends ElementX implements TypedefElement { |
| 950 Typedef cachedNode; | 973 Typedef cachedNode; |
| 951 | 974 |
| 952 /** | 975 /** |
| 953 * The type of this typedef in which the type arguments are the type | 976 * The type of this typedef in which the type arguments are the type |
| 954 * variables. | 977 * variables. |
| 955 * | 978 * |
| 956 * This resembles the [ClassElement.thisType] though a typedef has no notion | 979 * This resembles the [ClassElement.thisType] though a typedef has no notion |
| (...skipping 1349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2306 | 2329 |
| 2307 MetadataAnnotation ensureResolved(Compiler compiler) { | 2330 MetadataAnnotation ensureResolved(Compiler compiler) { |
| 2308 if (resolutionState == STATE_NOT_STARTED) { | 2331 if (resolutionState == STATE_NOT_STARTED) { |
| 2309 compiler.resolver.resolveMetadataAnnotation(this); | 2332 compiler.resolver.resolveMetadataAnnotation(this); |
| 2310 } | 2333 } |
| 2311 return this; | 2334 return this; |
| 2312 } | 2335 } |
| 2313 | 2336 |
| 2314 String toString() => 'MetadataAnnotation($value, $resolutionState)'; | 2337 String toString() => 'MetadataAnnotation($value, $resolutionState)'; |
| 2315 } | 2338 } |
| OLD | NEW |