Chromium Code Reviews| 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 '../compiler.dart' show | 7 import '../compiler.dart' show |
| 8 Compiler; | 8 Compiler; |
| 9 import '../constants/constant_constructors.dart'; | 9 import '../constants/constant_constructors.dart'; |
| 10 import '../constants/constructors.dart'; | 10 import '../constants/constructors.dart'; |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 553 newElement); | 553 newElement); |
| 554 | 554 |
| 555 void diagnose(Element context, DiagnosticListener listener) { | 555 void diagnose(Element context, DiagnosticListener listener) { |
| 556 Setlet ambiguousElements = flatten(); | 556 Setlet ambiguousElements = flatten(); |
| 557 MessageKind code = (ambiguousElements.length == 1) | 557 MessageKind code = (ambiguousElements.length == 1) |
| 558 ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION; | 558 ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION; |
| 559 LibraryElementX importer = context.library; | 559 LibraryElementX importer = context.library; |
| 560 for (Element element in ambiguousElements) { | 560 for (Element element in ambiguousElements) { |
| 561 var arguments = {'name': element.name}; | 561 var arguments = {'name': element.name}; |
| 562 listener.reportInfo(element, code, arguments); | 562 listener.reportInfo(element, code, arguments); |
| 563 Link<Import> importers = importer.importers.getImports(element); | |
| 564 listener.withCurrentElement(importer, () { | 563 listener.withCurrentElement(importer, () { |
| 565 for (; !importers.isEmpty; importers = importers.tail) { | 564 for (ImportElement import in importer.importers.getImports(element)) { |
| 566 listener.reportInfo( | 565 listener.reportInfo( |
| 567 importers.head, MessageKind.IMPORTED_HERE, arguments); | 566 import, MessageKind.IMPORTED_HERE, arguments); |
| 568 } | 567 } |
| 569 }); | 568 }); |
| 570 } | 569 } |
| 571 } | 570 } |
| 572 } | 571 } |
| 573 | 572 |
| 574 /// Element synthesized to recover from a duplicated member of an element. | 573 /// Element synthesized to recover from a duplicated member of an element. |
| 575 class DuplicatedElementX extends AmbiguousElementX { | 574 class DuplicatedElementX extends AmbiguousElementX { |
| 576 DuplicatedElementX( | 575 DuplicatedElementX( |
| 577 MessageKind messageKind, | 576 MessageKind messageKind, |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 755 | 754 |
| 756 bool get hasMembers => !localMembers.isEmpty; | 755 bool get hasMembers => !localMembers.isEmpty; |
| 757 | 756 |
| 758 Element get analyzableElement => library; | 757 Element get analyzableElement => library; |
| 759 | 758 |
| 760 accept(ElementVisitor visitor, arg) { | 759 accept(ElementVisitor visitor, arg) { |
| 761 return visitor.visitCompilationUnitElement(this, arg); | 760 return visitor.visitCompilationUnitElement(this, arg); |
| 762 } | 761 } |
| 763 } | 762 } |
| 764 | 763 |
| 765 class Importers { | 764 class Importers { |
|
karlklose
2015/09/15 06:35:55
Could you think of a more descriptive name for thi
Johnni Winther
2015/09/15 07:50:06
Done.
| |
| 766 Map<Element, Link<Import>> importers = new Map<Element, Link<Import>>(); | 765 Map<Element, List<ImportElement>> importers = |
| 766 new Map<Element, List<ImportElement>>(); | |
| 767 | 767 |
| 768 Link<Import> getImports(Element element) { | 768 List<ImportElement> getImports(Element element) { |
| 769 Link<Import> imports = importers[element]; | 769 List<ImportElement> imports = importers[element]; |
| 770 return imports != null ? imports : const Link<Import>(); | 770 return imports != null ? imports : const <ImportElement>[]; |
| 771 } | 771 } |
| 772 | 772 |
| 773 Import getImport(Element element) => getImports(element).head; | 773 ImportElement getImport(Element element) => getImports(element).first; |
| 774 | 774 |
| 775 void registerImport(Element element, Import import) { | 775 void registerImport(Element element, ImportElement import) { |
| 776 if (import == null) return; | 776 if (import == null) return; |
| 777 | 777 |
| 778 importers[element] = | 778 importers.putIfAbsent(element, () => <ImportElement>[]).add(import); |
| 779 importers.putIfAbsent(element, () => const Link<Import>()) | |
| 780 .prepend(import); | |
| 781 } | 779 } |
| 782 } | 780 } |
| 783 | 781 |
| 784 class ImportScope { | 782 class ImportScope { |
| 785 /** | 783 /** |
| 786 * Map for elements imported through import declarations. | 784 * Map for elements imported through import declarations. |
| 787 * | 785 * |
| 788 * Addition to the map is performed by [addImport]. Lookup is done trough | 786 * Addition to the map is performed by [addImport]. Lookup is done trough |
| 789 * [find]. | 787 * [find]. |
| 790 */ | 788 */ |
| 791 final Map<String, Element> importScope = | 789 final Map<String, Element> importScope = |
| 792 new Map<String, Element>(); | 790 new Map<String, Element>(); |
| 793 | 791 |
| 794 /** | 792 /** |
| 795 * Adds [element] to the import scope of this library. | 793 * Adds [element] to the import scope of this library. |
| 796 * | 794 * |
| 797 * If an element by the same name is already in the imported scope, an | 795 * If an element by the same name is already in the imported scope, an |
| 798 * [ErroneousElement] will be put in the imported scope, allowing for | 796 * [ErroneousElement] will be put in the imported scope, allowing for |
| 799 * detection of ambiguous uses of imported names. | 797 * detection of ambiguous uses of imported names. |
| 800 */ | 798 */ |
| 801 void addImport(Element enclosingElement, | 799 void addImport(Element enclosingElement, |
| 802 Element element, | 800 Element element, |
| 803 Import import, | 801 ImportElement import, |
| 804 DiagnosticListener listener) { | 802 DiagnosticListener listener) { |
| 805 LibraryElementX library = enclosingElement.library; | 803 LibraryElementX library = enclosingElement.library; |
| 806 Importers importers = library.importers; | 804 Importers importers = library.importers; |
| 807 | 805 |
| 808 String name = element.name; | 806 String name = element.name; |
| 809 | 807 |
| 810 // The loadLibrary function always shadows existing bindings to that name. | 808 // The loadLibrary function always shadows existing bindings to that name. |
| 811 if (element.isDeferredLoaderGetter) { | 809 if (element.isDeferredLoaderGetter) { |
| 812 importScope.remove(name); | 810 importScope.remove(name); |
| 813 // TODO(sigurdm): Print a hint. | 811 // TODO(sigurdm): Print a hint. |
| 814 } | 812 } |
| 815 Element existing = importScope.putIfAbsent(name, () => element); | 813 Element existing = importScope.putIfAbsent(name, () => element); |
| 816 importers.registerImport(element, import); | 814 importers.registerImport(element, import); |
| 817 | 815 |
| 818 void registerWarnOnUseElement(Import import, | 816 void registerWarnOnUseElement(ImportElement import, |
| 819 MessageKind messageKind, | 817 MessageKind messageKind, |
| 820 Element hidingElement, | 818 Element hidingElement, |
| 821 Element hiddenElement) { | 819 Element hiddenElement) { |
| 822 Uri hiddenUri = hiddenElement.library.canonicalUri; | 820 Uri hiddenUri = hiddenElement.library.canonicalUri; |
| 823 Uri hidingUri = hidingElement.library.canonicalUri; | 821 Uri hidingUri = hidingElement.library.canonicalUri; |
| 824 Element element = new WarnOnUseElementX( | 822 Element element = new WarnOnUseElementX( |
| 825 new WrappedMessage( | 823 new WrappedMessage( |
| 826 null, // Report on reference to [hidingElement]. | 824 null, // Report on reference to [hidingElement]. |
| 827 messageKind, | 825 messageKind, |
| 828 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), | 826 {'name': name, 'hiddenUri': hiddenUri, 'hidingUri': hidingUri}), |
| 829 new WrappedMessage( | 827 new WrappedMessage( |
| 830 listener.spanFromSpannable(import), | 828 listener.spanFromSpannable(import), |
| 831 MessageKind.IMPORTED_HERE, | 829 MessageKind.IMPORTED_HERE, |
| 832 {'name': name}), | 830 {'name': name}), |
| 833 enclosingElement, hidingElement); | 831 enclosingElement, hidingElement); |
| 834 importScope[name] = element; | 832 importScope[name] = element; |
| 835 importers.registerImport(element, import); | 833 importers.registerImport(element, import); |
| 836 } | 834 } |
| 837 | 835 |
| 838 if (existing != element) { | 836 if (existing != element) { |
| 839 Import existingImport = importers.getImport(existing); | 837 ImportElement existingImport = importers.getImport(existing); |
| 840 if (existing.library.isPlatformLibrary && | 838 if (existing.library.isPlatformLibrary && |
| 841 !element.library.isPlatformLibrary) { | 839 !element.library.isPlatformLibrary) { |
| 842 // [existing] is implicitly hidden. | 840 // [existing] is implicitly hidden. |
| 843 registerWarnOnUseElement( | 841 registerWarnOnUseElement( |
| 844 import, MessageKind.HIDDEN_IMPORT, element, existing); | 842 import, MessageKind.HIDDEN_IMPORT, element, existing); |
| 845 } else if (!existing.library.isPlatformLibrary && | 843 } else if (!existing.library.isPlatformLibrary && |
| 846 element.library.isPlatformLibrary) { | 844 element.library.isPlatformLibrary) { |
| 847 // [element] is implicitly hidden. | 845 // [element] is implicitly hidden. |
| 848 if (import == null) { | 846 if (import.isSynthesized) { |
| 849 // [element] is imported implicitly (probably through dart:core). | 847 // [element] is imported implicitly (probably through dart:core). |
| 850 registerWarnOnUseElement( | 848 registerWarnOnUseElement( |
| 851 existingImport, MessageKind.HIDDEN_IMPLICIT_IMPORT, | 849 existingImport, MessageKind.HIDDEN_IMPLICIT_IMPORT, |
| 852 existing, element); | 850 existing, element); |
| 853 } else { | 851 } else { |
| 854 registerWarnOnUseElement( | 852 registerWarnOnUseElement( |
| 855 import, MessageKind.HIDDEN_IMPORT, existing, element); | 853 import, MessageKind.HIDDEN_IMPORT, existing, element); |
| 856 } | 854 } |
| 857 } else { | 855 } else { |
| 858 Element ambiguousElement = new AmbiguousImportX( | 856 Element ambiguousElement = new AmbiguousImportX( |
| 859 MessageKind.DUPLICATE_IMPORT, {'name': name}, | 857 MessageKind.DUPLICATE_IMPORT, {'name': name}, |
| 860 enclosingElement, existing, element); | 858 enclosingElement, existing, element); |
| 861 importScope[name] = ambiguousElement; | 859 importScope[name] = ambiguousElement; |
| 862 importers.registerImport(ambiguousElement, import); | 860 importers.registerImport(ambiguousElement, import); |
| 863 importers.registerImport(ambiguousElement, existingImport); | 861 importers.registerImport(ambiguousElement, existingImport); |
| 864 } | 862 } |
| 865 } | 863 } |
| 866 } | 864 } |
| 867 | 865 |
| 868 Element operator [](String name) => importScope[name]; | 866 Element operator [](String name) => importScope[name]; |
| 867 | |
| 868 void forEach(f(Element element)) => importScope.values.forEach(f); | |
| 869 } | |
| 870 | |
| 871 abstract class LibraryDependencyElementX extends ElementX { | |
| 872 final LibraryDependency node; | |
| 873 final Uri uri; | |
| 874 LibraryElement libraryDependency; | |
| 875 | |
| 876 LibraryDependencyElementX(CompilationUnitElement enclosingElement, | |
| 877 ElementKind kind, | |
| 878 this.node, | |
| 879 this.uri) | |
| 880 : super('', kind, enclosingElement); | |
| 881 | |
| 882 @override | |
| 883 List<MetadataAnnotation> get metadata => node.metadata; | |
| 884 | |
| 885 void set metadata(value) { | |
| 886 // The metadata is stored on [libraryDependency]. | |
| 887 throw new SpannableAssertionFailure( | |
| 888 this, 'Cannot set metadata on a import/export.'); | |
| 889 } | |
| 890 | |
| 891 @override | |
| 892 Token get position => node.getBeginToken(); | |
| 893 | |
| 894 SourceSpan get sourcePosition { | |
| 895 return new SourceSpan.fromNode(compilationUnit.script.resourceUri, node); | |
| 896 } | |
| 897 | |
| 898 String toString() => '$kind($uri)'; | |
| 899 } | |
| 900 | |
| 901 class ImportElementX extends LibraryDependencyElementX | |
| 902 implements ImportElement { | |
| 903 PrefixElementX prefix; | |
| 904 | |
| 905 ImportElementX(CompilationUnitElement enclosingElement, Import node, Uri uri) | |
| 906 : super(enclosingElement, ElementKind.IMPORT, node, uri); | |
| 907 | |
| 908 @override | |
| 909 Import get node => super.node; | |
| 910 | |
| 911 @override | |
| 912 LibraryElement get importedLibrary => libraryDependency; | |
| 913 | |
| 914 @override | |
| 915 accept(ElementVisitor visitor, arg) => visitor.visitImportElement(this, arg); | |
| 916 | |
| 917 @override | |
| 918 bool get isDeferred => node.isDeferred; | |
| 919 } | |
| 920 | |
| 921 class SyntheticImportElement extends ImportElementX { | |
| 922 SyntheticImportElement(CompilationUnitElement enclosingElement, Uri uri) | |
| 923 : super(enclosingElement, null, uri); | |
| 924 | |
| 925 @override | |
| 926 Token get position => library.position; | |
| 927 | |
| 928 @override | |
| 929 bool get isSynthesized => true; | |
| 930 | |
| 931 @override | |
| 932 bool get isDeferred => false; | |
| 933 | |
| 934 @override | |
| 935 List<MetadataAnnotation> get metadata => const <MetadataAnnotation>[]; | |
| 936 | |
| 937 @override | |
| 938 SourceSpan get sourcePosition => library.sourcePosition; | |
| 939 } | |
| 940 | |
| 941 | |
| 942 class ExportElementX extends LibraryDependencyElementX | |
| 943 implements ExportElement { | |
| 944 | |
| 945 ExportElementX(CompilationUnitElement enclosingElement, Export node, Uri uri) | |
| 946 : super(enclosingElement, ElementKind.EXPORT, node, uri); | |
| 947 | |
| 948 Export get node => super.node; | |
| 949 | |
| 950 @override | |
| 951 LibraryElement get exportedLibrary => libraryDependency; | |
| 952 | |
| 953 @override | |
| 954 accept(ElementVisitor visitor, arg) => visitor.visitExportElement(this, arg); | |
| 869 } | 955 } |
| 870 | 956 |
| 871 class LibraryElementX | 957 class LibraryElementX |
| 872 extends ElementX | 958 extends ElementX |
| 873 with LibraryElementCommon, | 959 with LibraryElementCommon, |
| 874 AnalyzableElementX, | 960 AnalyzableElementX, |
| 875 PatchMixin<LibraryElementX> | 961 PatchMixin<LibraryElementX> |
| 876 implements LibraryElement { | 962 implements LibraryElement { |
| 877 final Uri canonicalUri; | 963 final Uri canonicalUri; |
| 878 | 964 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 896 /** | 982 /** |
| 897 * Link for elements exported either through export declarations or through | 983 * Link for elements exported either through export declarations or through |
| 898 * declaration. This field should not be accessed directly but instead through | 984 * declaration. This field should not be accessed directly but instead through |
| 899 * the [exports] getter. | 985 * the [exports] getter. |
| 900 * | 986 * |
| 901 * [LibraryDependencyHandler] sets this field through [setExports] when the | 987 * [LibraryDependencyHandler] sets this field through [setExports] when the |
| 902 * library is loaded. | 988 * library is loaded. |
| 903 */ | 989 */ |
| 904 Link<Element> slotForExports; | 990 Link<Element> slotForExports; |
| 905 | 991 |
| 992 List<ImportElement> _imports = <ImportElement>[]; | |
| 993 List<ExportElement> _exports = <ExportElement>[]; | |
| 994 | |
| 906 final Map<LibraryDependency, LibraryElement> tagMapping = | 995 final Map<LibraryDependency, LibraryElement> tagMapping = |
| 907 new Map<LibraryDependency, LibraryElement>(); | 996 new Map<LibraryDependency, LibraryElement>(); |
| 908 | 997 |
| 909 LibraryElementX(Script script, | 998 LibraryElementX(Script script, |
| 910 [Uri canonicalUri, LibraryElementX origin]) | 999 [Uri canonicalUri, LibraryElementX origin]) |
| 911 : this.canonicalUri = | 1000 : this.canonicalUri = |
| 912 ((canonicalUri == null) ? script.readableUri : canonicalUri), | 1001 ((canonicalUri == null) ? script.readableUri : canonicalUri), |
| 913 this.isSynthesized = script.isSynthesized, | 1002 this.isSynthesized = script.isSynthesized, |
| 914 super(script.name, ElementKind.LIBRARY, null) { | 1003 super(script.name, ElementKind.LIBRARY, null) { |
| 915 entryCompilationUnit = new CompilationUnitElementX(script, this); | 1004 entryCompilationUnit = new CompilationUnitElementX(script, this); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 947 } | 1036 } |
| 948 | 1037 |
| 949 Iterable<LibraryTag> get tags { | 1038 Iterable<LibraryTag> get tags { |
| 950 if (tagsCache == null) { | 1039 if (tagsCache == null) { |
| 951 tagsCache = tagsBuilder.toList(); | 1040 tagsCache = tagsBuilder.toList(); |
| 952 tagsBuilder = null; | 1041 tagsBuilder = null; |
| 953 } | 1042 } |
| 954 return tagsCache; | 1043 return tagsCache; |
| 955 } | 1044 } |
| 956 | 1045 |
| 957 /// Record which element an import or export tag resolved to. | 1046 void addImportDeclaration(ImportElement import) { |
| 958 void recordResolvedTag(LibraryDependency tag, LibraryElement library) { | 1047 _imports.add(import); |
| 959 assert(tagMapping[tag] == null); | |
| 960 tagMapping[tag] = library; | |
| 961 } | 1048 } |
| 962 | 1049 |
| 963 LibraryElement getLibraryFromTag(LibraryDependency tag) => tagMapping[tag]; | 1050 Iterable<ImportElement> get imports => _imports; |
| 1051 | |
| 1052 void addExportDeclaration(ExportElement export) { | |
| 1053 _exports.add(export); | |
| 1054 } | |
| 1055 | |
| 1056 Iterable<ExportElement> get exports => _exports; | |
| 964 | 1057 |
| 965 /** | 1058 /** |
| 966 * Adds [element] to the import scope of this library. | 1059 * Adds [element] to the import scope of this library. |
| 967 * | 1060 * |
| 968 * If an element by the same name is already in the imported scope, an | 1061 * If an element by the same name is already in the imported scope, an |
| 969 * [ErroneousElement] will be put in the imported scope, allowing for | 1062 * [ErroneousElement] will be put in the imported scope, allowing for |
| 970 * detection of ambiguous uses of imported names. | 1063 * detection of ambiguous uses of imported names. |
| 971 */ | 1064 */ |
| 972 void addImport(Element element, Import import, DiagnosticListener listener) { | 1065 void addImport(Element element, |
| 1066 ImportElement import, | |
| 1067 DiagnosticListener listener) { | |
| 973 importScope.addImport(this, element, import, listener); | 1068 importScope.addImport(this, element, import, listener); |
| 974 } | 1069 } |
| 975 | 1070 |
| 976 void addMember(Element element, DiagnosticListener listener) { | 1071 void addMember(Element element, DiagnosticListener listener) { |
| 977 localMembers = localMembers.prepend(element); | 1072 localMembers = localMembers.prepend(element); |
| 978 addToScope(element, listener); | 1073 addToScope(element, listener); |
| 979 } | 1074 } |
| 980 | 1075 |
| 981 void addToScope(Element element, DiagnosticListener listener) { | 1076 void addToScope(Element element, DiagnosticListener listener) { |
| 982 localScope.add(element, listener); | 1077 localScope.add(element, listener); |
| 983 } | 1078 } |
| 984 | 1079 |
| 985 Element localLookup(String elementName) { | 1080 Element localLookup(String elementName) { |
| 986 Element result = localScope.lookup(elementName); | 1081 Element result = localScope.lookup(elementName); |
| 987 if (result == null && isPatch) { | 1082 if (result == null && isPatch) { |
| 988 result = origin.localLookup(elementName); | 1083 result = origin.localLookup(elementName); |
| 989 } | 1084 } |
| 990 return result; | 1085 return result; |
| 991 } | 1086 } |
| 992 | 1087 |
| 993 /** | 1088 /** |
| 994 * Returns [:true:] if the export scope has already been computed for this | 1089 * Returns [:true:] if the export scope has already been computed for this |
| 995 * library. | 1090 * library. |
| 996 */ | 1091 */ |
| 997 bool get exportsHandled => slotForExports != null; | 1092 bool get exportsHandled => slotForExports != null; |
| 998 | 1093 |
| 999 Link<Element> get exports { | |
| 1000 assert(invariant(this, exportsHandled, | |
| 1001 message: 'Exports not handled on $this')); | |
| 1002 return slotForExports; | |
| 1003 } | |
| 1004 | |
| 1005 /** | 1094 /** |
| 1006 * Sets the export scope of this library. This method can only be called once. | 1095 * Sets the export scope of this library. This method can only be called once. |
| 1007 */ | 1096 */ |
| 1008 void setExports(Iterable<Element> exportedElements) { | 1097 void setExports(Iterable<Element> exportedElements) { |
| 1009 assert(invariant(this, !exportsHandled, | 1098 assert(invariant(this, !exportsHandled, |
| 1010 message: 'Exports already set to $slotForExports on $this')); | 1099 message: 'Exports already set to $slotForExports on $this')); |
| 1011 assert(invariant(this, exportedElements != null)); | 1100 assert(invariant(this, exportedElements != null)); |
| 1012 var builder = new LinkBuilder<Element>(); | 1101 var builder = new LinkBuilder<Element>(); |
| 1013 for (Element export in exportedElements) { | 1102 for (Element export in exportedElements) { |
| 1014 builder.addLast(export); | 1103 builder.addLast(export); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1046 // TODO((johnniwinther): How to handle injected elements in the patch | 1135 // TODO((johnniwinther): How to handle injected elements in the patch |
| 1047 // library? | 1136 // library? |
| 1048 Element result = localScope.lookup(elementName); | 1137 Element result = localScope.lookup(elementName); |
| 1049 if (result == null && isPatch) { | 1138 if (result == null && isPatch) { |
| 1050 return origin.findLocal(elementName); | 1139 return origin.findLocal(elementName); |
| 1051 } | 1140 } |
| 1052 return result; | 1141 return result; |
| 1053 } | 1142 } |
| 1054 | 1143 |
| 1055 Element findExported(String elementName) { | 1144 Element findExported(String elementName) { |
| 1056 for (Link link = exports; !link.isEmpty; link = link.tail) { | 1145 assert(invariant(this, exportsHandled, |
| 1146 message: 'Exports not handled on $this')); | |
| 1147 for (Link link = slotForExports; !link.isEmpty; link = link.tail) { | |
| 1057 Element element = link.head; | 1148 Element element = link.head; |
| 1058 if (element.name == elementName) return element; | 1149 if (element.name == elementName) return element; |
| 1059 } | 1150 } |
| 1060 return null; | 1151 return null; |
| 1061 } | 1152 } |
| 1062 | 1153 |
| 1063 void forEachExport(f(Element element)) { | 1154 void forEachExport(f(Element element)) { |
| 1064 exports.forEach((Element e) => f(e)); | 1155 assert(invariant(this, exportsHandled, |
| 1156 message: 'Exports not handled on $this')); | |
| 1157 slotForExports.forEach((Element e) => f(e)); | |
| 1065 } | 1158 } |
| 1066 | 1159 |
| 1067 Link<Import> getImportsFor(Element element) => importers.getImports(element); | 1160 Iterable<ImportElement> getImportsFor(Element element) { |
| 1161 return importers.getImports(element); | |
| 1162 } | |
| 1068 | 1163 |
| 1069 @override | 1164 void forEachImport(f(Element element)) => importScope.forEach(f); |
| 1070 void forEachImport(f(Element element)) { | |
| 1071 importScope.importScope.values.forEach(f); | |
| 1072 } | |
| 1073 | 1165 |
| 1074 void forEachLocalMember(f(Element element)) { | 1166 void forEachLocalMember(f(Element element)) { |
| 1075 if (isPatch) { | 1167 if (isPatch) { |
| 1076 // Patch libraries traverse both origin and injected members. | 1168 // Patch libraries traverse both origin and injected members. |
| 1077 origin.localMembers.forEach(f); | 1169 origin.localMembers.forEach(f); |
| 1078 | 1170 |
| 1079 void filterPatch(Element element) { | 1171 void filterPatch(Element element) { |
| 1080 if (!element.isPatch) { | 1172 if (!element.isPatch) { |
| 1081 // Do not traverse the patch members. | 1173 // Do not traverse the patch members. |
| 1082 f(element); | 1174 f(element); |
| 1083 } | 1175 } |
| 1084 } | 1176 } |
| 1085 localMembers.forEach(filterPatch); | 1177 localMembers.forEach(filterPatch); |
| 1086 } else { | 1178 } else { |
| 1087 localMembers.forEach(f); | 1179 localMembers.forEach(f); |
| 1088 } | 1180 } |
| 1089 } | 1181 } |
| 1090 | 1182 |
| 1091 Iterable<Element> getNonPrivateElementsInScope() { | 1183 Iterable<Element> getNonPrivateElementsInScope() { |
| 1092 return localScope.values.where((Element element) { | 1184 return localScope.values.where((Element element) { |
| 1093 // At this point [localScope] only contains members so we don't need | 1185 // At this point [localScope] only contains members so we don't need |
| 1094 // to check for foreign or prefix elements. | 1186 // to check for foreign or prefix elements. |
| 1095 return !Name.isPrivateName(element.name); | 1187 return !Name.isPrivateName(element.name); |
| 1096 }); | 1188 }); |
| 1097 } | 1189 } |
| 1098 | 1190 |
| 1099 bool hasLibraryName() => libraryTag != null; | 1191 bool get hasLibraryName => libraryTag != null; |
| 1100 | 1192 |
| 1101 /** | 1193 String get libraryName { |
| 1102 * Returns the library name, which is either the name given in the library tag | |
| 1103 * or the empty string if there is no library tag. | |
| 1104 */ | |
| 1105 String getLibraryName() { | |
| 1106 if (libraryTag == null) return ''; | 1194 if (libraryTag == null) return ''; |
| 1107 return libraryTag.name.toString(); | 1195 return libraryTag.name.toString(); |
| 1108 } | 1196 } |
| 1109 | 1197 |
| 1198 String get libraryOrScriptName { | |
| 1199 if (libraryTag != null) { | |
| 1200 return libraryTag.name.toString(); | |
| 1201 } else { | |
| 1202 // Use the file name as script name. | |
| 1203 String path = canonicalUri.path; | |
| 1204 return path.substring(path.lastIndexOf('/') + 1); | |
| 1205 } | |
| 1206 } | |
| 1207 | |
| 1110 Scope buildScope() => new LibraryScope(this); | 1208 Scope buildScope() => new LibraryScope(this); |
| 1111 | 1209 |
| 1112 String toString() { | 1210 String toString() { |
| 1113 if (origin != null) { | 1211 if (origin != null) { |
| 1114 return 'patch library(${canonicalUri})'; | 1212 return 'patch library(${canonicalUri})'; |
| 1115 } else if (patch != null) { | 1213 } else if (patch != null) { |
| 1116 return 'origin library(${canonicalUri})'; | 1214 return 'origin library(${canonicalUri})'; |
| 1117 } else { | 1215 } else { |
| 1118 return 'library(${canonicalUri})'; | 1216 return 'library(${canonicalUri})'; |
| 1119 } | 1217 } |
| 1120 } | 1218 } |
| 1121 | 1219 |
| 1122 accept(ElementVisitor visitor, arg) { | 1220 accept(ElementVisitor visitor, arg) { |
| 1123 return visitor.visitLibraryElement(this, arg); | 1221 return visitor.visitLibraryElement(this, arg); |
| 1124 } | 1222 } |
| 1125 | 1223 |
| 1126 // TODO(johnniwinther): Remove these when issue 18630 is fixed. | 1224 // TODO(johnniwinther): Remove these when issue 18630 is fixed. |
| 1127 LibraryElementX get patch => super.patch; | 1225 LibraryElementX get patch => super.patch; |
| 1128 LibraryElementX get origin => super.origin; | 1226 LibraryElementX get origin => super.origin; |
| 1129 } | 1227 } |
| 1130 | 1228 |
| 1131 class PrefixElementX extends ElementX implements PrefixElement { | 1229 class PrefixElementX extends ElementX implements PrefixElement { |
| 1132 Token firstPosition; | 1230 Token firstPosition; |
| 1133 | 1231 |
| 1134 final ImportScope importScope = new ImportScope(); | 1232 final ImportScope importScope = new ImportScope(); |
| 1135 | 1233 |
| 1136 bool get isDeferred => _deferredImport != null; | 1234 bool get isDeferred => deferredImport != null; |
| 1137 | 1235 |
| 1138 // Only needed for deferred imports. | 1236 // Only needed for deferred imports. |
| 1139 Import _deferredImport; | 1237 final ImportElement deferredImport; |
| 1140 Import get deferredImport => _deferredImport; | |
| 1141 | 1238 |
| 1142 PrefixElementX(String prefix, Element enclosing, this.firstPosition) | 1239 PrefixElementX(String prefix, |
| 1240 Element enclosing, | |
| 1241 this.firstPosition, | |
| 1242 this.deferredImport) | |
| 1143 : super(prefix, ElementKind.PREFIX, enclosing); | 1243 : super(prefix, ElementKind.PREFIX, enclosing); |
| 1144 | 1244 |
| 1145 bool get isTopLevel => false; | 1245 bool get isTopLevel => false; |
| 1146 | 1246 |
| 1147 Element lookupLocalMember(String memberName) => importScope[memberName]; | 1247 Element lookupLocalMember(String memberName) => importScope[memberName]; |
| 1148 | 1248 |
| 1149 DartType computeType(Compiler compiler) => const DynamicType(); | 1249 DartType computeType(Compiler compiler) => const DynamicType(); |
| 1150 | 1250 |
| 1151 Token get position => firstPosition; | 1251 Token get position => firstPosition; |
| 1152 | 1252 |
| 1153 void addImport(Element element, Import import, DiagnosticListener listener) { | 1253 void addImport(Element element, |
| 1254 ImportElement import, | |
| 1255 DiagnosticListener listener) { | |
| 1154 importScope.addImport(this, element, import, listener); | 1256 importScope.addImport(this, element, import, listener); |
| 1155 } | 1257 } |
| 1156 | 1258 |
| 1157 accept(ElementVisitor visitor, arg) { | 1259 accept(ElementVisitor visitor, arg) { |
| 1158 return visitor.visitPrefixElement(this, arg); | 1260 return visitor.visitPrefixElement(this, arg); |
| 1159 } | 1261 } |
| 1160 | 1262 |
| 1161 void markAsDeferred(Import deferredImport) { | |
| 1162 _deferredImport = deferredImport; | |
| 1163 } | |
| 1164 | |
| 1165 String toString() => '$kind($name)'; | 1263 String toString() => '$kind($name)'; |
| 1166 } | 1264 } |
| 1167 | 1265 |
| 1168 class TypedefElementX extends ElementX | 1266 class TypedefElementX extends ElementX |
| 1169 with AstElementMixin, | 1267 with AstElementMixin, |
| 1170 AnalyzableElementX, | 1268 AnalyzableElementX, |
| 1171 TypeDeclarationElementX<TypedefType> | 1269 TypeDeclarationElementX<TypedefType> |
| 1172 implements TypedefElement { | 1270 implements TypedefElement { |
| 1173 Typedef cachedNode; | 1271 Typedef cachedNode; |
| 1174 | 1272 |
| (...skipping 1792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2967 AstElement get definingElement; | 3065 AstElement get definingElement; |
| 2968 | 3066 |
| 2969 bool get hasResolvedAst => definingElement.hasTreeElements; | 3067 bool get hasResolvedAst => definingElement.hasTreeElements; |
| 2970 | 3068 |
| 2971 ResolvedAst get resolvedAst { | 3069 ResolvedAst get resolvedAst { |
| 2972 return new ResolvedAst(declaration, | 3070 return new ResolvedAst(declaration, |
| 2973 definingElement.node, definingElement.treeElements); | 3071 definingElement.node, definingElement.treeElements); |
| 2974 } | 3072 } |
| 2975 | 3073 |
| 2976 } | 3074 } |
| OLD | NEW |