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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/elements/modelx.dart

Issue 266193004: Clean patch implementation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698