| 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 'elements.dart'; | 7 import 'elements.dart'; |
| 8 import '../helpers/helpers.dart'; | 8 import '../helpers/helpers.dart'; |
| 9 import '../tree/tree.dart'; | 9 import '../tree/tree.dart'; |
| 10 import '../util/util.dart'; | 10 import '../util/util.dart'; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 'parseNode not implemented on $this.'); | 54 'parseNode not implemented on $this.'); |
| 55 return null; | 55 return null; |
| 56 } | 56 } |
| 57 | 57 |
| 58 DartType computeType(Compiler compiler) { | 58 DartType computeType(Compiler compiler) { |
| 59 compiler.internalError(this, | 59 compiler.internalError(this, |
| 60 "computeType not implemented on $this."); | 60 "computeType not implemented on $this."); |
| 61 return null; | 61 return null; |
| 62 } | 62 } |
| 63 | 63 |
| 64 void addMetadata(MetadataAnnotation annotation) { | 64 void addMetadata(MetadataAnnotationX annotation) { |
| 65 assert(annotation.annotatedElement == null); | 65 assert(annotation.annotatedElement == null); |
| 66 annotation.annotatedElement = this; | 66 annotation.annotatedElement = this; |
| 67 addMetadataInternal(annotation); | 67 addMetadataInternal(annotation); |
| 68 } | 68 } |
| 69 | 69 |
| 70 void addMetadataInternal(MetadataAnnotation annotation) { | 70 void addMetadataInternal(MetadataAnnotation annotation) { |
| 71 metadata = metadata.prepend(annotation); | 71 metadata = metadata.prepend(annotation); |
| 72 } | 72 } |
| 73 | 73 |
| 74 bool get isClosure => false; | 74 bool get isClosure => false; |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 */ | 195 */ |
| 196 Element get enclosingMember { | 196 Element get enclosingMember { |
| 197 for (Element e = this; e != null; e = e.enclosingElement) { | 197 for (Element e = this; e != null; e = e.enclosingElement) { |
| 198 if (e.isMember) return e; | 198 if (e.isMember) return e; |
| 199 } | 199 } |
| 200 return null; | 200 return null; |
| 201 } | 201 } |
| 202 | 202 |
| 203 Element get outermostEnclosingMemberOrTopLevel { | 203 Element get outermostEnclosingMemberOrTopLevel { |
| 204 // TODO(lrn): Why is this called "Outermost"? | 204 // TODO(lrn): Why is this called "Outermost"? |
| 205 // TODO(johnniwinther): Clean up this method: This method does not return |
| 206 // the outermost for elements in closure classses, but some call-sites rely |
| 207 // on that behavior. |
| 205 for (Element e = this; e != null; e = e.enclosingElement) { | 208 for (Element e = this; e != null; e = e.enclosingElement) { |
| 206 if (e.isMember || e.isTopLevel) { | 209 if (e.isMember || e.isTopLevel) { |
| 207 return e; | 210 return e; |
| 208 } | 211 } |
| 209 } | 212 } |
| 210 return null; | 213 return null; |
| 211 } | 214 } |
| 212 | 215 |
| 213 ClassElement get contextClass { | 216 ClassElement get contextClass { |
| 214 ClassElement cls; | 217 ClassElement cls; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 _fixedBackendName = name; | 258 _fixedBackendName = name; |
| 256 } | 259 } |
| 257 | 260 |
| 258 FunctionElement asFunctionElement() => null; | 261 FunctionElement asFunctionElement() => null; |
| 259 | 262 |
| 260 bool get isAbstract => modifiers.isAbstract; | 263 bool get isAbstract => modifiers.isAbstract; |
| 261 bool isForeign(Compiler compiler) => library == compiler.foreignLibrary; | 264 bool isForeign(Compiler compiler) => library == compiler.foreignLibrary; |
| 262 | 265 |
| 263 void diagnose(Element context, DiagnosticListener listener) {} | 266 void diagnose(Element context, DiagnosticListener listener) {} |
| 264 | 267 |
| 265 TreeElements get treeElements => enclosingElement.treeElements; | 268 TreeElements get treeElements => analyzableElement.treeElements; |
| 269 |
| 270 AnalyzableElement get analyzableElement => outermostEnclosingMemberOrTopLevel; |
| 266 } | 271 } |
| 267 | 272 |
| 268 /** | 273 /** |
| 269 * Represents an unresolvable or duplicated element. | 274 * Represents an unresolvable or duplicated element. |
| 270 * | 275 * |
| 271 * An [ErroneousElement] is used instead of [:null:] to provide additional | 276 * An [ErroneousElement] is used instead of [:null:] to provide additional |
| 272 * information about the error that caused the element to be unresolvable | 277 * information about the error that caused the element to be unresolvable |
| 273 * or otherwise invalid. | 278 * or otherwise invalid. |
| 274 * | 279 * |
| 275 * Accessing any field or calling any method defined on [ErroneousElement] | 280 * Accessing any field or calling any method defined on [ErroneousElement] |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 if (accessor.isGetter) { | 541 if (accessor.isGetter) { |
| 537 field.getter = accessor; | 542 field.getter = accessor; |
| 538 } else { | 543 } else { |
| 539 field.setter = accessor; | 544 field.setter = accessor; |
| 540 } | 545 } |
| 541 add(field, listener); | 546 add(field, listener); |
| 542 } | 547 } |
| 543 } | 548 } |
| 544 } | 549 } |
| 545 | 550 |
| 546 class CompilationUnitElementX extends ElementX with AnalyzableElement | 551 class CompilationUnitElementX extends ElementX |
| 547 implements CompilationUnitElement { | 552 implements CompilationUnitElement { |
| 548 final Script script; | 553 final Script script; |
| 549 PartOf partTag; | 554 PartOf partTag; |
| 550 Link<Element> localMembers = const Link<Element>(); | 555 Link<Element> localMembers = const Link<Element>(); |
| 551 | 556 |
| 552 CompilationUnitElementX(Script script, LibraryElement library) | 557 CompilationUnitElementX(Script script, LibraryElement library) |
| 553 : this.script = script, | 558 : this.script = script, |
| 554 super(script.name, | 559 super(script.name, |
| 555 ElementKind.COMPILATION_UNIT, | 560 ElementKind.COMPILATION_UNIT, |
| 556 library) { | 561 library) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 } | 610 } |
| 606 } | 611 } |
| 607 | 612 |
| 608 bool get hasMembers => !localMembers.isEmpty; | 613 bool get hasMembers => !localMembers.isEmpty; |
| 609 | 614 |
| 610 int compareTo(CompilationUnitElement other) { | 615 int compareTo(CompilationUnitElement other) { |
| 611 if (this == other) return 0; | 616 if (this == other) return 0; |
| 612 return '${script.readableUri}'.compareTo('${other.script.readableUri}'); | 617 return '${script.readableUri}'.compareTo('${other.script.readableUri}'); |
| 613 } | 618 } |
| 614 | 619 |
| 620 Element get analyzableElement => library; |
| 621 |
| 615 accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this); | 622 accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this); |
| 616 } | 623 } |
| 617 | 624 |
| 618 class Importers { | 625 class Importers { |
| 619 Map<Element, Link<Import>> importers = new Map<Element, Link<Import>>(); | 626 Map<Element, Link<Import>> importers = new Map<Element, Link<Import>>(); |
| 620 | 627 |
| 621 Link<Import> getImports(Element element) { | 628 Link<Import> getImports(Element element) { |
| 622 Link<Import> imports = importers[element]; | 629 Link<Import> imports = importers[element]; |
| 623 return imports != null ? imports : const Link<Import>(); | 630 return imports != null ? imports : const Link<Import>(); |
| 624 } | 631 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 importers.registerImport(ambiguousElement, import); | 723 importers.registerImport(ambiguousElement, import); |
| 717 importers.registerImport(ambiguousElement, existingImport); | 724 importers.registerImport(ambiguousElement, existingImport); |
| 718 } | 725 } |
| 719 } | 726 } |
| 720 } | 727 } |
| 721 | 728 |
| 722 Element operator [](String name) => importScope[name]; | 729 Element operator [](String name) => importScope[name]; |
| 723 } | 730 } |
| 724 | 731 |
| 725 class LibraryElementX | 732 class LibraryElementX |
| 726 extends ElementX with AnalyzableElement, PatchMixin<LibraryElementX> | 733 extends ElementX with AnalyzableElementX, PatchMixin<LibraryElementX> |
| 727 implements LibraryElement { | 734 implements LibraryElement { |
| 728 final Uri canonicalUri; | 735 final Uri canonicalUri; |
| 729 CompilationUnitElement entryCompilationUnit; | 736 CompilationUnitElement entryCompilationUnit; |
| 730 Link<CompilationUnitElement> compilationUnits = | 737 Link<CompilationUnitElement> compilationUnits = |
| 731 const Link<CompilationUnitElement>(); | 738 const Link<CompilationUnitElement>(); |
| 732 Link<LibraryTag> tags = const Link<LibraryTag>(); | 739 Link<LibraryTag> tags = const Link<LibraryTag>(); |
| 733 LibraryName libraryTag; | 740 LibraryName libraryTag; |
| 734 bool canUseNative = false; | 741 bool canUseNative = false; |
| 735 Link<Element> localMembers = const Link<Element>(); | 742 Link<Element> localMembers = const Link<Element>(); |
| 736 final ScopeX localScope = new ScopeX(); | 743 final ScopeX localScope = new ScopeX(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 767 return (libraryTag == null) ? super.metadata : libraryTag.metadata; | 774 return (libraryTag == null) ? super.metadata : libraryTag.metadata; |
| 768 } | 775 } |
| 769 | 776 |
| 770 set metadata(value) { | 777 set metadata(value) { |
| 771 // The metadata is stored on [libraryTag]. | 778 // The metadata is stored on [libraryTag]. |
| 772 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library'); | 779 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library'); |
| 773 } | 780 } |
| 774 | 781 |
| 775 CompilationUnitElement get compilationUnit => entryCompilationUnit; | 782 CompilationUnitElement get compilationUnit => entryCompilationUnit; |
| 776 | 783 |
| 784 Element get analyzableElement => this; |
| 785 |
| 777 void addCompilationUnit(CompilationUnitElement element) { | 786 void addCompilationUnit(CompilationUnitElement element) { |
| 778 compilationUnits = compilationUnits.prepend(element); | 787 compilationUnits = compilationUnits.prepend(element); |
| 779 } | 788 } |
| 780 | 789 |
| 781 void addTag(LibraryTag tag, DiagnosticListener listener) { | 790 void addTag(LibraryTag tag, DiagnosticListener listener) { |
| 782 tags = tags.prepend(tag); | 791 tags = tags.prepend(tag); |
| 783 } | 792 } |
| 784 | 793 |
| 785 void recordResolvedTag(LibraryDependency tag, LibraryElement library) { | 794 void recordResolvedTag(LibraryDependency tag, LibraryElement library) { |
| 786 assert(tagMapping[tag] == null); | 795 assert(tagMapping[tag] == null); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1001 } | 1010 } |
| 1002 | 1011 |
| 1003 accept(ElementVisitor visitor) => visitor.visitPrefixElement(this); | 1012 accept(ElementVisitor visitor) => visitor.visitPrefixElement(this); |
| 1004 | 1013 |
| 1005 void markAsDeferred(Import deferredImport) { | 1014 void markAsDeferred(Import deferredImport) { |
| 1006 _deferredImport = deferredImport; | 1015 _deferredImport = deferredImport; |
| 1007 } | 1016 } |
| 1008 } | 1017 } |
| 1009 | 1018 |
| 1010 class TypedefElementX extends ElementX | 1019 class TypedefElementX extends ElementX |
| 1011 with AnalyzableElement, TypeDeclarationElementX<TypedefType> | 1020 with AnalyzableElementX, TypeDeclarationElementX<TypedefType> |
| 1012 implements TypedefElement { | 1021 implements TypedefElement { |
| 1013 Typedef cachedNode; | 1022 Typedef cachedNode; |
| 1014 | 1023 |
| 1015 /** | 1024 /** |
| 1016 * The type annotation which defines this typedef. | 1025 * The type annotation which defines this typedef. |
| 1017 */ | 1026 */ |
| 1018 DartType alias; | 1027 DartType alias; |
| 1019 | 1028 |
| 1020 /// [:true:] if the typedef has been checked for cyclic reference. | 1029 /// [:true:] if the typedef has been checked for cyclic reference. |
| 1021 bool hasBeenCheckedForCycles = false; | 1030 bool hasBeenCheckedForCycles = false; |
| 1022 | 1031 |
| 1023 bool get isResolved => hasTreeElements; | 1032 int resolutionState = STATE_NOT_STARTED; |
| 1024 | 1033 |
| 1025 TypedefElementX(String name, Element enclosing) | 1034 TypedefElementX(String name, Element enclosing) |
| 1026 : super(name, ElementKind.TYPEDEF, enclosing); | 1035 : super(name, ElementKind.TYPEDEF, enclosing); |
| 1027 | 1036 |
| 1028 Typedef get node { | 1037 Typedef get node { |
| 1029 assert(invariant(this, cachedNode != null, | 1038 assert(invariant(this, cachedNode != null, |
| 1030 message: "Node has not been computed for $this.")); | 1039 message: "Node has not been computed for $this.")); |
| 1031 return cachedNode; | 1040 return cachedNode; |
| 1032 } | 1041 } |
| 1033 | 1042 |
| 1034 /** | 1043 /** |
| 1035 * Function signature for a typedef of a function type. The signature is | 1044 * Function signature for a typedef of a function type. The signature is |
| 1036 * kept to provide full information about parameter names through the mirror | 1045 * kept to provide full information about parameter names through the mirror |
| 1037 * system. | 1046 * system. |
| 1038 * | 1047 * |
| 1039 * The [functionSignature] is not available until the typedef element has been | 1048 * The [functionSignature] is not available until the typedef element has been |
| 1040 * resolved. | 1049 * resolved. |
| 1041 */ | 1050 */ |
| 1042 FunctionSignature functionSignature; | 1051 FunctionSignature functionSignature; |
| 1043 | 1052 |
| 1044 TypedefType computeType(Compiler compiler) { | 1053 TypedefType computeType(Compiler compiler) { |
| 1045 if (thisTypeCache != null) return thisTypeCache; | 1054 if (thisTypeCache != null) return thisTypeCache; |
| 1046 Typedef node = parseNode(compiler); | 1055 Typedef node = parseNode(compiler); |
| 1047 setThisAndRawTypes(compiler, createTypeVariables(node.typeParameters)); | 1056 setThisAndRawTypes(compiler, createTypeVariables(node.typeParameters)); |
| 1048 compiler.resolveTypedef(this); | 1057 ensureResolved(compiler); |
| 1049 return thisTypeCache; | 1058 return thisTypeCache; |
| 1050 } | 1059 } |
| 1051 | 1060 |
| 1061 void ensureResolved(Compiler compiler) { |
| 1062 if (resolutionState == STATE_NOT_STARTED) { |
| 1063 compiler.resolver.resolve(this); |
| 1064 } |
| 1065 } |
| 1066 |
| 1052 TypedefType createType(Link<DartType> typeArguments) { | 1067 TypedefType createType(Link<DartType> typeArguments) { |
| 1053 return new TypedefType(this, typeArguments); | 1068 return new TypedefType(this, typeArguments); |
| 1054 } | 1069 } |
| 1055 | 1070 |
| 1056 Scope buildScope() { | 1071 Scope buildScope() { |
| 1057 return new TypeDeclarationScope(enclosingElement.buildScope(), this); | 1072 return new TypeDeclarationScope(enclosingElement.buildScope(), this); |
| 1058 } | 1073 } |
| 1059 | 1074 |
| 1060 void checkCyclicReference(Compiler compiler) { | 1075 void checkCyclicReference(Compiler compiler) { |
| 1061 if (hasBeenCheckedForCycles) return; | 1076 if (hasBeenCheckedForCycles) return; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1084 assert(modifiers != null); | 1099 assert(modifiers != null); |
| 1085 } | 1100 } |
| 1086 | 1101 |
| 1087 VariableDefinitions parseNode(Element element, DiagnosticListener listener) { | 1102 VariableDefinitions parseNode(Element element, DiagnosticListener listener) { |
| 1088 return definitions; | 1103 return definitions; |
| 1089 } | 1104 } |
| 1090 | 1105 |
| 1091 DartType computeType(Element element, Compiler compiler) => type; | 1106 DartType computeType(Element element, Compiler compiler) => type; |
| 1092 } | 1107 } |
| 1093 | 1108 |
| 1094 class VariableElementX extends ElementX with AnalyzableElement | 1109 class VariableElementX extends ElementX with AnalyzableElementX |
| 1095 implements VariableElement { | 1110 implements VariableElement { |
| 1096 final Token token; | 1111 final Token token; |
| 1097 final VariableList variables; | 1112 final VariableList variables; |
| 1098 VariableDefinitions definitionsCache; | 1113 VariableDefinitions definitionsCache; |
| 1099 Expression initializerCache; | 1114 Expression initializerCache; |
| 1100 | 1115 |
| 1101 Modifiers get modifiers => variables.modifiers; | 1116 Modifiers get modifiers => variables.modifiers; |
| 1102 | 1117 |
| 1103 VariableElementX(String name, | 1118 VariableElementX(String name, |
| 1104 ElementKind kind, | 1119 ElementKind kind, |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1440 // by call sites of a call to a method with the other signature. | 1455 // by call sites of a call to a method with the other signature. |
| 1441 int otherTotalCount = signature.parameterCount; | 1456 int otherTotalCount = signature.parameterCount; |
| 1442 return requiredParameterCount <= otherTotalCount | 1457 return requiredParameterCount <= otherTotalCount |
| 1443 && parameterCount >= otherTotalCount; | 1458 && parameterCount >= otherTotalCount; |
| 1444 } | 1459 } |
| 1445 return true; | 1460 return true; |
| 1446 } | 1461 } |
| 1447 } | 1462 } |
| 1448 | 1463 |
| 1449 abstract class FunctionElementX | 1464 abstract class FunctionElementX |
| 1450 extends ElementX with AnalyzableElement, PatchMixin<FunctionElement> | 1465 extends ElementX with AnalyzableElementX, PatchMixin<FunctionElement> |
| 1451 implements FunctionElement { | 1466 implements FunctionElement { |
| 1452 DartType typeCache; | 1467 DartType typeCache; |
| 1453 final Modifiers modifiers; | 1468 final Modifiers modifiers; |
| 1454 | 1469 |
| 1455 List<FunctionElement> nestedClosures = new List<FunctionElement>(); | 1470 List<FunctionElement> nestedClosures = new List<FunctionElement>(); |
| 1456 | 1471 |
| 1457 FunctionSignature functionSignatureCache; | 1472 FunctionSignature functionSignatureCache; |
| 1458 | 1473 |
| 1459 final bool _hasNoBody; | 1474 final bool _hasNoBody; |
| 1460 | 1475 |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1802 TypeVariable node = link.head; | 1817 TypeVariable node = link.head; |
| 1803 String variableName = node.name.source; | 1818 String variableName = node.name.source; |
| 1804 TypeVariableElementX variableElement = | 1819 TypeVariableElementX variableElement = |
| 1805 new TypeVariableElementX(variableName, this, node); | 1820 new TypeVariableElementX(variableName, this, node); |
| 1806 TypeVariableType variableType = new TypeVariableType(variableElement); | 1821 TypeVariableType variableType = new TypeVariableType(variableElement); |
| 1807 variableElement.typeCache = variableType; | 1822 variableElement.typeCache = variableType; |
| 1808 arguments.addLast(variableType); | 1823 arguments.addLast(variableType); |
| 1809 } | 1824 } |
| 1810 return arguments.toLink(); | 1825 return arguments.toLink(); |
| 1811 } | 1826 } |
| 1827 |
| 1828 bool get isResolved => resolutionState == STATE_DONE; |
| 1812 } | 1829 } |
| 1813 | 1830 |
| 1814 abstract class BaseClassElementX extends ElementX | 1831 abstract class BaseClassElementX extends ElementX |
| 1815 with AnalyzableElement, | 1832 with AnalyzableElementX, |
| 1816 TypeDeclarationElementX<InterfaceType>, | 1833 TypeDeclarationElementX<InterfaceType>, |
| 1817 PatchMixin<ClassElement>, | 1834 PatchMixin<ClassElement>, |
| 1818 ClassMemberMixin | 1835 ClassMemberMixin |
| 1819 implements ClassElement { | 1836 implements ClassElement { |
| 1820 final int id; | 1837 final int id; |
| 1821 | 1838 |
| 1822 DartType supertype; | 1839 DartType supertype; |
| 1823 Link<DartType> interfaces; | 1840 Link<DartType> interfaces; |
| 1824 String nativeTagInfo; | 1841 String nativeTagInfo; |
| 1825 int supertypeLoadState; | 1842 int supertypeLoadState; |
| 1826 int resolutionState; | 1843 int resolutionState; |
| 1827 bool get isResolved => resolutionState == STATE_DONE; | |
| 1828 bool isProxy = false; | 1844 bool isProxy = false; |
| 1829 bool hasIncompleteHierarchy = false; | 1845 bool hasIncompleteHierarchy = false; |
| 1830 | 1846 |
| 1831 // backendMembers are members that have been added by the backend to simplify | 1847 // backendMembers are members that have been added by the backend to simplify |
| 1832 // compilation. They don't have any user-side counter-part. | 1848 // compilation. They don't have any user-side counter-part. |
| 1833 Link<Element> backendMembers = const Link<Element>(); | 1849 Link<Element> backendMembers = const Link<Element>(); |
| 1834 | 1850 |
| 1835 OrderedTypeSet allSupertypesAndSelf; | 1851 OrderedTypeSet allSupertypesAndSelf; |
| 1836 | 1852 |
| 1837 Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes; | 1853 Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes; |
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2546 assert(invariant(this, this.origin == null, | 2562 assert(invariant(this, this.origin == null, |
| 2547 message: "Origin element is a patch.")); | 2563 message: "Origin element is a patch.")); |
| 2548 assert(invariant(patch, patch.origin == null, | 2564 assert(invariant(patch, patch.origin == null, |
| 2549 message: "Element is patched twice.")); | 2565 message: "Element is patched twice.")); |
| 2550 assert(invariant(patch, patch.patch == null, | 2566 assert(invariant(patch, patch.patch == null, |
| 2551 message: "Patch element is patched.")); | 2567 message: "Patch element is patched.")); |
| 2552 this.patch = patch; | 2568 this.patch = patch; |
| 2553 patch.origin = this; | 2569 patch.origin = this; |
| 2554 } | 2570 } |
| 2555 } | 2571 } |
| OLD | NEW |