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