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

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: 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
karlklose 2014/05/06 09:27:07 Does the 'extends ... with' clause fit in one line
Johnni Winther 2014/05/06 12:05:29 Done.
733 with AnalyzableElement,
734 PatchMixin<LibraryElementX>
773 implements LibraryElement { 735 implements LibraryElement {
774 final Uri canonicalUri; 736 final Uri canonicalUri;
775 CompilationUnitElement entryCompilationUnit; 737 CompilationUnitElement entryCompilationUnit;
776 Link<CompilationUnitElement> compilationUnits = 738 Link<CompilationUnitElement> compilationUnits =
777 const Link<CompilationUnitElement>(); 739 const Link<CompilationUnitElement>();
778 Link<LibraryTag> tags = const Link<LibraryTag>(); 740 Link<LibraryTag> tags = const Link<LibraryTag>();
779 LibraryName libraryTag; 741 LibraryName libraryTag;
780 bool canUseNative = false; 742 bool canUseNative = false;
781 Link<Element> localMembers = const Link<Element>(); 743 Link<Element> localMembers = const Link<Element>();
782 final ScopeX localScope = new ScopeX(); 744 final ScopeX localScope = new ScopeX();
783 final ImportScope importScope = new ImportScope(); 745 final ImportScope importScope = new ImportScope();
784 746
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. 747 /// A mapping from an imported element to the "import" tag.
800 final Importers importers = new Importers(); 748 final Importers importers = new Importers();
801 749
802 /** 750 /**
803 * Link for elements exported either through export declarations or through 751 * Link for elements exported either through export declarations or through
804 * declaration. This field should not be accessed directly but instead through 752 * declaration. This field should not be accessed directly but instead through
805 * the [exports] getter. 753 * the [exports] getter.
806 * 754 *
807 * [LibraryDependencyHandler] sets this field through [setExports] when the 755 * [LibraryDependencyHandler] sets this field through [setExports] when the
808 * library is loaded. 756 * library is loaded.
809 */ 757 */
810 Link<Element> slotForExports; 758 Link<Element> slotForExports;
811 759
812 final Map<LibraryDependency, LibraryElement> tagMapping = 760 final Map<LibraryDependency, LibraryElement> tagMapping =
813 new Map<LibraryDependency, LibraryElement>(); 761 new Map<LibraryDependency, LibraryElement>();
814 762
815 LibraryElementX(Script script, [Uri canonicalUri, LibraryElement this.origin]) 763 LibraryElementX(Script script,
764 [Uri canonicalUri, LibraryElementX origin])
816 : this.canonicalUri = 765 : this.canonicalUri =
817 ((canonicalUri == null) ? script.readableUri : canonicalUri), 766 ((canonicalUri == null) ? script.readableUri : canonicalUri),
818 super(script.name, ElementKind.LIBRARY, null) { 767 super(script.name, ElementKind.LIBRARY, null) {
819 entryCompilationUnit = new CompilationUnitElementX(script, this); 768 entryCompilationUnit = new CompilationUnitElementX(script, this);
820 if (isPatch) { 769 if (origin != null) {
821 origin.patch = this; 770 origin.applyPatch(this);
822 } 771 }
823 } 772 }
824 773
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 { 774 Link<MetadataAnnotation> get metadata {
832 return (libraryTag == null) ? super.metadata : libraryTag.metadata; 775 return (libraryTag == null) ? super.metadata : libraryTag.metadata;
833 } 776 }
834 777
835 set metadata(value) { 778 set metadata(value) {
836 // The metadata is stored on [libraryTag]. 779 // The metadata is stored on [libraryTag].
837 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library'); 780 throw new SpannableAssertionFailure(this, 'Cannot set metadata on Library');
838 } 781 }
839 782
840 CompilationUnitElement getCompilationUnit() => entryCompilationUnit; 783 CompilationUnitElement getCompilationUnit() => entryCompilationUnit;
(...skipping 10 matching lines...) Expand all
851 assert(tagMapping[tag] == null); 794 assert(tagMapping[tag] == null);
852 tagMapping[tag] = library; 795 tagMapping[tag] = library;
853 } 796 }
854 797
855 LibraryElement getLibraryFromTag(LibraryDependency tag) => tagMapping[tag]; 798 LibraryElement getLibraryFromTag(LibraryDependency tag) => tagMapping[tag];
856 799
857 /** 800 /**
858 * Adds [element] to the import scope of this library. 801 * Adds [element] to the import scope of this library.
859 * 802 *
860 * If an element by the same name is already in the imported scope, an 803 * 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. 804 * [ErroneousElement] will be put in the imported scope, allowing for
805 * detection of ambiguous uses of imported names.
862 */ 806 */
863 void addImport(Element element, Import import, DiagnosticListener listener) { 807 void addImport(Element element, Import import, DiagnosticListener listener) {
864 importScope.addImport(this, element, import, listener); 808 importScope.addImport(this, element, import, listener);
865 } 809 }
866 810
867 void addMember(Element element, DiagnosticListener listener) { 811 void addMember(Element element, DiagnosticListener listener) {
868 localMembers = localMembers.prepend(element); 812 localMembers = localMembers.prepend(element);
869 addToScope(element, listener); 813 addToScope(element, listener);
870 } 814 }
871 815
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 1221
1278 accept(ElementVisitor visitor) => visitor.visitFieldParameterElement(this); 1222 accept(ElementVisitor visitor) => visitor.visitFieldParameterElement(this);
1279 } 1223 }
1280 1224
1281 /// [Element] for a formal parameter. 1225 /// [Element] for a formal parameter.
1282 /// 1226 ///
1283 /// A [ParameterElementX] can be patched. A parameter of an external method is 1227 /// 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 1228 /// 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 1229 /// 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. 1230 /// origin parameter) but can be found through both the origin and the patch.
1287 class ParameterElementX extends ElementX implements ParameterElement { 1231 class ParameterElementX
1232 extends ElementX
1233 with PatchMixin<ParameterElement>
karlklose 2014/05/06 09:27:07 Ditto.
Johnni Winther 2014/05/06 12:05:29 Done.
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
karlklose 2014/05/06 09:27:07 Ditto.
Johnni Winther 2014/05/06 12:05:29 Done.
1432 with AnalyzableElement,
1433 PatchMixin<FunctionElement>
1490 implements FunctionElement { 1434 implements FunctionElement {
1491 FunctionExpression cachedNode; 1435 FunctionExpression cachedNode;
1492 DartType typeCache; 1436 DartType typeCache;
1493 final Modifiers modifiers; 1437 final Modifiers modifiers;
1494 1438
1495 List<FunctionElement> nestedClosures = new List<FunctionElement>(); 1439 List<FunctionElement> nestedClosures = new List<FunctionElement>();
1496 1440
1497 FunctionSignature functionSignatureCache; 1441 FunctionSignature functionSignatureCache;
1498 1442
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; 1443 final bool _hasNoBody;
1508 1444
1509 AbstractFieldElement abstractField; 1445 AbstractFieldElement abstractField;
1510 1446
1511 /** 1447 /**
1512 * If this is a redirecting factory, [defaultImplementation] will be 1448 * If this is a redirecting factory, [defaultImplementation] will be
1513 * changed by the resolver to point to the redirection target. 1449 * changed by the resolver to point to the redirection target.
1514 * Otherwise, [:identical(defaultImplementation, this):]. 1450 * Otherwise, [:identical(defaultImplementation, this):].
1515 */ 1451 */
1516 // TODO(ahe): Rename this field to redirectionTarget. 1452 // TODO(ahe): Rename this field to redirectionTarget.
(...skipping 21 matching lines...) Expand all
1538 this.modifiers, 1474 this.modifiers,
1539 Element enclosing, 1475 Element enclosing,
1540 this.functionSignatureCache, 1476 this.functionSignatureCache,
1541 bool hasNoBody) 1477 bool hasNoBody)
1542 : super(name, kind, enclosing), 1478 : super(name, kind, enclosing),
1543 _hasNoBody = hasNoBody { 1479 _hasNoBody = hasNoBody {
1544 assert(modifiers != null); 1480 assert(modifiers != null);
1545 defaultImplementation = this; 1481 defaultImplementation = this;
1546 } 1482 }
1547 1483
1548 bool get isPatched => patch != null;
1549 bool get isPatch => origin != null;
1550
1551 bool get isRedirectingFactory => defaultImplementation != this; 1484 bool get isRedirectingFactory => defaultImplementation != this;
1552 1485
1553 /// This field is set by the post process queue when checking for cycles. 1486 /// This field is set by the post process queue when checking for cycles.
1554 FunctionElement internalRedirectionTarget; 1487 FunctionElement internalRedirectionTarget;
1555 DartType redirectionTargetType; 1488 DartType redirectionTargetType;
1556 1489
1557 set redirectionTarget(FunctionElement constructor) { 1490 set redirectionTarget(FunctionElement constructor) {
1558 assert(constructor != null && internalRedirectionTarget == null); 1491 assert(constructor != null && internalRedirectionTarget == null);
1559 internalRedirectionTarget = constructor; 1492 internalRedirectionTarget = constructor;
1560 } 1493 }
1561 1494
1562 FunctionElement get redirectionTarget { 1495 FunctionElement get redirectionTarget {
1563 if (Elements.isErroneousElement(defaultImplementation)) { 1496 if (Elements.isErroneousElement(defaultImplementation)) {
1564 return defaultImplementation; 1497 return defaultImplementation;
1565 } 1498 }
1566 assert(!isRedirectingFactory || internalRedirectionTarget != null); 1499 assert(!isRedirectingFactory || internalRedirectionTarget != null);
1567 return isRedirectingFactory ? internalRedirectionTarget : this; 1500 return isRedirectingFactory ? internalRedirectionTarget : this;
1568 } 1501 }
1569 1502
1570 InterfaceType computeTargetType(InterfaceType newType) { 1503 InterfaceType computeTargetType(InterfaceType newType) {
1571 if (!isRedirectingFactory) return newType; 1504 if (!isRedirectingFactory) return newType;
1572 assert(invariant(this, redirectionTargetType != null, 1505 assert(invariant(this, redirectionTargetType != null,
1573 message: 'Redirection target type has not yet been computed for ' 1506 message: 'Redirection target type has not yet been computed for '
1574 '$this.')); 1507 '$this.'));
1575 return redirectionTargetType.substByContext(newType); 1508 return redirectionTargetType.substByContext(newType);
1576 } 1509 }
1577 1510
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() { 1511 bool isInstanceMember() {
1591 return isMember() 1512 return isMember()
1592 && !isConstructor() 1513 && !isConstructor()
1593 && !modifiers.isStatic(); 1514 && !modifiers.isStatic();
1594 } 1515 }
1595 1516
1596 FunctionSignature computeSignature(Compiler compiler) { 1517 FunctionSignature computeSignature(Compiler compiler) {
1597 if (functionSignatureCache != null) return functionSignatureCache; 1518 if (functionSignatureCache != null) return functionSignatureCache;
1598 compiler.withCurrentElement(this, () { 1519 compiler.withCurrentElement(this, () {
1599 functionSignatureCache = compiler.resolveSignature(this); 1520 functionSignatureCache = compiler.resolveSignature(this);
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1904 variableElement.typeCache = variableType; 1825 variableElement.typeCache = variableType;
1905 arguments.addLast(variableType); 1826 arguments.addLast(variableType);
1906 } 1827 }
1907 return arguments.toLink(); 1828 return arguments.toLink();
1908 } 1829 }
1909 } 1830 }
1910 1831
1911 abstract class BaseClassElementX extends ElementX 1832 abstract class BaseClassElementX extends ElementX
1912 with AnalyzableElement, 1833 with AnalyzableElement,
1913 TypeDeclarationElementX<InterfaceType>, 1834 TypeDeclarationElementX<InterfaceType>,
1835 PatchMixin<ClassElement>,
1914 ClassMemberMixin 1836 ClassMemberMixin
1915 implements ClassElement { 1837 implements ClassElement {
1916 final int id; 1838 final int id;
1917 1839
1918 DartType supertype; 1840 DartType supertype;
1919 Link<DartType> interfaces; 1841 Link<DartType> interfaces;
1920 String nativeTagInfo; 1842 String nativeTagInfo;
1921 int supertypeLoadState; 1843 int supertypeLoadState;
1922 int resolutionState; 1844 int resolutionState;
1923 bool get isResolved => resolutionState == STATE_DONE; 1845 bool get isResolved => resolutionState == STATE_DONE;
(...skipping 12 matching lines...) Expand all
1936 1858
1937 BaseClassElementX(String name, 1859 BaseClassElementX(String name,
1938 Element enclosing, 1860 Element enclosing,
1939 this.id, 1861 this.id,
1940 int initialState) 1862 int initialState)
1941 : supertypeLoadState = initialState, 1863 : supertypeLoadState = initialState,
1942 resolutionState = initialState, 1864 resolutionState = initialState,
1943 super(name, ElementKind.CLASS, enclosing); 1865 super(name, ElementKind.CLASS, enclosing);
1944 1866
1945 int get hashCode => id; 1867 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 1868
1951 bool get hasBackendMembers => !backendMembers.isEmpty; 1869 bool get hasBackendMembers => !backendMembers.isEmpty;
1952 1870
1953 bool get isUnnamedMixinApplication => false; 1871 bool get isUnnamedMixinApplication => false;
1954 1872
1955 InterfaceType computeType(Compiler compiler) { 1873 InterfaceType computeType(Compiler compiler) {
1956 if (thisTypeCache == null) { 1874 if (thisTypeCache == null) {
1957 computeThisAndRawType(compiler, computeTypeParameters(compiler)); 1875 computeThisAndRawType(compiler, computeTypeParameters(compiler));
1958 } 1876 }
1959 return thisTypeCache; 1877 return thisTypeCache;
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
2293 } 2211 }
2294 2212
2295 FunctionType get callType { 2213 FunctionType get callType {
2296 MemberSignature member = 2214 MemberSignature member =
2297 lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME)); 2215 lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));
2298 return member != null && member.isMethod ? member.type : null; 2216 return member != null && member.isMethod ? member.type : null;
2299 } 2217 }
2300 } 2218 }
2301 2219
2302 abstract class ClassElementX extends BaseClassElementX { 2220 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>(); 2221 Link<Element> localMembers = const Link<Element>();
2308 final ScopeX localScope = new ScopeX(); 2222 final ScopeX localScope = new ScopeX();
2309 2223
2310 ClassElementX(String name, Element enclosing, int id, int initialState) 2224 ClassElementX(String name, Element enclosing, int id, int initialState)
2311 : super(name, enclosing, id, initialState); 2225 : super(name, enclosing, id, initialState);
2312 2226
2313 ClassNode parseNode(Compiler compiler); 2227 ClassNode parseNode(Compiler compiler);
2314 2228
2315 bool get isMixinApplication => false; 2229 bool get isMixinApplication => false;
2316 bool get isPatched => patch != null;
2317 bool get isPatch => origin != null;
2318 bool get hasLocalScopeMembers => !localScope.isEmpty; 2230 bool get hasLocalScopeMembers => !localScope.isEmpty;
2319 2231
2320 void addMember(Element element, DiagnosticListener listener) { 2232 void addMember(Element element, DiagnosticListener listener) {
2321 localMembers = localMembers.prepend(element); 2233 localMembers = localMembers.prepend(element);
2322 addToScope(element, listener); 2234 addToScope(element, listener);
2323 } 2235 }
2324 2236
2325 void addToScope(Element element, DiagnosticListener listener) { 2237 void addToScope(Element element, DiagnosticListener listener) {
2326 if (element.isField() && element.name == name) { 2238 if (element.isField() && element.name == name) {
2327 listener.reportError(element, MessageKind.MEMBER_USES_CLASS_NAME); 2239 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) 2298 this.node, this.modifiers)
2387 : super(name, enclosing, id, STATE_NOT_STARTED); 2299 : super(name, enclosing, id, STATE_NOT_STARTED);
2388 2300
2389 ClassElement get mixin => mixinType != null ? mixinType.element : null; 2301 ClassElement get mixin => mixinType != null ? mixinType.element : null;
2390 2302
2391 bool get isMixinApplication => true; 2303 bool get isMixinApplication => true;
2392 bool get isUnnamedMixinApplication => node is! NamedMixinApplication; 2304 bool get isUnnamedMixinApplication => node is! NamedMixinApplication;
2393 bool get hasConstructor => !constructors.isEmpty; 2305 bool get hasConstructor => !constructors.isEmpty;
2394 bool get hasLocalScopeMembers => !constructors.isEmpty; 2306 bool get hasLocalScopeMembers => !constructors.isEmpty;
2395 2307
2396 unsupported(message) {
2397 throw new UnsupportedError('$message is not supported on $this');
2398 }
2399
2400 get patch => null; 2308 get patch => null;
2401 get origin => null; 2309 get origin => null;
2402 2310
2403 set patch(value) => unsupported('set patch');
2404 set origin(value) => unsupported('set origin');
2405
2406 Token position() => node.getBeginToken(); 2311 Token position() => node.getBeginToken();
2407 2312
2408 Node parseNode(DiagnosticListener listener) => node; 2313 Node parseNode(DiagnosticListener listener) => node;
2409 2314
2410 FunctionElement lookupLocalConstructor(String name) { 2315 FunctionElement lookupLocalConstructor(String name) {
2411 for (Link<Element> link = constructors; 2316 for (Link<Element> link = constructors;
2412 !link.isEmpty; 2317 !link.isEmpty;
2413 link = link.tail) { 2318 link = link.tail) {
2414 if (link.head.name == name) return link.head; 2319 if (link.head.name == name) return link.head;
2415 } 2320 }
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
2619 2524
2620 ParameterMetadataAnnotation(Metadata this.metadata); 2525 ParameterMetadataAnnotation(Metadata this.metadata);
2621 2526
2622 Node parseNode(DiagnosticListener listener) => metadata.expression; 2527 Node parseNode(DiagnosticListener listener) => metadata.expression;
2623 2528
2624 Token get beginToken => metadata.getBeginToken(); 2529 Token get beginToken => metadata.getBeginToken();
2625 2530
2626 Token get endToken => metadata.getEndToken(); 2531 Token get endToken => metadata.getEndToken();
2627 } 2532 }
2628 2533
2534 /// Mixin for the implementation of patched elements.
2535 ///
2536 /// See [:patch_parser.dart:] for a description of the terminology.
2537 abstract class PatchMixin<E extends Element> implements Element {
2538 // TODO(johnniwinther): Use type variables when issue 18630 is fixed.
2539 var/*E*/ patch = null;
karlklose 2014/05/06 09:27:07 Use the bound (Element) instead of var.
Johnni Winther 2014/05/06 12:05:29 Done. Added temporary explicit getters to BaseClas
2540 var/*E*/ origin = null;
2541
2542 bool get isPatch => origin != null;
2543 bool get isPatched => patch != null;
2544
2545 bool get isImplementation => !isPatched;
2546 bool get isDeclaration => !isPatch;
2547
2548 /*E*/ get implementation => isPatched ? patch : this;
karlklose 2014/05/06 09:27:07 Use Element.
Johnni Winther 2014/05/06 12:05:29 Done.
2549 /*E*/ get declaration => isPatch ? origin : this;
2550
2551 /// Applies a patch to this element. This method must be called at most once.
2552 void applyPatch(PatchMixin<E> patch) {
2553 assert(invariant(this, this.patch == null,
2554 message: "Element is patched twice."));
2555 assert(invariant(this, this.origin == null,
2556 message: "Origin element is a patch."));
2557 assert(invariant(patch, patch.origin == null,
2558 message: "Element is patched twice."));
2559 assert(invariant(patch, patch.patch == null,
2560 message: "Patch element is patched."));
2561 this.patch = patch;
2562 patch.origin = this;
2563 }
2564 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698