| 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 '../tree/tree.dart'; | 9 import '../tree/tree.dart'; |
| 9 import '../util/util.dart'; | 10 import '../util/util.dart'; |
| 10 import '../resolution/resolution.dart'; | 11 import '../resolution/resolution.dart'; |
| 11 import '../resolution/class_members.dart' show ClassMemberMixin; | 12 import '../resolution/class_members.dart' show ClassMemberMixin; |
| 12 | 13 |
| 13 import '../dart2jslib.dart' show invariant, | 14 import '../dart2jslib.dart' show invariant, |
| 14 InterfaceType, | 15 InterfaceType, |
| 15 DartType, | 16 DartType, |
| 16 TypeVariableType, | 17 TypeVariableType, |
| 17 TypedefType, | 18 TypedefType, |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 | 104 |
| 104 /** See [ErroneousElement] for documentation. */ | 105 /** See [ErroneousElement] for documentation. */ |
| 105 bool isErroneous() => false; | 106 bool isErroneous() => false; |
| 106 | 107 |
| 107 /** See [AmbiguousElement] for documentation. */ | 108 /** See [AmbiguousElement] for documentation. */ |
| 108 bool isAmbiguous() => false; | 109 bool isAmbiguous() => false; |
| 109 | 110 |
| 110 /** See [WarnOnUseElement] for documentation. */ | 111 /** See [WarnOnUseElement] for documentation. */ |
| 111 bool isWarnOnUse() => false; | 112 bool isWarnOnUse() => false; |
| 112 | 113 |
| 113 /** | |
| 114 * Is [:true:] if this element has a corresponding patch. | |
| 115 * | |
| 116 * If [:true:] this element has a non-null [patch] field. | |
| 117 * | |
| 118 * See [:patch_parser.dart:] for a description of the terminology. | |
| 119 */ | |
| 120 bool get isPatched => false; | 114 bool get isPatched => false; |
| 121 | 115 |
| 122 /** | |
| 123 * Is [:true:] if this element is a patch. | |
| 124 * | |
| 125 * If [:true:] this element has a non-null [origin] field. | |
| 126 * | |
| 127 * See [:patch_parser.dart:] for a description of the terminology. | |
| 128 */ | |
| 129 bool get isPatch => false; | 116 bool get isPatch => false; |
| 130 | 117 |
| 131 /** | 118 bool get isImplementation => true; |
| 132 * Is [:true:] if this element defines the implementation for the entity of | |
| 133 * this element. | |
| 134 * | |
| 135 * See [:patch_parser.dart:] for a description of the terminology. | |
| 136 */ | |
| 137 bool get isImplementation => !isPatched; | |
| 138 | 119 |
| 139 /** | 120 bool get isDeclaration => true; |
| 140 * Is [:true:] if this element introduces the entity of this element. | |
| 141 * | |
| 142 * See [:patch_parser.dart:] for a description of the terminology. | |
| 143 */ | |
| 144 bool get isDeclaration => !isPatch; | |
| 145 | 121 |
| 146 bool get isSynthesized => false; | 122 Element get implementation => this; |
| 147 | 123 |
| 148 bool get isForwardingConstructor => false; | 124 Element get declaration => this; |
| 149 | |
| 150 bool get isMixinApplication => false; | |
| 151 | |
| 152 /** | |
| 153 * Returns the element which defines the implementation for the entity of this | |
| 154 * element. | |
| 155 * | |
| 156 * See [:patch_parser.dart:] for a description of the terminology. | |
| 157 */ | |
| 158 Element get implementation => isPatched ? patch : this; | |
| 159 | |
| 160 /** | |
| 161 * Returns the element which introduces the entity of this element. | |
| 162 * | |
| 163 * See [:patch_parser.dart:] for a description of the terminology. | |
| 164 */ | |
| 165 Element get declaration => isPatch ? origin : this; | |
| 166 | 125 |
| 167 Element get patch { | 126 Element get patch { |
| 168 throw new UnsupportedError('patch is not supported on $this'); | 127 throw new UnsupportedError('patch is not supported on $this'); |
| 169 } | 128 } |
| 170 | 129 |
| 171 Element get origin { | 130 Element get origin { |
| 172 throw new UnsupportedError('origin is not supported on $this'); | 131 throw new UnsupportedError('origin is not supported on $this'); |
| 173 } | 132 } |
| 174 | 133 |
| 134 bool get isSynthesized => false; |
| 135 |
| 136 bool get isForwardingConstructor => false; |
| 137 |
| 138 bool get isMixinApplication => false; |
| 139 |
| 175 // TODO(johnniwinther): This breaks for libraries (for which enclosing | 140 // TODO(johnniwinther): This breaks for libraries (for which enclosing |
| 176 // elements are null) and is invalid for top level variable declarations for | 141 // elements are null) and is invalid for top level variable declarations for |
| 177 // which the enclosing element is a VariableDeclarations and not a compilation | 142 // which the enclosing element is a VariableDeclarations and not a compilation |
| 178 // unit. | 143 // unit. |
| 179 bool isTopLevel() { | 144 bool isTopLevel() { |
| 180 return enclosingElement != null && enclosingElement.isCompilationUnit(); | 145 return enclosingElement != null && enclosingElement.isCompilationUnit(); |
| 181 } | 146 } |
| 182 | 147 |
| 183 bool isAssignable() { | 148 bool isAssignable() { |
| 184 if (modifiers.isFinalOrConst()) return false; | 149 if (modifiers.isFinalOrConst()) return false; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 get type => unsupported(); | 308 get type => unsupported(); |
| 344 get cachedNode => unsupported(); | 309 get cachedNode => unsupported(); |
| 345 get functionSignature => unsupported(); | 310 get functionSignature => unsupported(); |
| 346 get patch => null; | 311 get patch => null; |
| 347 get origin => this; | 312 get origin => this; |
| 348 get defaultImplementation => unsupported(); | 313 get defaultImplementation => unsupported(); |
| 349 get nestedClosures => unsupported(); | 314 get nestedClosures => unsupported(); |
| 350 | 315 |
| 351 bool get isRedirectingFactory => unsupported(); | 316 bool get isRedirectingFactory => unsupported(); |
| 352 | 317 |
| 353 setPatch(patch) => unsupported(); | |
| 354 computeSignature(compiler) => unsupported(); | 318 computeSignature(compiler) => unsupported(); |
| 355 requiredParameterCount(compiler) => unsupported(); | |
| 356 optionalParameterCount(compiler) => unsupported(); | |
| 357 parameterCount(compiler) => unsupported(); | |
| 358 | 319 |
| 359 // TODO(kasperl): These seem unnecessary. | 320 // TODO(kasperl): These seem unnecessary. |
| 360 set patch(value) => unsupported(); | |
| 361 set origin(value) => unsupported(); | |
| 362 set defaultImplementation(value) => unsupported(); | 321 set defaultImplementation(value) => unsupported(); |
| 363 | 322 |
| 364 get redirectionTarget => this; | 323 get redirectionTarget => this; |
| 365 | 324 |
| 366 getLibrary() => enclosingElement.getLibrary(); | 325 getLibrary() => enclosingElement.getLibrary(); |
| 367 | 326 |
| 368 computeTargetType(InterfaceType newType) => unsupported(); | 327 computeTargetType(InterfaceType newType) => unsupported(); |
| 369 | 328 |
| 370 String get message => '${messageKind.message(messageArguments)}'; | 329 String get message => '${messageKind.message(messageArguments)}'; |
| 371 | 330 |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 importScope[name] = ambiguousElement; | 721 importScope[name] = ambiguousElement; |
| 763 importers.registerImport(ambiguousElement, import); | 722 importers.registerImport(ambiguousElement, import); |
| 764 importers.registerImport(ambiguousElement, existingImport); | 723 importers.registerImport(ambiguousElement, existingImport); |
| 765 } | 724 } |
| 766 } | 725 } |
| 767 } | 726 } |
| 768 | 727 |
| 769 Element operator [](String name) => importScope[name]; | 728 Element operator [](String name) => importScope[name]; |
| 770 } | 729 } |
| 771 | 730 |
| 772 class LibraryElementX extends ElementX with AnalyzableElement | 731 class LibraryElementX |
| 732 extends ElementX with AnalyzableElement, PatchMixin<LibraryElementX> |
| 773 implements LibraryElement { | 733 implements LibraryElement { |
| 774 final Uri canonicalUri; | 734 final Uri canonicalUri; |
| 775 CompilationUnitElement entryCompilationUnit; | 735 CompilationUnitElement entryCompilationUnit; |
| 776 Link<CompilationUnitElement> compilationUnits = | 736 Link<CompilationUnitElement> compilationUnits = |
| 777 const Link<CompilationUnitElement>(); | 737 const Link<CompilationUnitElement>(); |
| 778 Link<LibraryTag> tags = const Link<LibraryTag>(); | 738 Link<LibraryTag> tags = const Link<LibraryTag>(); |
| 779 LibraryName libraryTag; | 739 LibraryName libraryTag; |
| 780 bool canUseNative = false; | 740 bool canUseNative = false; |
| 781 Link<Element> localMembers = const Link<Element>(); | 741 Link<Element> localMembers = const Link<Element>(); |
| 782 final ScopeX localScope = new ScopeX(); | 742 final ScopeX localScope = new ScopeX(); |
| 783 final ImportScope importScope = new ImportScope(); | 743 final ImportScope importScope = new ImportScope(); |
| 784 | 744 |
| 785 /** | |
| 786 * If this library is patched, [patch] points to the patch library. | |
| 787 * | |
| 788 * See [:patch_parser.dart:] for a description of the terminology. | |
| 789 */ | |
| 790 LibraryElementX patch = null; | |
| 791 | |
| 792 /** | |
| 793 * If this is a patch library, [origin] points to the origin library. | |
| 794 * | |
| 795 * See [:patch_parser.dart:] for a description of the terminology. | |
| 796 */ | |
| 797 final LibraryElementX origin; | |
| 798 | |
| 799 /// A mapping from an imported element to the "import" tag. | 745 /// A mapping from an imported element to the "import" tag. |
| 800 final Importers importers = new Importers(); | 746 final Importers importers = new Importers(); |
| 801 | 747 |
| 802 /** | 748 /** |
| 803 * Link for elements exported either through export declarations or through | 749 * Link for elements exported either through export declarations or through |
| 804 * declaration. This field should not be accessed directly but instead through | 750 * declaration. This field should not be accessed directly but instead through |
| 805 * the [exports] getter. | 751 * the [exports] getter. |
| 806 * | 752 * |
| 807 * [LibraryDependencyHandler] sets this field through [setExports] when the | 753 * [LibraryDependencyHandler] sets this field through [setExports] when the |
| 808 * library is loaded. | 754 * library is loaded. |
| 809 */ | 755 */ |
| 810 Link<Element> slotForExports; | 756 Link<Element> slotForExports; |
| 811 | 757 |
| 812 final Map<LibraryDependency, LibraryElement> tagMapping = | 758 final Map<LibraryDependency, LibraryElement> tagMapping = |
| 813 new Map<LibraryDependency, LibraryElement>(); | 759 new Map<LibraryDependency, LibraryElement>(); |
| 814 | 760 |
| 815 LibraryElementX(Script script, [Uri canonicalUri, LibraryElement this.origin]) | 761 LibraryElementX(Script script, |
| 762 [Uri canonicalUri, LibraryElementX origin]) |
| 816 : this.canonicalUri = | 763 : this.canonicalUri = |
| 817 ((canonicalUri == null) ? script.readableUri : canonicalUri), | 764 ((canonicalUri == null) ? script.readableUri : canonicalUri), |
| 818 super(script.name, ElementKind.LIBRARY, null) { | 765 super(script.name, ElementKind.LIBRARY, null) { |
| 819 entryCompilationUnit = new CompilationUnitElementX(script, this); | 766 entryCompilationUnit = new CompilationUnitElementX(script, this); |
| 820 if (isPatch) { | 767 if (origin != null) { |
| 821 origin.patch = this; | 768 origin.applyPatch(this); |
| 822 } | 769 } |
| 823 } | 770 } |
| 824 | 771 |
| 825 bool get isPatched => patch != null; | |
| 826 bool get isPatch => origin != null; | |
| 827 | |
| 828 LibraryElement get declaration => super.declaration; | |
| 829 LibraryElement get implementation => super.implementation; | |
| 830 | |
| 831 Link<MetadataAnnotation> get metadata { | 772 Link<MetadataAnnotation> get metadata { |
| 832 return (libraryTag == null) ? super.metadata : libraryTag.metadata; | 773 return (libraryTag == null) ? super.metadata : libraryTag.metadata; |
| 833 } | 774 } |
| 834 | 775 |
| 835 set metadata(value) { | 776 set metadata(value) { |
| 836 // The metadata is stored on [libraryTag]. | 777 // The metadata is stored on [libraryTag]. |
| 837 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library'); | 778 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library'); |
| 838 } | 779 } |
| 839 | 780 |
| 840 CompilationUnitElement getCompilationUnit() => entryCompilationUnit; | 781 CompilationUnitElement getCompilationUnit() => entryCompilationUnit; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 851 assert(tagMapping[tag] == null); | 792 assert(tagMapping[tag] == null); |
| 852 tagMapping[tag] = library; | 793 tagMapping[tag] = library; |
| 853 } | 794 } |
| 854 | 795 |
| 855 LibraryElement getLibraryFromTag(LibraryDependency tag) => tagMapping[tag]; | 796 LibraryElement getLibraryFromTag(LibraryDependency tag) => tagMapping[tag]; |
| 856 | 797 |
| 857 /** | 798 /** |
| 858 * Adds [element] to the import scope of this library. | 799 * Adds [element] to the import scope of this library. |
| 859 * | 800 * |
| 860 * If an element by the same name is already in the imported scope, an | 801 * If an element by the same name is already in the imported scope, an |
| 861 * [ErroneousElement] will be put in the imported scope, allowing for detectio
n of ambiguous uses of imported names. | 802 * [ErroneousElement] will be put in the imported scope, allowing for |
| 803 * detection of ambiguous uses of imported names. |
| 862 */ | 804 */ |
| 863 void addImport(Element element, Import import, DiagnosticListener listener) { | 805 void addImport(Element element, Import import, DiagnosticListener listener) { |
| 864 importScope.addImport(this, element, import, listener); | 806 importScope.addImport(this, element, import, listener); |
| 865 } | 807 } |
| 866 | 808 |
| 867 void addMember(Element element, DiagnosticListener listener) { | 809 void addMember(Element element, DiagnosticListener listener) { |
| 868 localMembers = localMembers.prepend(element); | 810 localMembers = localMembers.prepend(element); |
| 869 addToScope(element, listener); | 811 addToScope(element, listener); |
| 870 } | 812 } |
| 871 | 813 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 return 'library(${getLibraryOrScriptName()})'; | 969 return 'library(${getLibraryOrScriptName()})'; |
| 1028 } | 970 } |
| 1029 } | 971 } |
| 1030 | 972 |
| 1031 int compareTo(LibraryElement other) { | 973 int compareTo(LibraryElement other) { |
| 1032 if (this == other) return 0; | 974 if (this == other) return 0; |
| 1033 return getLibraryOrScriptName().compareTo(other.getLibraryOrScriptName()); | 975 return getLibraryOrScriptName().compareTo(other.getLibraryOrScriptName()); |
| 1034 } | 976 } |
| 1035 | 977 |
| 1036 accept(ElementVisitor visitor) => visitor.visitLibraryElement(this); | 978 accept(ElementVisitor visitor) => visitor.visitLibraryElement(this); |
| 979 |
| 980 // TODO(johnniwinther): Remove these when issue 18630 is fixed. |
| 981 LibraryElementX get patch => super.patch; |
| 982 LibraryElementX get origin => super.origin; |
| 1037 } | 983 } |
| 1038 | 984 |
| 1039 class PrefixElementX extends ElementX implements PrefixElement { | 985 class PrefixElementX extends ElementX implements PrefixElement { |
| 1040 Token firstPosition; | 986 Token firstPosition; |
| 1041 | 987 |
| 1042 final ImportScope importScope = new ImportScope(); | 988 final ImportScope importScope = new ImportScope(); |
| 1043 | 989 |
| 1044 bool get isDeferred => _deferredImport != null; | 990 bool get isDeferred => _deferredImport != null; |
| 1045 | 991 |
| 1046 // Only needed for deferred imports. | 992 // Only needed for deferred imports. |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1277 | 1223 |
| 1278 accept(ElementVisitor visitor) => visitor.visitFieldParameterElement(this); | 1224 accept(ElementVisitor visitor) => visitor.visitFieldParameterElement(this); |
| 1279 } | 1225 } |
| 1280 | 1226 |
| 1281 /// [Element] for a formal parameter. | 1227 /// [Element] for a formal parameter. |
| 1282 /// | 1228 /// |
| 1283 /// A [ParameterElementX] can be patched. A parameter of an external method is | 1229 /// A [ParameterElementX] can be patched. A parameter of an external method is |
| 1284 /// patched with the corresponding parameter of the patch method. This is done | 1230 /// patched with the corresponding parameter of the patch method. This is done |
| 1285 /// to ensure that default values on parameters are computed once (on the | 1231 /// to ensure that default values on parameters are computed once (on the |
| 1286 /// origin parameter) but can be found through both the origin and the patch. | 1232 /// origin parameter) but can be found through both the origin and the patch. |
| 1287 class ParameterElementX extends ElementX implements ParameterElement { | 1233 class ParameterElementX extends ElementX with PatchMixin<ParameterElement> |
| 1234 implements ParameterElement { |
| 1288 final VariableDefinitions definitions; | 1235 final VariableDefinitions definitions; |
| 1289 final Identifier identifier; | 1236 final Identifier identifier; |
| 1290 final Expression initializer; | 1237 final Expression initializer; |
| 1291 DartType typeCache; | 1238 DartType typeCache; |
| 1292 | 1239 |
| 1293 /** | 1240 /** |
| 1294 * Function signature for a variable with a function type. The signature is | 1241 * Function signature for a variable with a function type. The signature is |
| 1295 * kept to provide full information about parameter names through the mirror | 1242 * kept to provide full information about parameter names through the mirror |
| 1296 * system. | 1243 * system. |
| 1297 */ | 1244 */ |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1327 assert(invariant(this, typeCache != null, | 1274 assert(invariant(this, typeCache != null, |
| 1328 message: "Parameter signature has not been set for $this.")); | 1275 message: "Parameter signature has not been set for $this.")); |
| 1329 return functionSignatureCache; | 1276 return functionSignatureCache; |
| 1330 } | 1277 } |
| 1331 | 1278 |
| 1332 VariableDefinitions get node => definitions; | 1279 VariableDefinitions get node => definitions; |
| 1333 | 1280 |
| 1334 FunctionType get functionType => type; | 1281 FunctionType get functionType => type; |
| 1335 | 1282 |
| 1336 accept(ElementVisitor visitor) => visitor.visitVariableElement(this); | 1283 accept(ElementVisitor visitor) => visitor.visitVariableElement(this); |
| 1337 | |
| 1338 ParameterElementX patch = null; | |
| 1339 ParameterElementX origin = null; | |
| 1340 | |
| 1341 bool get isPatch => origin != null; | |
| 1342 bool get isPatched => patch != null; | |
| 1343 } | 1284 } |
| 1344 | 1285 |
| 1345 class AbstractFieldElementX extends ElementX implements AbstractFieldElement { | 1286 class AbstractFieldElementX extends ElementX implements AbstractFieldElement { |
| 1346 FunctionElement getter; | 1287 FunctionElement getter; |
| 1347 FunctionElement setter; | 1288 FunctionElement setter; |
| 1348 | 1289 |
| 1349 AbstractFieldElementX(String name, Element enclosing) | 1290 AbstractFieldElementX(String name, Element enclosing) |
| 1350 : super(name, ElementKind.ABSTRACT_FIELD, enclosing); | 1291 : super(name, ElementKind.ABSTRACT_FIELD, enclosing); |
| 1351 | 1292 |
| 1352 DartType computeType(Compiler compiler) { | 1293 DartType computeType(Compiler compiler) { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 // optional parameters is not a problem, they simply are never provided | 1420 // optional parameters is not a problem, they simply are never provided |
| 1480 // by call sites of a call to a method with the other signature. | 1421 // by call sites of a call to a method with the other signature. |
| 1481 int otherTotalCount = signature.parameterCount; | 1422 int otherTotalCount = signature.parameterCount; |
| 1482 return requiredParameterCount <= otherTotalCount | 1423 return requiredParameterCount <= otherTotalCount |
| 1483 && parameterCount >= otherTotalCount; | 1424 && parameterCount >= otherTotalCount; |
| 1484 } | 1425 } |
| 1485 return true; | 1426 return true; |
| 1486 } | 1427 } |
| 1487 } | 1428 } |
| 1488 | 1429 |
| 1489 class FunctionElementX extends ElementX with AnalyzableElement | 1430 class FunctionElementX |
| 1431 extends ElementX with AnalyzableElement, PatchMixin<FunctionElement> |
| 1490 implements FunctionElement { | 1432 implements FunctionElement { |
| 1491 FunctionExpression cachedNode; | 1433 FunctionExpression cachedNode; |
| 1492 DartType typeCache; | 1434 DartType typeCache; |
| 1493 final Modifiers modifiers; | 1435 final Modifiers modifiers; |
| 1494 | 1436 |
| 1495 List<FunctionElement> nestedClosures = new List<FunctionElement>(); | 1437 List<FunctionElement> nestedClosures = new List<FunctionElement>(); |
| 1496 | 1438 |
| 1497 FunctionSignature functionSignatureCache; | 1439 FunctionSignature functionSignatureCache; |
| 1498 | 1440 |
| 1499 /** | |
| 1500 * A function declaration that should be parsed instead of the current one. | |
| 1501 * The patch should be parsed as if it was in the current scope. Its | |
| 1502 * signature must match this function's signature. | |
| 1503 */ | |
| 1504 FunctionElement patch = null; | |
| 1505 FunctionElement origin = null; | |
| 1506 | |
| 1507 final bool _hasNoBody; | 1441 final bool _hasNoBody; |
| 1508 | 1442 |
| 1509 AbstractFieldElement abstractField; | 1443 AbstractFieldElement abstractField; |
| 1510 | 1444 |
| 1511 /** | 1445 /** |
| 1512 * If this is a redirecting factory, [defaultImplementation] will be | 1446 * If this is a redirecting factory, [defaultImplementation] will be |
| 1513 * changed by the resolver to point to the redirection target. | 1447 * changed by the resolver to point to the redirection target. |
| 1514 * Otherwise, [:identical(defaultImplementation, this):]. | 1448 * Otherwise, [:identical(defaultImplementation, this):]. |
| 1515 */ | 1449 */ |
| 1516 // TODO(ahe): Rename this field to redirectionTarget. | 1450 // TODO(ahe): Rename this field to redirectionTarget. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1538 this.modifiers, | 1472 this.modifiers, |
| 1539 Element enclosing, | 1473 Element enclosing, |
| 1540 this.functionSignatureCache, | 1474 this.functionSignatureCache, |
| 1541 bool hasNoBody) | 1475 bool hasNoBody) |
| 1542 : super(name, kind, enclosing), | 1476 : super(name, kind, enclosing), |
| 1543 _hasNoBody = hasNoBody { | 1477 _hasNoBody = hasNoBody { |
| 1544 assert(modifiers != null); | 1478 assert(modifiers != null); |
| 1545 defaultImplementation = this; | 1479 defaultImplementation = this; |
| 1546 } | 1480 } |
| 1547 | 1481 |
| 1548 bool get isPatched => patch != null; | |
| 1549 bool get isPatch => origin != null; | |
| 1550 | |
| 1551 bool get isRedirectingFactory => defaultImplementation != this; | 1482 bool get isRedirectingFactory => defaultImplementation != this; |
| 1552 | 1483 |
| 1553 /// This field is set by the post process queue when checking for cycles. | 1484 /// This field is set by the post process queue when checking for cycles. |
| 1554 FunctionElement internalRedirectionTarget; | 1485 FunctionElement internalRedirectionTarget; |
| 1555 DartType redirectionTargetType; | 1486 DartType redirectionTargetType; |
| 1556 | 1487 |
| 1557 set redirectionTarget(FunctionElement constructor) { | 1488 set redirectionTarget(FunctionElement constructor) { |
| 1558 assert(constructor != null && internalRedirectionTarget == null); | 1489 assert(constructor != null && internalRedirectionTarget == null); |
| 1559 internalRedirectionTarget = constructor; | 1490 internalRedirectionTarget = constructor; |
| 1560 } | 1491 } |
| 1561 | 1492 |
| 1562 FunctionElement get redirectionTarget { | 1493 FunctionElement get redirectionTarget { |
| 1563 if (Elements.isErroneousElement(defaultImplementation)) { | 1494 if (Elements.isErroneousElement(defaultImplementation)) { |
| 1564 return defaultImplementation; | 1495 return defaultImplementation; |
| 1565 } | 1496 } |
| 1566 assert(!isRedirectingFactory || internalRedirectionTarget != null); | 1497 assert(!isRedirectingFactory || internalRedirectionTarget != null); |
| 1567 return isRedirectingFactory ? internalRedirectionTarget : this; | 1498 return isRedirectingFactory ? internalRedirectionTarget : this; |
| 1568 } | 1499 } |
| 1569 | 1500 |
| 1570 InterfaceType computeTargetType(InterfaceType newType) { | 1501 InterfaceType computeTargetType(InterfaceType newType) { |
| 1571 if (!isRedirectingFactory) return newType; | 1502 if (!isRedirectingFactory) return newType; |
| 1572 assert(invariant(this, redirectionTargetType != null, | 1503 assert(invariant(this, redirectionTargetType != null, |
| 1573 message: 'Redirection target type has not yet been computed for ' | 1504 message: 'Redirection target type has not yet been computed for ' |
| 1574 '$this.')); | 1505 '$this.')); |
| 1575 return redirectionTargetType.substByContext(newType); | 1506 return redirectionTargetType.substByContext(newType); |
| 1576 } | 1507 } |
| 1577 | 1508 |
| 1578 /** | |
| 1579 * Applies a patch function to this function. The patch function's body | |
| 1580 * is used as replacement when parsing this function's body. | |
| 1581 * This method must not be called after the function has been parsed, | |
| 1582 * and it must be called at most once. | |
| 1583 */ | |
| 1584 void setPatch(FunctionElement patchElement) { | |
| 1585 // Sanity checks. The caller must check these things before calling. | |
| 1586 assert(patch == null); | |
| 1587 this.patch = patchElement; | |
| 1588 } | |
| 1589 | |
| 1590 bool isInstanceMember() { | 1509 bool isInstanceMember() { |
| 1591 return isMember() | 1510 return isMember() |
| 1592 && !isConstructor() | 1511 && !isConstructor() |
| 1593 && !modifiers.isStatic(); | 1512 && !modifiers.isStatic(); |
| 1594 } | 1513 } |
| 1595 | 1514 |
| 1596 FunctionSignature computeSignature(Compiler compiler) { | 1515 FunctionSignature computeSignature(Compiler compiler) { |
| 1597 if (functionSignatureCache != null) return functionSignatureCache; | 1516 if (functionSignatureCache != null) return functionSignatureCache; |
| 1598 compiler.withCurrentElement(this, () { | 1517 compiler.withCurrentElement(this, () { |
| 1599 functionSignatureCache = compiler.resolveSignature(this); | 1518 functionSignatureCache = compiler.resolveSignature(this); |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1904 variableElement.typeCache = variableType; | 1823 variableElement.typeCache = variableType; |
| 1905 arguments.addLast(variableType); | 1824 arguments.addLast(variableType); |
| 1906 } | 1825 } |
| 1907 return arguments.toLink(); | 1826 return arguments.toLink(); |
| 1908 } | 1827 } |
| 1909 } | 1828 } |
| 1910 | 1829 |
| 1911 abstract class BaseClassElementX extends ElementX | 1830 abstract class BaseClassElementX extends ElementX |
| 1912 with AnalyzableElement, | 1831 with AnalyzableElement, |
| 1913 TypeDeclarationElementX<InterfaceType>, | 1832 TypeDeclarationElementX<InterfaceType>, |
| 1833 PatchMixin<ClassElement>, |
| 1914 ClassMemberMixin | 1834 ClassMemberMixin |
| 1915 implements ClassElement { | 1835 implements ClassElement { |
| 1916 final int id; | 1836 final int id; |
| 1917 | 1837 |
| 1918 DartType supertype; | 1838 DartType supertype; |
| 1919 Link<DartType> interfaces; | 1839 Link<DartType> interfaces; |
| 1920 String nativeTagInfo; | 1840 String nativeTagInfo; |
| 1921 int supertypeLoadState; | 1841 int supertypeLoadState; |
| 1922 int resolutionState; | 1842 int resolutionState; |
| 1923 bool get isResolved => resolutionState == STATE_DONE; | 1843 bool get isResolved => resolutionState == STATE_DONE; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1936 | 1856 |
| 1937 BaseClassElementX(String name, | 1857 BaseClassElementX(String name, |
| 1938 Element enclosing, | 1858 Element enclosing, |
| 1939 this.id, | 1859 this.id, |
| 1940 int initialState) | 1860 int initialState) |
| 1941 : supertypeLoadState = initialState, | 1861 : supertypeLoadState = initialState, |
| 1942 resolutionState = initialState, | 1862 resolutionState = initialState, |
| 1943 super(name, ElementKind.CLASS, enclosing); | 1863 super(name, ElementKind.CLASS, enclosing); |
| 1944 | 1864 |
| 1945 int get hashCode => id; | 1865 int get hashCode => id; |
| 1946 ClassElement get patch => super.patch; | |
| 1947 ClassElement get origin => super.origin; | |
| 1948 ClassElement get declaration => super.declaration; | |
| 1949 ClassElement get implementation => super.implementation; | |
| 1950 | 1866 |
| 1951 bool get hasBackendMembers => !backendMembers.isEmpty; | 1867 bool get hasBackendMembers => !backendMembers.isEmpty; |
| 1952 | 1868 |
| 1953 bool get isUnnamedMixinApplication => false; | 1869 bool get isUnnamedMixinApplication => false; |
| 1954 | 1870 |
| 1955 InterfaceType computeType(Compiler compiler) { | 1871 InterfaceType computeType(Compiler compiler) { |
| 1956 if (thisTypeCache == null) { | 1872 if (thisTypeCache == null) { |
| 1957 computeThisAndRawType(compiler, computeTypeParameters(compiler)); | 1873 computeThisAndRawType(compiler, computeTypeParameters(compiler)); |
| 1958 } | 1874 } |
| 1959 return thisTypeCache; | 1875 return thisTypeCache; |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2290 bool isNative() => nativeTagInfo != null; | 2206 bool isNative() => nativeTagInfo != null; |
| 2291 void setNative(String name) { | 2207 void setNative(String name) { |
| 2292 nativeTagInfo = name; | 2208 nativeTagInfo = name; |
| 2293 } | 2209 } |
| 2294 | 2210 |
| 2295 FunctionType get callType { | 2211 FunctionType get callType { |
| 2296 MemberSignature member = | 2212 MemberSignature member = |
| 2297 lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME)); | 2213 lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME)); |
| 2298 return member != null && member.isMethod ? member.type : null; | 2214 return member != null && member.isMethod ? member.type : null; |
| 2299 } | 2215 } |
| 2216 |
| 2217 // TODO(johnniwinther): Remove these when issue 18630 is fixed. |
| 2218 ClassElement get patch => super.patch; |
| 2219 ClassElement get origin => super.origin; |
| 2300 } | 2220 } |
| 2301 | 2221 |
| 2302 abstract class ClassElementX extends BaseClassElementX { | 2222 abstract class ClassElementX extends BaseClassElementX { |
| 2303 // Lazily applied patch of class members. | |
| 2304 ClassElement patch = null; | |
| 2305 ClassElement origin = null; | |
| 2306 | |
| 2307 Link<Element> localMembers = const Link<Element>(); | 2223 Link<Element> localMembers = const Link<Element>(); |
| 2308 final ScopeX localScope = new ScopeX(); | 2224 final ScopeX localScope = new ScopeX(); |
| 2309 | 2225 |
| 2310 ClassElementX(String name, Element enclosing, int id, int initialState) | 2226 ClassElementX(String name, Element enclosing, int id, int initialState) |
| 2311 : super(name, enclosing, id, initialState); | 2227 : super(name, enclosing, id, initialState); |
| 2312 | 2228 |
| 2313 ClassNode parseNode(Compiler compiler); | 2229 ClassNode parseNode(Compiler compiler); |
| 2314 | 2230 |
| 2315 bool get isMixinApplication => false; | 2231 bool get isMixinApplication => false; |
| 2316 bool get isPatched => patch != null; | |
| 2317 bool get isPatch => origin != null; | |
| 2318 bool get hasLocalScopeMembers => !localScope.isEmpty; | 2232 bool get hasLocalScopeMembers => !localScope.isEmpty; |
| 2319 | 2233 |
| 2320 void addMember(Element element, DiagnosticListener listener) { | 2234 void addMember(Element element, DiagnosticListener listener) { |
| 2321 localMembers = localMembers.prepend(element); | 2235 localMembers = localMembers.prepend(element); |
| 2322 addToScope(element, listener); | 2236 addToScope(element, listener); |
| 2323 } | 2237 } |
| 2324 | 2238 |
| 2325 void addToScope(Element element, DiagnosticListener listener) { | 2239 void addToScope(Element element, DiagnosticListener listener) { |
| 2326 if (element.isField() && element.name == name) { | 2240 if (element.isField() && element.name == name) { |
| 2327 listener.reportError(element, MessageKind.MEMBER_USES_CLASS_NAME); | 2241 listener.reportError(element, MessageKind.MEMBER_USES_CLASS_NAME); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2386 this.node, this.modifiers) | 2300 this.node, this.modifiers) |
| 2387 : super(name, enclosing, id, STATE_NOT_STARTED); | 2301 : super(name, enclosing, id, STATE_NOT_STARTED); |
| 2388 | 2302 |
| 2389 ClassElement get mixin => mixinType != null ? mixinType.element : null; | 2303 ClassElement get mixin => mixinType != null ? mixinType.element : null; |
| 2390 | 2304 |
| 2391 bool get isMixinApplication => true; | 2305 bool get isMixinApplication => true; |
| 2392 bool get isUnnamedMixinApplication => node is! NamedMixinApplication; | 2306 bool get isUnnamedMixinApplication => node is! NamedMixinApplication; |
| 2393 bool get hasConstructor => !constructors.isEmpty; | 2307 bool get hasConstructor => !constructors.isEmpty; |
| 2394 bool get hasLocalScopeMembers => !constructors.isEmpty; | 2308 bool get hasLocalScopeMembers => !constructors.isEmpty; |
| 2395 | 2309 |
| 2396 unsupported(message) { | |
| 2397 throw new UnsupportedError('$message is not supported on $this'); | |
| 2398 } | |
| 2399 | |
| 2400 get patch => null; | 2310 get patch => null; |
| 2401 get origin => null; | 2311 get origin => null; |
| 2402 | 2312 |
| 2403 set patch(value) => unsupported('set patch'); | |
| 2404 set origin(value) => unsupported('set origin'); | |
| 2405 | |
| 2406 Token position() => node.getBeginToken(); | 2313 Token position() => node.getBeginToken(); |
| 2407 | 2314 |
| 2408 Node parseNode(DiagnosticListener listener) => node; | 2315 Node parseNode(DiagnosticListener listener) => node; |
| 2409 | 2316 |
| 2410 FunctionElement lookupLocalConstructor(String name) { | 2317 FunctionElement lookupLocalConstructor(String name) { |
| 2411 for (Link<Element> link = constructors; | 2318 for (Link<Element> link = constructors; |
| 2412 !link.isEmpty; | 2319 !link.isEmpty; |
| 2413 link = link.tail) { | 2320 link = link.tail) { |
| 2414 if (link.head.name == name) return link.head; | 2321 if (link.head.name == name) return link.head; |
| 2415 } | 2322 } |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2619 | 2526 |
| 2620 ParameterMetadataAnnotation(Metadata this.metadata); | 2527 ParameterMetadataAnnotation(Metadata this.metadata); |
| 2621 | 2528 |
| 2622 Node parseNode(DiagnosticListener listener) => metadata.expression; | 2529 Node parseNode(DiagnosticListener listener) => metadata.expression; |
| 2623 | 2530 |
| 2624 Token get beginToken => metadata.getBeginToken(); | 2531 Token get beginToken => metadata.getBeginToken(); |
| 2625 | 2532 |
| 2626 Token get endToken => metadata.getEndToken(); | 2533 Token get endToken => metadata.getEndToken(); |
| 2627 } | 2534 } |
| 2628 | 2535 |
| 2536 /// Mixin for the implementation of patched elements. |
| 2537 /// |
| 2538 /// See [:patch_parser.dart:] for a description of the terminology. |
| 2539 abstract class PatchMixin<E extends Element> implements Element { |
| 2540 // TODO(johnniwinther): Use type variables when issue 18630 is fixed. |
| 2541 Element/*E*/ patch = null; |
| 2542 Element/*E*/ origin = null; |
| 2543 |
| 2544 bool get isPatch => origin != null; |
| 2545 bool get isPatched => patch != null; |
| 2546 |
| 2547 bool get isImplementation => !isPatched; |
| 2548 bool get isDeclaration => !isPatch; |
| 2549 |
| 2550 Element/*E*/ get implementation => isPatched ? patch : this; |
| 2551 Element/*E*/ get declaration => isPatch ? origin : this; |
| 2552 |
| 2553 /// Applies a patch to this element. This method must be called at most once. |
| 2554 void applyPatch(PatchMixin<E> patch) { |
| 2555 assert(invariant(this, this.patch == null, |
| 2556 message: "Element is patched twice.")); |
| 2557 assert(invariant(this, this.origin == null, |
| 2558 message: "Origin element is a patch.")); |
| 2559 assert(invariant(patch, patch.origin == null, |
| 2560 message: "Element is patched twice.")); |
| 2561 assert(invariant(patch, patch.patch == null, |
| 2562 message: "Patch element is patched.")); |
| 2563 this.patch = patch; |
| 2564 patch.origin = this; |
| 2565 } |
| 2566 } |
| OLD | NEW |