| 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 '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/names.dart' show Identifiers; | 8 import '../common/names.dart' show Identifiers; |
| 9 import '../common/resolution.dart' show Resolution, ParsingContext; | 9 import '../common/resolution.dart' show Resolution, ParsingContext; |
| 10 import '../compiler.dart' show Compiler; | 10 import '../compiler.dart' show Compiler; |
| (...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1137 /** | 1137 /** |
| 1138 * Returns [:true:] if the export scope has already been computed for this | 1138 * Returns [:true:] if the export scope has already been computed for this |
| 1139 * library. | 1139 * library. |
| 1140 */ | 1140 */ |
| 1141 bool get exportsHandled => slotForExports != null; | 1141 bool get exportsHandled => slotForExports != null; |
| 1142 | 1142 |
| 1143 /** | 1143 /** |
| 1144 * Sets the export scope of this library. This method can only be called once. | 1144 * Sets the export scope of this library. This method can only be called once. |
| 1145 */ | 1145 */ |
| 1146 void setExports(Iterable<Element> exportedElements) { | 1146 void setExports(Iterable<Element> exportedElements) { |
| 1147 assert(invariant(this, !exportsHandled, | 1147 assert(!exportsHandled, |
| 1148 message: 'Exports already set to $slotForExports on $this')); | 1148 failedAt(this, 'Exports already set to $slotForExports on $this')); |
| 1149 assert(invariant(this, exportedElements != null)); | 1149 assert(exportedElements != null, failedAt(this)); |
| 1150 var builder = new LinkBuilder<Element>(); | 1150 var builder = new LinkBuilder<Element>(); |
| 1151 for (Element export in exportedElements) { | 1151 for (Element export in exportedElements) { |
| 1152 builder.addLast(export); | 1152 builder.addLast(export); |
| 1153 } | 1153 } |
| 1154 slotForExports = builder.toLink(); | 1154 slotForExports = builder.toLink(); |
| 1155 } | 1155 } |
| 1156 | 1156 |
| 1157 LibraryElement get library => isPatch ? origin : this; | 1157 LibraryElement get library => isPatch ? origin : this; |
| 1158 | 1158 |
| 1159 /** | 1159 /** |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1184 // TODO((johnniwinther): How to handle injected elements in the patch | 1184 // TODO((johnniwinther): How to handle injected elements in the patch |
| 1185 // library? | 1185 // library? |
| 1186 Element result = localScope.lookup(elementName); | 1186 Element result = localScope.lookup(elementName); |
| 1187 if (result == null && isPatch) { | 1187 if (result == null && isPatch) { |
| 1188 return origin.findLocal(elementName); | 1188 return origin.findLocal(elementName); |
| 1189 } | 1189 } |
| 1190 return result; | 1190 return result; |
| 1191 } | 1191 } |
| 1192 | 1192 |
| 1193 Element findExported(String elementName) { | 1193 Element findExported(String elementName) { |
| 1194 assert(invariant(this, exportsHandled, | 1194 assert(exportsHandled, failedAt(this, 'Exports not handled on $this')); |
| 1195 message: 'Exports not handled on $this')); | |
| 1196 for (Link link = slotForExports; !link.isEmpty; link = link.tail) { | 1195 for (Link link = slotForExports; !link.isEmpty; link = link.tail) { |
| 1197 Element element = link.head; | 1196 Element element = link.head; |
| 1198 if (element.name == elementName) return element; | 1197 if (element.name == elementName) return element; |
| 1199 } | 1198 } |
| 1200 return null; | 1199 return null; |
| 1201 } | 1200 } |
| 1202 | 1201 |
| 1203 void forEachExport(f(Element element)) { | 1202 void forEachExport(f(Element element)) { |
| 1204 assert(invariant(this, exportsHandled, | 1203 assert(exportsHandled, failedAt(this, 'Exports not handled on $this')); |
| 1205 message: 'Exports not handled on $this')); | |
| 1206 slotForExports.forEach((Element e) => f(e)); | 1204 slotForExports.forEach((Element e) => f(e)); |
| 1207 } | 1205 } |
| 1208 | 1206 |
| 1209 Iterable<ImportElement> getImportsFor(Element element) { | 1207 Iterable<ImportElement> getImportsFor(Element element) { |
| 1210 return importers.getImports(element); | 1208 return importers.getImports(element); |
| 1211 } | 1209 } |
| 1212 | 1210 |
| 1213 void forEachImport(f(Element element)) => importScope.forEach(f); | 1211 void forEachImport(f(Element element)) => importScope.forEach(f); |
| 1214 | 1212 |
| 1215 void forEachLocalMember(f(Element element)) { | 1213 void forEachLocalMember(f(Element element)) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1315 TypeDeclarationElementX<ResolutionTypedefType> | 1313 TypeDeclarationElementX<ResolutionTypedefType> |
| 1316 implements TypedefElement { | 1314 implements TypedefElement { |
| 1317 Typedef cachedNode; | 1315 Typedef cachedNode; |
| 1318 | 1316 |
| 1319 /** | 1317 /** |
| 1320 * The type annotation which defines this typedef. | 1318 * The type annotation which defines this typedef. |
| 1321 */ | 1319 */ |
| 1322 ResolutionDartType aliasCache; | 1320 ResolutionDartType aliasCache; |
| 1323 | 1321 |
| 1324 ResolutionDartType get alias { | 1322 ResolutionDartType get alias { |
| 1325 assert(invariant(this, hasBeenCheckedForCycles, | 1323 assert(hasBeenCheckedForCycles, |
| 1326 message: "$this has not been checked for cycles.")); | 1324 failedAt(this, "$this has not been checked for cycles.")); |
| 1327 return aliasCache; | 1325 return aliasCache; |
| 1328 } | 1326 } |
| 1329 | 1327 |
| 1330 /// [:true:] if the typedef has been checked for cyclic reference. | 1328 /// [:true:] if the typedef has been checked for cyclic reference. |
| 1331 bool hasBeenCheckedForCycles = false; | 1329 bool hasBeenCheckedForCycles = false; |
| 1332 | 1330 |
| 1333 int resolutionState = STATE_NOT_STARTED; | 1331 int resolutionState = STATE_NOT_STARTED; |
| 1334 | 1332 |
| 1335 TypedefElementX(String name, Element enclosing) | 1333 TypedefElementX(String name, Element enclosing) |
| 1336 : super(name, ElementKind.TYPEDEF, enclosing); | 1334 : super(name, ElementKind.TYPEDEF, enclosing); |
| 1337 | 1335 |
| 1338 bool get hasNode => cachedNode != null; | 1336 bool get hasNode => cachedNode != null; |
| 1339 | 1337 |
| 1340 Typedef get node { | 1338 Typedef get node { |
| 1341 assert(invariant(this, cachedNode != null, | 1339 assert(cachedNode != null, |
| 1342 message: "Node has not been computed for $this.")); | 1340 failedAt(this, "Node has not been computed for $this.")); |
| 1343 return cachedNode; | 1341 return cachedNode; |
| 1344 } | 1342 } |
| 1345 | 1343 |
| 1346 /** | 1344 /** |
| 1347 * Function signature for a typedef of a function type. The signature is | 1345 * Function signature for a typedef of a function type. The signature is |
| 1348 * kept to provide full information about parameter names through the mirror | 1346 * kept to provide full information about parameter names through the mirror |
| 1349 * system. | 1347 * system. |
| 1350 * | 1348 * |
| 1351 * The [functionSignature] is not available until the typedef element has been | 1349 * The [functionSignature] is not available until the typedef element has been |
| 1352 * resolved. | 1350 * resolved. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1442 // TODO(johnniwinther): Update the on `constant = ...` when evaluation of | 1440 // TODO(johnniwinther): Update the on `constant = ...` when evaluation of |
| 1443 // constant expression can handle references to unanalyzed constant variables. | 1441 // constant expression can handle references to unanalyzed constant variables. |
| 1444 @override | 1442 @override |
| 1445 bool get hasConstant => false; | 1443 bool get hasConstant => false; |
| 1446 | 1444 |
| 1447 ConstantExpression get constant { | 1445 ConstantExpression get constant { |
| 1448 if (isPatch) { | 1446 if (isPatch) { |
| 1449 ConstantVariableMixin originVariable = origin; | 1447 ConstantVariableMixin originVariable = origin; |
| 1450 return originVariable.constant; | 1448 return originVariable.constant; |
| 1451 } | 1449 } |
| 1452 assert(invariant(this, !isConst || constantCache != null, | 1450 assert(!isConst || constantCache != null, |
| 1453 message: "Constant has not been computed for $this.")); | 1451 failedAt(this, "Constant has not been computed for $this.")); |
| 1454 return constantCache; | 1452 return constantCache; |
| 1455 } | 1453 } |
| 1456 | 1454 |
| 1457 void set constant(ConstantExpression value) { | 1455 void set constant(ConstantExpression value) { |
| 1458 if (isPatch) { | 1456 if (isPatch) { |
| 1459 ConstantVariableMixin originVariable = origin; | 1457 ConstantVariableMixin originVariable = origin; |
| 1460 originVariable.constant = value; | 1458 originVariable.constant = value; |
| 1461 return; | 1459 return; |
| 1462 } | 1460 } |
| 1463 if (constantCache != null && | 1461 if (constantCache != null && |
| 1464 constantCache.kind == ConstantExpressionKind.ERRONEOUS) { | 1462 constantCache.kind == ConstantExpressionKind.ERRONEOUS) { |
| 1465 // TODO(johnniwinther): Find out why we sometimes compute a non-erroneous | 1463 // TODO(johnniwinther): Find out why we sometimes compute a non-erroneous |
| 1466 // constant for a variable already known to be erroneous. | 1464 // constant for a variable already known to be erroneous. |
| 1467 return; | 1465 return; |
| 1468 } | 1466 } |
| 1469 if (constantCache != null && constantCache != value) { | 1467 if (constantCache != null && constantCache != value) { |
| 1470 // Allow setting the constant as erroneous. Constants computed during | 1468 // Allow setting the constant as erroneous. Constants computed during |
| 1471 // resolution are locally valid but might be effectively erroneous. For | 1469 // resolution are locally valid but might be effectively erroneous. For |
| 1472 // instance `a ? true : false` where a is `const a = m()`. Since `a` is | 1470 // instance `a ? true : false` where a is `const a = m()`. Since `a` is |
| 1473 // declared to be constant, the conditional is assumed valid, but when | 1471 // declared to be constant, the conditional is assumed valid, but when |
| 1474 // computing the value we see that it isn't. | 1472 // computing the value we see that it isn't. |
| 1475 // TODO(johnniwinther): Remove this exception when all constant | 1473 // TODO(johnniwinther): Remove this exception when all constant |
| 1476 // expressions are computed during resolution. | 1474 // expressions are computed during resolution. |
| 1477 assert(invariant( | 1475 assert( |
| 1478 this, value == null || value.kind == ConstantExpressionKind.ERRONEOUS, | 1476 value == null || value.kind == ConstantExpressionKind.ERRONEOUS, |
| 1479 message: "Constant has already been computed for $this. " | 1477 failedAt( |
| 1478 this, |
| 1479 "Constant has already been computed for $this. " |
| 1480 "Existing constant: " | 1480 "Existing constant: " |
| 1481 "${constantCache != null ? constantCache.toStructuredText() : ''}" | 1481 "${constantCache != null ? constantCache.toStructuredText() : ''}" |
| 1482 ", New constant: " | 1482 ", New constant: " |
| 1483 "${value != null ? value.toStructuredText() : ''}.")); | 1483 "${value != null ? value.toStructuredText() : ''}.")); |
| 1484 } | 1484 } |
| 1485 constantCache = value; | 1485 constantCache = value; |
| 1486 } | 1486 } |
| 1487 } | 1487 } |
| 1488 | 1488 |
| 1489 abstract class VariableElementX extends ElementX | 1489 abstract class VariableElementX extends ElementX |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1513 } | 1513 } |
| 1514 variables.metadata = metadata; | 1514 variables.metadata = metadata; |
| 1515 } | 1515 } |
| 1516 | 1516 |
| 1517 // A variable cannot be patched therefore defines itself. | 1517 // A variable cannot be patched therefore defines itself. |
| 1518 AstElement get definingElement => this; | 1518 AstElement get definingElement => this; |
| 1519 | 1519 |
| 1520 bool get hasNode => definitionsCache != null; | 1520 bool get hasNode => definitionsCache != null; |
| 1521 | 1521 |
| 1522 VariableDefinitions get node { | 1522 VariableDefinitions get node { |
| 1523 assert(invariant(this, definitionsCache != null, | 1523 assert(definitionsCache != null, |
| 1524 message: "Node has not been computed for $this.")); | 1524 failedAt(this, "Node has not been computed for $this.")); |
| 1525 return definitionsCache; | 1525 return definitionsCache; |
| 1526 } | 1526 } |
| 1527 | 1527 |
| 1528 /// Returns the node that defines this field. | 1528 /// Returns the node that defines this field. |
| 1529 /// | 1529 /// |
| 1530 /// For instance in `var a, b = true`, the definitions nodes for fields 'a' | 1530 /// For instance in `var a, b = true`, the definitions nodes for fields 'a' |
| 1531 /// and 'b' are the nodes for `a` and `b = true`, respectively. | 1531 /// and 'b' are the nodes for `a` and `b = true`, respectively. |
| 1532 Expression get definition { | 1532 Expression get definition { |
| 1533 assert(invariant(this, definitionCache != null, | 1533 assert(definitionCache != null, |
| 1534 message: "Definition node has not been computed for $this.")); | 1534 failedAt(this, "Definition node has not been computed for $this.")); |
| 1535 return definitionCache; | 1535 return definitionCache; |
| 1536 } | 1536 } |
| 1537 | 1537 |
| 1538 Expression get initializer { | 1538 Expression get initializer { |
| 1539 assert(invariant(this, definitionsCache != null, | 1539 assert(definitionsCache != null, |
| 1540 message: "Initializer has not been computed for $this.")); | 1540 failedAt(this, "Initializer has not been computed for $this.")); |
| 1541 return initializerCache; | 1541 return initializerCache; |
| 1542 } | 1542 } |
| 1543 | 1543 |
| 1544 Node parseNode(ParsingContext parsing) { | 1544 Node parseNode(ParsingContext parsing) { |
| 1545 if (definitionsCache != null) return definitionsCache; | 1545 if (definitionsCache != null) return definitionsCache; |
| 1546 | 1546 |
| 1547 VariableDefinitions definitions = variables.parseNode(this, parsing); | 1547 VariableDefinitions definitions = variables.parseNode(this, parsing); |
| 1548 createDefinitions(definitions); | 1548 createDefinitions(definitions); |
| 1549 return definitionsCache; | 1549 return definitionsCache; |
| 1550 } | 1550 } |
| 1551 | 1551 |
| 1552 void createDefinitions(VariableDefinitions definitions) { | 1552 void createDefinitions(VariableDefinitions definitions) { |
| 1553 assert(invariant(this, definitionsCache == null, | 1553 assert( |
| 1554 message: "VariableDefinitions has already been computed for $this.")); | 1554 definitionsCache == null, |
| 1555 failedAt( |
| 1556 this, "VariableDefinitions has already been computed for $this.")); |
| 1555 for (Link<Node> link = definitions.definitions.nodes; | 1557 for (Link<Node> link = definitions.definitions.nodes; |
| 1556 !link.isEmpty; | 1558 !link.isEmpty; |
| 1557 link = link.tail) { | 1559 link = link.tail) { |
| 1558 Expression initializedIdentifier = link.head; | 1560 Expression initializedIdentifier = link.head; |
| 1559 Identifier identifier = initializedIdentifier.asIdentifier(); | 1561 Identifier identifier = initializedIdentifier.asIdentifier(); |
| 1560 if (identifier == null) { | 1562 if (identifier == null) { |
| 1561 SendSet sendSet = initializedIdentifier.asSendSet(); | 1563 SendSet sendSet = initializedIdentifier.asSendSet(); |
| 1562 identifier = sendSet.selector.asIdentifier(); | 1564 identifier = sendSet.selector.asIdentifier(); |
| 1563 if (identical(name, identifier.source)) { | 1565 if (identical(name, identifier.source)) { |
| 1564 definitionCache = initializedIdentifier; | 1566 definitionCache = initializedIdentifier; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1575 | 1577 |
| 1576 ResolutionDartType computeType(Resolution resolution) { | 1578 ResolutionDartType computeType(Resolution resolution) { |
| 1577 if (variables.type != null) return variables.type; | 1579 if (variables.type != null) return variables.type; |
| 1578 // Call [parseNode] to ensure that [definitionsCache] and [initializerCache] | 1580 // Call [parseNode] to ensure that [definitionsCache] and [initializerCache] |
| 1579 // are set as a consequence of calling [computeType]. | 1581 // are set as a consequence of calling [computeType]. |
| 1580 parseNode(resolution.parsingContext); | 1582 parseNode(resolution.parsingContext); |
| 1581 return variables.computeType(this, resolution); | 1583 return variables.computeType(this, resolution); |
| 1582 } | 1584 } |
| 1583 | 1585 |
| 1584 ResolutionDartType get type { | 1586 ResolutionDartType get type { |
| 1585 assert(invariant(this, variables.type != null, | 1587 assert(variables.type != null, |
| 1586 message: "Type has not been computed for $this.")); | 1588 failedAt(this, "Type has not been computed for $this.")); |
| 1587 return variables.type; | 1589 return variables.type; |
| 1588 } | 1590 } |
| 1589 | 1591 |
| 1590 bool get isInstanceMember => isClassMember && !isStatic; | 1592 bool get isInstanceMember => isClassMember && !isStatic; |
| 1591 | 1593 |
| 1592 // Note: cachedNode.beginToken will not be correct in all | 1594 // Note: cachedNode.beginToken will not be correct in all |
| 1593 // cases, for example, for function typed parameters. | 1595 // cases, for example, for function typed parameters. |
| 1594 Token get position => token; | 1596 Token get position => token; |
| 1595 | 1597 |
| 1596 DeclarationSite get declarationSite => variables; | 1598 DeclarationSite get declarationSite => variables; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1764 | 1766 |
| 1765 FunctionTypedElement get functionDeclaration => enclosingElement; | 1767 FunctionTypedElement get functionDeclaration => enclosingElement; |
| 1766 | 1768 |
| 1767 Modifiers get modifiers => definitions.modifiers; | 1769 Modifiers get modifiers => definitions.modifiers; |
| 1768 | 1770 |
| 1769 Token get position => identifier.getBeginToken(); | 1771 Token get position => identifier.getBeginToken(); |
| 1770 | 1772 |
| 1771 Node parseNode(ParsingContext parsing) => definitions; | 1773 Node parseNode(ParsingContext parsing) => definitions; |
| 1772 | 1774 |
| 1773 ResolutionDartType computeType(Resolution resolution) { | 1775 ResolutionDartType computeType(Resolution resolution) { |
| 1774 assert(invariant(this, type != null, | 1776 assert(type != null, |
| 1775 message: "Parameter type has not been set for $this.")); | 1777 failedAt(this, "Parameter type has not been set for $this.")); |
| 1776 return type; | 1778 return type; |
| 1777 } | 1779 } |
| 1778 | 1780 |
| 1779 ResolutionDartType get type { | 1781 ResolutionDartType get type { |
| 1780 assert(invariant(this, typeCache != null, | 1782 assert(typeCache != null, |
| 1781 message: "Parameter type has not been set for $this.")); | 1783 failedAt(this, "Parameter type has not been set for $this.")); |
| 1782 return typeCache; | 1784 return typeCache; |
| 1783 } | 1785 } |
| 1784 | 1786 |
| 1785 FunctionSignature get functionSignature { | 1787 FunctionSignature get functionSignature { |
| 1786 assert(invariant(this, _functionSignatureCache != null, | 1788 assert(_functionSignatureCache != null, |
| 1787 message: "Parameter signature has not been computed for $this.")); | 1789 failedAt(this, "Parameter signature has not been computed for $this.")); |
| 1788 return _functionSignatureCache; | 1790 return _functionSignatureCache; |
| 1789 } | 1791 } |
| 1790 | 1792 |
| 1791 void set functionSignature(FunctionSignature value) { | 1793 void set functionSignature(FunctionSignature value) { |
| 1792 assert(invariant(this, _functionSignatureCache == null, | 1794 assert( |
| 1793 message: "Parameter signature has already been computed for $this.")); | 1795 _functionSignatureCache == null, |
| 1796 failedAt( |
| 1797 this, "Parameter signature has already been computed for $this.")); |
| 1794 _functionSignatureCache = value; | 1798 _functionSignatureCache = value; |
| 1795 typeCache = _functionSignatureCache.type; | 1799 typeCache = _functionSignatureCache.type; |
| 1796 } | 1800 } |
| 1797 | 1801 |
| 1798 bool get hasNode => true; | 1802 bool get hasNode => true; |
| 1799 | 1803 |
| 1800 VariableDefinitions get node => definitions; | 1804 VariableDefinitions get node => definitions; |
| 1801 | 1805 |
| 1802 ResolutionFunctionType get functionType => type; | 1806 ResolutionFunctionType get functionType => type; |
| 1803 | 1807 |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2027 functionSignature.parameterStructure; | 2031 functionSignature.parameterStructure; |
| 2028 | 2032 |
| 2029 bool get hasFunctionSignature => _functionSignatureCache != null; | 2033 bool get hasFunctionSignature => _functionSignatureCache != null; |
| 2030 | 2034 |
| 2031 void _computeSignature(Resolution resolution) { | 2035 void _computeSignature(Resolution resolution) { |
| 2032 if (hasFunctionSignature) return; | 2036 if (hasFunctionSignature) return; |
| 2033 functionSignature = resolution.resolveSignature(this); | 2037 functionSignature = resolution.resolveSignature(this); |
| 2034 } | 2038 } |
| 2035 | 2039 |
| 2036 FunctionSignature get functionSignature { | 2040 FunctionSignature get functionSignature { |
| 2037 assert(invariant(this, hasFunctionSignature, | 2041 assert(hasFunctionSignature, |
| 2038 message: "Function signature has not been computed for $this.")); | 2042 failedAt(this, "Function signature has not been computed for $this.")); |
| 2039 return _functionSignatureCache; | 2043 return _functionSignatureCache; |
| 2040 } | 2044 } |
| 2041 | 2045 |
| 2042 void set functionSignature(FunctionSignature value) { | 2046 void set functionSignature(FunctionSignature value) { |
| 2043 // TODO(johnniwinther): Strengthen the invariant to `!hasFunctionSignature` | 2047 // TODO(johnniwinther): Strengthen the invariant to `!hasFunctionSignature` |
| 2044 // when checked mode checks are not enqueued eagerly. | 2048 // when checked mode checks are not enqueued eagerly. |
| 2045 assert(invariant(this, !hasFunctionSignature || type == value.type, | 2049 assert( |
| 2046 message: "Function signature has already been computed for $this.")); | 2050 !hasFunctionSignature || type == value.type, |
| 2051 failedAt( |
| 2052 this, "Function signature has already been computed for $this.")); |
| 2047 _functionSignatureCache = value; | 2053 _functionSignatureCache = value; |
| 2048 typeCache = _functionSignatureCache.type; | 2054 typeCache = _functionSignatureCache.type; |
| 2049 } | 2055 } |
| 2050 | 2056 |
| 2051 List<ParameterElement> get parameters { | 2057 List<ParameterElement> get parameters { |
| 2052 // TODO(johnniwinther): Store the list directly, possibly by using List | 2058 // TODO(johnniwinther): Store the list directly, possibly by using List |
| 2053 // instead of Link in FunctionSignature. | 2059 // instead of Link in FunctionSignature. |
| 2054 List<ParameterElement> list = <ParameterElement>[]; | 2060 List<ParameterElement> list = <ParameterElement>[]; |
| 2055 functionSignature.forEachParameter((e) => list.add(e)); | 2061 functionSignature.forEachParameter((e) => list.add(e)); |
| 2056 return list; | 2062 return list; |
| 2057 } | 2063 } |
| 2058 | 2064 |
| 2059 ResolutionFunctionType computeType(Resolution resolution) { | 2065 ResolutionFunctionType computeType(Resolution resolution) { |
| 2060 if (typeCache != null) return typeCache; | 2066 if (typeCache != null) return typeCache; |
| 2061 _computeSignature(resolution); | 2067 _computeSignature(resolution); |
| 2062 assert(invariant(this, typeCache != null, | 2068 assert(typeCache != null, |
| 2063 message: "Type cache expected to be set on $this.")); | 2069 failedAt(this, "Type cache expected to be set on $this.")); |
| 2064 return typeCache; | 2070 return typeCache; |
| 2065 } | 2071 } |
| 2066 | 2072 |
| 2067 ResolutionFunctionType get type { | 2073 ResolutionFunctionType get type { |
| 2068 assert(invariant(this, typeCache != null, | 2074 assert(typeCache != null, |
| 2069 message: "Type has not been computed for $this.")); | 2075 failedAt(this, "Type has not been computed for $this.")); |
| 2070 return typeCache; | 2076 return typeCache; |
| 2071 } | 2077 } |
| 2072 | 2078 |
| 2073 FunctionElement asFunctionElement() => this; | 2079 FunctionElement asFunctionElement() => this; |
| 2074 | 2080 |
| 2075 @override | 2081 @override |
| 2076 Scope buildScope() => new TypeDeclarationScope(super.buildScope(), this); | 2082 Scope buildScope() => new TypeDeclarationScope(super.buildScope(), this); |
| 2077 | 2083 |
| 2078 String toString() { | 2084 String toString() { |
| 2079 if (isPatch) { | 2085 if (isPatch) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2221 _constantConstructor = computeConstantConstructor(resolvedAst); | 2227 _constantConstructor = computeConstantConstructor(resolvedAst); |
| 2222 } | 2228 } |
| 2223 return _constantConstructor; | 2229 return _constantConstructor; |
| 2224 } | 2230 } |
| 2225 | 2231 |
| 2226 void set constantConstructor(ConstantConstructor value) { | 2232 void set constantConstructor(ConstantConstructor value) { |
| 2227 if (isPatch) { | 2233 if (isPatch) { |
| 2228 ConstantConstructorMixin originConstructor = origin; | 2234 ConstantConstructorMixin originConstructor = origin; |
| 2229 originConstructor.constantConstructor = value; | 2235 originConstructor.constantConstructor = value; |
| 2230 } else { | 2236 } else { |
| 2231 assert(invariant(this, isConst, | 2237 assert( |
| 2232 message: "Constant constructor set on non-constant " | 2238 isConst, |
| 2239 failedAt( |
| 2240 this, |
| 2241 "Constant constructor set on non-constant " |
| 2233 "constructor $this.")); | 2242 "constructor $this.")); |
| 2234 assert(invariant(this, !isFromEnvironmentConstructor, | 2243 assert( |
| 2235 message: "Constant constructor set on fromEnvironment " | 2244 !isFromEnvironmentConstructor, |
| 2245 failedAt( |
| 2246 this, |
| 2247 "Constant constructor set on fromEnvironment " |
| 2236 "constructor: $this.")); | 2248 "constructor: $this.")); |
| 2237 assert(invariant( | 2249 assert( |
| 2238 this, _constantConstructor == null || _constantConstructor == value, | 2250 _constantConstructor == null || _constantConstructor == value, |
| 2239 message: "Constant constructor already computed for $this:" | 2251 failedAt( |
| 2252 this, |
| 2253 "Constant constructor already computed for $this:" |
| 2240 "Existing: $_constantConstructor, new: $value")); | 2254 "Existing: $_constantConstructor, new: $value")); |
| 2241 _constantConstructor = value; | 2255 _constantConstructor = value; |
| 2242 } | 2256 } |
| 2243 } | 2257 } |
| 2244 | 2258 |
| 2245 /// Returns the empty list of type variables by default. | 2259 /// Returns the empty list of type variables by default. |
| 2246 @override | 2260 @override |
| 2247 List<ResolutionDartType> get typeVariables => functionSignature.typeVariables; | 2261 List<ResolutionDartType> get typeVariables => functionSignature.typeVariables; |
| 2248 } | 2262 } |
| 2249 | 2263 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2284 return patch.hasEffectiveTarget; | 2298 return patch.hasEffectiveTarget; |
| 2285 } | 2299 } |
| 2286 return effectiveTargetInternal != null; | 2300 return effectiveTargetInternal != null; |
| 2287 } | 2301 } |
| 2288 | 2302 |
| 2289 void setImmediateRedirectionTarget( | 2303 void setImmediateRedirectionTarget( |
| 2290 ConstructorElement target, PrefixElement prefix) { | 2304 ConstructorElement target, PrefixElement prefix) { |
| 2291 if (isPatched) { | 2305 if (isPatched) { |
| 2292 patch.setImmediateRedirectionTarget(target, prefix); | 2306 patch.setImmediateRedirectionTarget(target, prefix); |
| 2293 } else { | 2307 } else { |
| 2294 assert(invariant(this, _immediateRedirectionTarget == null, | 2308 assert( |
| 2295 message: "Immediate redirection target has already been " | 2309 _immediateRedirectionTarget == null, |
| 2296 "set on $this.")); | 2310 failedAt(this, |
| 2311 "Immediate redirection target has already been set on $this.")); |
| 2297 _immediateRedirectionTarget = target; | 2312 _immediateRedirectionTarget = target; |
| 2298 _redirectionDeferredPrefix = prefix; | 2313 _redirectionDeferredPrefix = prefix; |
| 2299 } | 2314 } |
| 2300 } | 2315 } |
| 2301 | 2316 |
| 2302 ConstructorElement get immediateRedirectionTarget { | 2317 ConstructorElement get immediateRedirectionTarget { |
| 2303 if (isPatched) { | 2318 if (isPatched) { |
| 2304 return patch.immediateRedirectionTarget; | 2319 return patch.immediateRedirectionTarget; |
| 2305 } | 2320 } |
| 2306 return _immediateRedirectionTarget; | 2321 return _immediateRedirectionTarget; |
| 2307 } | 2322 } |
| 2308 | 2323 |
| 2309 PrefixElement get redirectionDeferredPrefix { | 2324 PrefixElement get redirectionDeferredPrefix { |
| 2310 if (isPatched) { | 2325 if (isPatched) { |
| 2311 return patch.redirectionDeferredPrefix; | 2326 return patch.redirectionDeferredPrefix; |
| 2312 } | 2327 } |
| 2313 return _redirectionDeferredPrefix; | 2328 return _redirectionDeferredPrefix; |
| 2314 } | 2329 } |
| 2315 | 2330 |
| 2316 void setEffectiveTarget(ConstructorElement target, ResolutionDartType type, | 2331 void setEffectiveTarget(ConstructorElement target, ResolutionDartType type, |
| 2317 {bool isMalformed: false}) { | 2332 {bool isMalformed: false}) { |
| 2318 if (isPatched) { | 2333 if (isPatched) { |
| 2319 patch.setEffectiveTarget(target, type, isMalformed: isMalformed); | 2334 patch.setEffectiveTarget(target, type, isMalformed: isMalformed); |
| 2320 } else { | 2335 } else { |
| 2321 assert(invariant(this, target != null, | 2336 assert(target != null, |
| 2322 message: 'No effective target provided for $this.')); | 2337 failedAt(this, 'No effective target provided for $this.')); |
| 2323 assert(invariant(this, effectiveTargetInternal == null, | 2338 assert( |
| 2324 message: 'Effective target has already been computed for $this.')); | 2339 effectiveTargetInternal == null, |
| 2325 assert(invariant(this, !target.isMalformed || isMalformed, | 2340 failedAt( |
| 2326 message: 'Effective target is not marked as malformed for $this: ' | 2341 this, 'Effective target has already been computed for $this.')); |
| 2342 assert( |
| 2343 !target.isMalformed || isMalformed, |
| 2344 failedAt( |
| 2345 this, |
| 2346 'Effective target is not marked as malformed for $this: ' |
| 2327 'target=$target, type=$type, isMalformed: $isMalformed')); | 2347 'target=$target, type=$type, isMalformed: $isMalformed')); |
| 2328 assert(invariant(this, isMalformed || type.isInterfaceType, | 2348 assert( |
| 2329 message: 'Effective target type is not an interface type for $this: ' | 2349 isMalformed || type.isInterfaceType, |
| 2350 failedAt( |
| 2351 this, |
| 2352 'Effective target type is not an interface type for $this: ' |
| 2330 'target=$target, type=$type, isMalformed: $isMalformed')); | 2353 'target=$target, type=$type, isMalformed: $isMalformed')); |
| 2331 effectiveTargetInternal = target; | 2354 effectiveTargetInternal = target; |
| 2332 _effectiveTargetType = type; | 2355 _effectiveTargetType = type; |
| 2333 _isEffectiveTargetMalformed = isMalformed; | 2356 _isEffectiveTargetMalformed = isMalformed; |
| 2334 } | 2357 } |
| 2335 } | 2358 } |
| 2336 | 2359 |
| 2337 ConstructorElement get effectiveTarget { | 2360 ConstructorElement get effectiveTarget { |
| 2338 if (isPatched) { | 2361 if (isPatched) { |
| 2339 return patch.effectiveTarget; | 2362 return patch.effectiveTarget; |
| 2340 } | 2363 } |
| 2341 if (isRedirectingFactory) { | 2364 if (isRedirectingFactory) { |
| 2342 assert(effectiveTargetInternal != null); | 2365 assert(effectiveTargetInternal != null); |
| 2343 return effectiveTargetInternal; | 2366 return effectiveTargetInternal; |
| 2344 } | 2367 } |
| 2345 return this; | 2368 return this; |
| 2346 } | 2369 } |
| 2347 | 2370 |
| 2348 ResolutionDartType get effectiveTargetType { | 2371 ResolutionDartType get effectiveTargetType { |
| 2349 if (isPatched) { | 2372 if (isPatched) { |
| 2350 return patch.effectiveTargetType; | 2373 return patch.effectiveTargetType; |
| 2351 } | 2374 } |
| 2352 assert(invariant(this, _effectiveTargetType != null, | 2375 assert( |
| 2353 message: 'Effective target type has not yet been computed for $this.')); | 2376 _effectiveTargetType != null, |
| 2377 failedAt(this, |
| 2378 'Effective target type has not yet been computed for $this.')); |
| 2354 return _effectiveTargetType; | 2379 return _effectiveTargetType; |
| 2355 } | 2380 } |
| 2356 | 2381 |
| 2357 ResolutionDartType computeEffectiveTargetType( | 2382 ResolutionDartType computeEffectiveTargetType( |
| 2358 ResolutionInterfaceType newType) { | 2383 ResolutionInterfaceType newType) { |
| 2359 if (isPatched) { | 2384 if (isPatched) { |
| 2360 return patch.computeEffectiveTargetType(newType); | 2385 return patch.computeEffectiveTargetType(newType); |
| 2361 } | 2386 } |
| 2362 if (!isRedirectingFactory) return newType; | 2387 if (!isRedirectingFactory) return newType; |
| 2363 return effectiveTargetType.substByContext(newType); | 2388 return effectiveTargetType.substByContext(newType); |
| 2364 } | 2389 } |
| 2365 | 2390 |
| 2366 bool get isEffectiveTargetMalformed { | 2391 bool get isEffectiveTargetMalformed { |
| 2367 if (isPatched) { | 2392 if (isPatched) { |
| 2368 return patch.isEffectiveTargetMalformed; | 2393 return patch.isEffectiveTargetMalformed; |
| 2369 } | 2394 } |
| 2370 if (!isRedirectingFactory) return false; | 2395 if (!isRedirectingFactory) return false; |
| 2371 assert(invariant(this, _isEffectiveTargetMalformed != null, | 2396 assert(_isEffectiveTargetMalformed != null, |
| 2372 message: 'Malformedness has not yet been computed for $this.')); | 2397 failedAt(this, 'Malformedness has not yet been computed for $this.')); |
| 2373 return _isEffectiveTargetMalformed == true; | 2398 return _isEffectiveTargetMalformed == true; |
| 2374 } | 2399 } |
| 2375 | 2400 |
| 2376 accept(ElementVisitor visitor, arg) { | 2401 accept(ElementVisitor visitor, arg) { |
| 2377 return visitor.visitConstructorElement(this, arg); | 2402 return visitor.visitConstructorElement(this, arg); |
| 2378 } | 2403 } |
| 2379 | 2404 |
| 2380 ConstructorElement get definingConstructor => null; | 2405 ConstructorElement get definingConstructor => null; |
| 2381 | 2406 |
| 2382 ClassElement get enclosingClass => enclosingElement.declaration; | 2407 ClassElement get enclosingClass => enclosingElement.declaration; |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2625 * [:List:] class element whereas [:List<dynamic>:] should be its own | 2650 * [:List:] class element whereas [:List<dynamic>:] should be its own |
| 2626 * instantiation of [ResolutionInterfaceType] with [:dynamic:] as type | 2651 * instantiation of [ResolutionInterfaceType] with [:dynamic:] as type |
| 2627 * argument. Using this distinction, we can print the raw type with type | 2652 * argument. Using this distinction, we can print the raw type with type |
| 2628 * arguments only when the input source has used explicit type arguments. | 2653 * arguments only when the input source has used explicit type arguments. |
| 2629 * | 2654 * |
| 2630 * This type is computed together with [thisType] in [computeType]. | 2655 * This type is computed together with [thisType] in [computeType]. |
| 2631 */ | 2656 */ |
| 2632 T rawTypeCache; | 2657 T rawTypeCache; |
| 2633 | 2658 |
| 2634 T get thisType { | 2659 T get thisType { |
| 2635 assert(invariant(this, thisTypeCache != null, | 2660 assert(thisTypeCache != null, |
| 2636 message: 'This type has not been computed for $this')); | 2661 failedAt(this, 'This type has not been computed for $this')); |
| 2637 return thisTypeCache; | 2662 return thisTypeCache; |
| 2638 } | 2663 } |
| 2639 | 2664 |
| 2640 T get rawType { | 2665 T get rawType { |
| 2641 assert(invariant(this, rawTypeCache != null, | 2666 assert(rawTypeCache != null, |
| 2642 message: 'Raw type has not been computed for $this')); | 2667 failedAt(this, 'Raw type has not been computed for $this')); |
| 2643 return rawTypeCache; | 2668 return rawTypeCache; |
| 2644 } | 2669 } |
| 2645 | 2670 |
| 2646 T createType(List<ResolutionDartType> typeArguments); | 2671 T createType(List<ResolutionDartType> typeArguments); |
| 2647 | 2672 |
| 2648 void setThisAndRawTypes(List<ResolutionDartType> typeParameters) { | 2673 void setThisAndRawTypes(List<ResolutionDartType> typeParameters) { |
| 2649 assert(invariant(this, thisTypeCache == null, | 2674 assert(thisTypeCache == null, |
| 2650 message: "This type has already been set on $this.")); | 2675 failedAt(this, "This type has already been set on $this.")); |
| 2651 assert(invariant(this, rawTypeCache == null, | 2676 assert(rawTypeCache == null, |
| 2652 message: "Raw type has already been set on $this.")); | 2677 failedAt(this, "Raw type has already been set on $this.")); |
| 2653 thisTypeCache = createType(typeParameters); | 2678 thisTypeCache = createType(typeParameters); |
| 2654 if (typeParameters.isEmpty) { | 2679 if (typeParameters.isEmpty) { |
| 2655 rawTypeCache = thisTypeCache; | 2680 rawTypeCache = thisTypeCache; |
| 2656 } else { | 2681 } else { |
| 2657 List<ResolutionDartType> dynamicParameters = | 2682 List<ResolutionDartType> dynamicParameters = |
| 2658 new List.filled(typeParameters.length, const ResolutionDynamicType()); | 2683 new List.filled(typeParameters.length, const ResolutionDynamicType()); |
| 2659 rawTypeCache = createType(dynamicParameters); | 2684 rawTypeCache = createType(dynamicParameters); |
| 2660 } | 2685 } |
| 2661 } | 2686 } |
| 2662 | 2687 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2749 } | 2774 } |
| 2750 | 2775 |
| 2751 @override | 2776 @override |
| 2752 ResolutionInterfaceType createType(List<ResolutionDartType> typeArguments) { | 2777 ResolutionInterfaceType createType(List<ResolutionDartType> typeArguments) { |
| 2753 return new ResolutionInterfaceType(this, typeArguments); | 2778 return new ResolutionInterfaceType(this, typeArguments); |
| 2754 } | 2779 } |
| 2755 | 2780 |
| 2756 List<ResolutionDartType> computeTypeParameters(ParsingContext parsing); | 2781 List<ResolutionDartType> computeTypeParameters(ParsingContext parsing); |
| 2757 | 2782 |
| 2758 bool get isObject { | 2783 bool get isObject { |
| 2759 assert(invariant(this, isResolved, | 2784 assert(isResolved, |
| 2760 message: "isObject has not been computed for $this.")); | 2785 failedAt(this, "isObject has not been computed for $this.")); |
| 2761 return supertype == null; | 2786 return supertype == null; |
| 2762 } | 2787 } |
| 2763 | 2788 |
| 2764 void ensureResolved(Resolution resolution) { | 2789 void ensureResolved(Resolution resolution) { |
| 2765 if (resolutionState == STATE_NOT_STARTED) { | 2790 if (resolutionState == STATE_NOT_STARTED) { |
| 2766 resolution.resolveClass(this); | 2791 resolution.resolveClass(this); |
| 2767 resolution.registerClass(this); | 2792 resolution.registerClass(this); |
| 2768 } | 2793 } |
| 2769 } | 2794 } |
| 2770 | 2795 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2783 } | 2808 } |
| 2784 return null; | 2809 return null; |
| 2785 } | 2810 } |
| 2786 | 2811 |
| 2787 /** | 2812 /** |
| 2788 * Returns the super class, if any. | 2813 * Returns the super class, if any. |
| 2789 * | 2814 * |
| 2790 * The returned element may not be resolved yet. | 2815 * The returned element may not be resolved yet. |
| 2791 */ | 2816 */ |
| 2792 ClassElement get superclass { | 2817 ClassElement get superclass { |
| 2793 assert(invariant(this, supertypeLoadState == STATE_DONE, | 2818 assert(supertypeLoadState == STATE_DONE, |
| 2794 message: "Superclass has not been computed for $this.")); | 2819 failedAt(this, "Superclass has not been computed for $this.")); |
| 2795 return supertype == null ? null : supertype.element; | 2820 return supertype == null ? null : supertype.element; |
| 2796 } | 2821 } |
| 2797 | 2822 |
| 2798 // TODO(johnniwinther): Remove these when issue 18630 is fixed. | 2823 // TODO(johnniwinther): Remove these when issue 18630 is fixed. |
| 2799 ClassElement get patch => super.patch; | 2824 ClassElement get patch => super.patch; |
| 2800 ClassElement get origin => super.origin; | 2825 ClassElement get origin => super.origin; |
| 2801 | 2826 |
| 2802 // A class declaration is defined by the declaration element. | 2827 // A class declaration is defined by the declaration element. |
| 2803 AstElement get definingElement => declaration; | 2828 AstElement get definingElement => declaration; |
| 2804 } | 2829 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2926 | 2951 |
| 2927 @override | 2952 @override |
| 2928 accept(ElementVisitor visitor, arg) { | 2953 accept(ElementVisitor visitor, arg) { |
| 2929 return visitor.visitEnumClassElement(this, arg); | 2954 return visitor.visitEnumClassElement(this, arg); |
| 2930 } | 2955 } |
| 2931 | 2956 |
| 2932 List<ResolutionDartType> computeTypeParameters(ParsingContext parsing) => | 2957 List<ResolutionDartType> computeTypeParameters(ParsingContext parsing) => |
| 2933 const <ResolutionDartType>[]; | 2958 const <ResolutionDartType>[]; |
| 2934 | 2959 |
| 2935 List<FieldElement> get enumValues { | 2960 List<FieldElement> get enumValues { |
| 2936 assert(invariant(this, _enumValues != null, | 2961 assert(_enumValues != null, |
| 2937 message: "enumValues has not been computed for $this.")); | 2962 failedAt(this, "enumValues has not been computed for $this.")); |
| 2938 return _enumValues; | 2963 return _enumValues; |
| 2939 } | 2964 } |
| 2940 | 2965 |
| 2941 void set enumValues(List<FieldElement> values) { | 2966 void set enumValues(List<FieldElement> values) { |
| 2942 assert(invariant(this, _enumValues == null, | 2967 assert(_enumValues == null, |
| 2943 message: "enumValues has already been computed for $this.")); | 2968 failedAt(this, "enumValues has already been computed for $this.")); |
| 2944 _enumValues = values; | 2969 _enumValues = values; |
| 2945 } | 2970 } |
| 2946 | 2971 |
| 2947 @override | 2972 @override |
| 2948 DeclarationSite get declarationSite => this; | 2973 DeclarationSite get declarationSite => this; |
| 2949 } | 2974 } |
| 2950 | 2975 |
| 2951 /// This element is used to encode the implicit constructor in an enum class. | 2976 /// This element is used to encode the implicit constructor in an enum class. |
| 2952 /// | 2977 /// |
| 2953 /// For instance | 2978 /// For instance |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3319 | 3344 |
| 3320 TypeVariableElementX( | 3345 TypeVariableElementX( |
| 3321 String name, GenericElement enclosing, this.index, this.node) | 3346 String name, GenericElement enclosing, this.index, this.node) |
| 3322 : super(name, ElementKind.TYPE_VARIABLE, enclosing); | 3347 : super(name, ElementKind.TYPE_VARIABLE, enclosing); |
| 3323 | 3348 |
| 3324 GenericElement get typeDeclaration => enclosingElement; | 3349 GenericElement get typeDeclaration => enclosingElement; |
| 3325 | 3350 |
| 3326 ResolutionTypeVariableType computeType(Resolution resolution) => type; | 3351 ResolutionTypeVariableType computeType(Resolution resolution) => type; |
| 3327 | 3352 |
| 3328 ResolutionTypeVariableType get type { | 3353 ResolutionTypeVariableType get type { |
| 3329 assert(invariant(this, typeCache != null, | 3354 assert( |
| 3330 message: "Type has not been set on $this.")); | 3355 typeCache != null, failedAt(this, "Type has not been set on $this.")); |
| 3331 return typeCache; | 3356 return typeCache; |
| 3332 } | 3357 } |
| 3333 | 3358 |
| 3334 ResolutionDartType get bound { | 3359 ResolutionDartType get bound { |
| 3335 assert(invariant(this, boundCache != null, | 3360 assert( |
| 3336 message: "Bound has not been set on $this.")); | 3361 boundCache != null, failedAt(this, "Bound has not been set on $this.")); |
| 3337 return boundCache; | 3362 return boundCache; |
| 3338 } | 3363 } |
| 3339 | 3364 |
| 3340 bool get hasNode => true; | 3365 bool get hasNode => true; |
| 3341 | 3366 |
| 3342 Node parseNode(ParsingContext parsing) => node; | 3367 Node parseNode(ParsingContext parsing) => node; |
| 3343 | 3368 |
| 3344 Token get position => node.getBeginToken(); | 3369 Token get position => node.getBeginToken(); |
| 3345 | 3370 |
| 3346 accept(ElementVisitor visitor, arg) { | 3371 accept(ElementVisitor visitor, arg) { |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3445 bool get isPatched => patch != null; | 3470 bool get isPatched => patch != null; |
| 3446 | 3471 |
| 3447 bool get isImplementation => !isPatched; | 3472 bool get isImplementation => !isPatched; |
| 3448 bool get isDeclaration => !isPatch; | 3473 bool get isDeclaration => !isPatch; |
| 3449 | 3474 |
| 3450 Element /*E*/ get implementation => isPatched ? patch : this; | 3475 Element /*E*/ get implementation => isPatched ? patch : this; |
| 3451 Element /*E*/ get declaration => isPatch ? origin : this; | 3476 Element /*E*/ get declaration => isPatch ? origin : this; |
| 3452 | 3477 |
| 3453 /// Applies a patch to this element. This method must be called at most once. | 3478 /// Applies a patch to this element. This method must be called at most once. |
| 3454 void applyPatch(PatchMixin<E> patch) { | 3479 void applyPatch(PatchMixin<E> patch) { |
| 3455 assert(invariant(this, this.patch == null, | 3480 assert(this.patch == null, failedAt(this, "Element is patched twice.")); |
| 3456 message: "Element is patched twice.")); | 3481 assert(this.origin == null, failedAt(this, "Origin element is a patch.")); |
| 3457 assert(invariant(this, this.origin == null, | 3482 assert(patch.origin == null, failedAt(patch, "Element is patched twice.")); |
| 3458 message: "Origin element is a patch.")); | 3483 assert(patch.patch == null, failedAt(patch, "Patch element is patched.")); |
| 3459 assert(invariant(patch, patch.origin == null, | |
| 3460 message: "Element is patched twice.")); | |
| 3461 assert(invariant(patch, patch.patch == null, | |
| 3462 message: "Patch element is patched.")); | |
| 3463 this.patch = patch; | 3484 this.patch = patch; |
| 3464 patch.origin = this; | 3485 patch.origin = this; |
| 3465 } | 3486 } |
| 3466 } | 3487 } |
| 3467 | 3488 |
| 3468 /// Abstract implementation of the [AstElement] interface. | 3489 /// Abstract implementation of the [AstElement] interface. |
| 3469 abstract class AstElementMixin implements AstElement { | 3490 abstract class AstElementMixin implements AstElement { |
| 3470 /// The element whose node defines this element. | 3491 /// The element whose node defines this element. |
| 3471 /// | 3492 /// |
| 3472 /// For patched functions the defining element is the patch element found | 3493 /// For patched functions the defining element is the patch element found |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3491 body = node.asFunctionExpression().body; | 3512 body = node.asFunctionExpression().body; |
| 3492 } | 3513 } |
| 3493 return new ParsedResolvedAst( | 3514 return new ParsedResolvedAst( |
| 3494 declaration, | 3515 declaration, |
| 3495 node, | 3516 node, |
| 3496 body, | 3517 body, |
| 3497 definingElement.treeElements, | 3518 definingElement.treeElements, |
| 3498 definingElement.compilationUnit.script.resourceUri); | 3519 definingElement.compilationUnit.script.resourceUri); |
| 3499 } | 3520 } |
| 3500 } | 3521 } |
| OLD | NEW |