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 1455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1466 constantCache = value; | 1466 constantCache = value; |
1467 } | 1467 } |
1468 } | 1468 } |
1469 | 1469 |
1470 abstract class VariableElementX extends ElementX | 1470 abstract class VariableElementX extends ElementX |
1471 with AstElementMixin, ConstantVariableMixin | 1471 with AstElementMixin, ConstantVariableMixin |
1472 implements VariableElement { | 1472 implements VariableElement { |
1473 final Token token; | 1473 final Token token; |
1474 final VariableList variables; | 1474 final VariableList variables; |
1475 VariableDefinitions definitionsCache; | 1475 VariableDefinitions definitionsCache; |
| 1476 Expression definitionCache; |
1476 Expression initializerCache; | 1477 Expression initializerCache; |
1477 | 1478 |
1478 Modifiers get modifiers => variables.modifiers; | 1479 Modifiers get modifiers => variables.modifiers; |
1479 | 1480 |
1480 VariableElementX(String name, ElementKind kind, Element enclosingElement, | 1481 VariableElementX(String name, ElementKind kind, Element enclosingElement, |
1481 VariableList variables, this.token) | 1482 VariableList variables, this.token) |
1482 : this.variables = variables, | 1483 : this.variables = variables, |
1483 super(name, kind, enclosingElement); | 1484 super(name, kind, enclosingElement); |
1484 | 1485 |
1485 // TODO(johnniwinther): Ensure that the [TreeElements] for this variable hold | 1486 // TODO(johnniwinther): Ensure that the [TreeElements] for this variable hold |
(...skipping 12 matching lines...) Expand all Loading... |
1498 AstElement get definingElement => this; | 1499 AstElement get definingElement => this; |
1499 | 1500 |
1500 bool get hasNode => definitionsCache != null; | 1501 bool get hasNode => definitionsCache != null; |
1501 | 1502 |
1502 VariableDefinitions get node { | 1503 VariableDefinitions get node { |
1503 assert(invariant(this, definitionsCache != null, | 1504 assert(invariant(this, definitionsCache != null, |
1504 message: "Node has not been computed for $this.")); | 1505 message: "Node has not been computed for $this.")); |
1505 return definitionsCache; | 1506 return definitionsCache; |
1506 } | 1507 } |
1507 | 1508 |
| 1509 /// Returns the node that defines this field. |
| 1510 /// |
| 1511 /// For instance in `var a, b = true`, the definitions nodes for fields 'a' |
| 1512 /// and 'b' are the nodes for `a` and `b = true`, respectively. |
| 1513 Expression get definition { |
| 1514 assert(invariant(this, definitionCache != null, |
| 1515 message: "Definition node has not been computed for $this.")); |
| 1516 return definitionCache; |
| 1517 } |
| 1518 |
1508 Expression get initializer { | 1519 Expression get initializer { |
1509 assert(invariant(this, definitionsCache != null, | 1520 assert(invariant(this, definitionsCache != null, |
1510 message: "Initializer has not been computed for $this.")); | 1521 message: "Initializer has not been computed for $this.")); |
1511 return initializerCache; | 1522 return initializerCache; |
1512 } | 1523 } |
1513 | 1524 |
1514 Node parseNode(ParsingContext parsing) { | 1525 Node parseNode(ParsingContext parsing) { |
1515 if (definitionsCache != null) return definitionsCache; | 1526 if (definitionsCache != null) return definitionsCache; |
1516 | 1527 |
1517 VariableDefinitions definitions = variables.parseNode(this, parsing); | 1528 VariableDefinitions definitions = variables.parseNode(this, parsing); |
1518 createDefinitions(definitions); | 1529 createDefinitions(definitions); |
1519 return definitionsCache; | 1530 return definitionsCache; |
1520 } | 1531 } |
1521 | 1532 |
1522 void createDefinitions(VariableDefinitions definitions) { | 1533 void createDefinitions(VariableDefinitions definitions) { |
1523 assert(invariant(this, definitionsCache == null, | 1534 assert(invariant(this, definitionsCache == null, |
1524 message: "VariableDefinitions has already been computed for $this.")); | 1535 message: "VariableDefinitions has already been computed for $this.")); |
1525 Expression node; | |
1526 int count = 0; | |
1527 for (Link<Node> link = definitions.definitions.nodes; | 1536 for (Link<Node> link = definitions.definitions.nodes; |
1528 !link.isEmpty; | 1537 !link.isEmpty; |
1529 link = link.tail) { | 1538 link = link.tail) { |
1530 Expression initializedIdentifier = link.head; | 1539 Expression initializedIdentifier = link.head; |
1531 Identifier identifier = initializedIdentifier.asIdentifier(); | 1540 Identifier identifier = initializedIdentifier.asIdentifier(); |
1532 if (identifier == null) { | 1541 if (identifier == null) { |
1533 SendSet sendSet = initializedIdentifier.asSendSet(); | 1542 SendSet sendSet = initializedIdentifier.asSendSet(); |
1534 identifier = sendSet.selector.asIdentifier(); | 1543 identifier = sendSet.selector.asIdentifier(); |
1535 if (identical(name, identifier.source)) { | 1544 if (identical(name, identifier.source)) { |
1536 node = initializedIdentifier; | 1545 definitionCache = initializedIdentifier; |
1537 initializerCache = sendSet.arguments.first; | 1546 initializerCache = sendSet.arguments.first; |
1538 } | 1547 } |
1539 } else if (identical(name, identifier.source)) { | 1548 } else if (identical(name, identifier.source)) { |
1540 node = initializedIdentifier; | 1549 definitionCache = initializedIdentifier; |
1541 } | 1550 } |
1542 count++; | |
1543 } | 1551 } |
1544 invariant(definitions, node != null, message: "Could not find '$name'."); | 1552 invariant(definitions, definitionCache != null, |
1545 if (count == 1) { | 1553 message: "Could not find '$name'."); |
1546 definitionsCache = definitions; | 1554 definitionsCache = definitions; |
1547 } else { | |
1548 // Create a [VariableDefinitions] node for the single definition of | |
1549 // [node]. | |
1550 definitionsCache = new VariableDefinitions( | |
1551 definitions.type, | |
1552 definitions.modifiers, | |
1553 new NodeList( | |
1554 definitions.definitions.beginToken, | |
1555 const Link<Node>().prepend(node), | |
1556 definitions.definitions.endToken)); | |
1557 } | |
1558 } | 1555 } |
1559 | 1556 |
1560 DartType computeType(Resolution resolution) { | 1557 DartType computeType(Resolution resolution) { |
1561 if (variables.type != null) return variables.type; | 1558 if (variables.type != null) return variables.type; |
1562 // Call [parseNode] to ensure that [definitionsCache] and [initializerCache] | 1559 // Call [parseNode] to ensure that [definitionsCache] and [initializerCache] |
1563 // are set as a consequence of calling [computeType]. | 1560 // are set as a consequence of calling [computeType]. |
1564 parseNode(resolution.parsingContext); | 1561 parseNode(resolution.parsingContext); |
1565 return variables.computeType(this, resolution); | 1562 return variables.computeType(this, resolution); |
1566 } | 1563 } |
1567 | 1564 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1652 bool get hasResolvedAst => false; | 1649 bool get hasResolvedAst => false; |
1653 | 1650 |
1654 ResolvedAst get resolvedAst { | 1651 ResolvedAst get resolvedAst { |
1655 throw new UnsupportedError("resolvedAst"); | 1652 throw new UnsupportedError("resolvedAst"); |
1656 } | 1653 } |
1657 | 1654 |
1658 DynamicType get type => const DynamicType(); | 1655 DynamicType get type => const DynamicType(); |
1659 | 1656 |
1660 Token get token => node.getBeginToken(); | 1657 Token get token => node.getBeginToken(); |
1661 | 1658 |
| 1659 get definitionCache { |
| 1660 throw new UnsupportedError("definitionCache"); |
| 1661 } |
| 1662 |
| 1663 set definitionCache(_) { |
| 1664 throw new UnsupportedError("definitionCache="); |
| 1665 } |
| 1666 |
1662 get initializerCache { | 1667 get initializerCache { |
1663 throw new UnsupportedError("initializerCache"); | 1668 throw new UnsupportedError("initializerCache"); |
1664 } | 1669 } |
1665 | 1670 |
1666 set initializerCache(_) { | 1671 set initializerCache(_) { |
1667 throw new UnsupportedError("initializerCache="); | 1672 throw new UnsupportedError("initializerCache="); |
1668 } | 1673 } |
1669 | 1674 |
1670 void createDefinitions(VariableDefinitions definitions) { | 1675 void createDefinitions(VariableDefinitions definitions) { |
1671 throw new UnsupportedError("createDefinitions"); | 1676 throw new UnsupportedError("createDefinitions"); |
1672 } | 1677 } |
1673 | 1678 |
1674 get initializer => null; | 1679 get initializer => null; |
1675 | 1680 |
| 1681 get definition => null; |
| 1682 |
1676 bool get isMalformed => true; | 1683 bool get isMalformed => true; |
1677 | 1684 |
1678 get nestedClosures { | 1685 get nestedClosures { |
1679 throw new UnsupportedError("nestedClosures"); | 1686 throw new UnsupportedError("nestedClosures"); |
1680 } | 1687 } |
1681 | 1688 |
1682 set nestedClosures(_) { | 1689 set nestedClosures(_) { |
1683 throw new UnsupportedError("nestedClosures="); | 1690 throw new UnsupportedError("nestedClosures="); |
1684 } | 1691 } |
1685 | 1692 |
(...skipping 1323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3009 /// where the `index` and `values` fields are encoded using this element. | 3016 /// where the `index` and `values` fields are encoded using this element. |
3010 /// | 3017 /// |
3011 class EnumFieldElementX extends FieldElementX { | 3018 class EnumFieldElementX extends FieldElementX { |
3012 EnumFieldElementX(Identifier name, EnumClassElementX enumClass, | 3019 EnumFieldElementX(Identifier name, EnumClassElementX enumClass, |
3013 VariableList variableList, Node definition, | 3020 VariableList variableList, Node definition, |
3014 [Expression initializer]) | 3021 [Expression initializer]) |
3015 : super(name, enumClass, variableList) { | 3022 : super(name, enumClass, variableList) { |
3016 definitionsCache = new VariableDefinitions( | 3023 definitionsCache = new VariableDefinitions( |
3017 null, variableList.modifiers, new NodeList.singleton(definition)); | 3024 null, variableList.modifiers, new NodeList.singleton(definition)); |
3018 initializerCache = initializer; | 3025 initializerCache = initializer; |
| 3026 definitionCache = definition; |
3019 } | 3027 } |
3020 | 3028 |
3021 @override | 3029 @override |
3022 SourceSpan get sourcePosition => enclosingClass.sourcePosition; | 3030 SourceSpan get sourcePosition => enclosingClass.sourcePosition; |
3023 } | 3031 } |
3024 | 3032 |
3025 /// This element is used to encode the constant value in an enum class. | 3033 /// This element is used to encode the constant value in an enum class. |
3026 /// | 3034 /// |
3027 /// For instance | 3035 /// For instance |
3028 /// | 3036 /// |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3394 body = node.asFunctionExpression().body; | 3402 body = node.asFunctionExpression().body; |
3395 } | 3403 } |
3396 return new ParsedResolvedAst( | 3404 return new ParsedResolvedAst( |
3397 declaration, | 3405 declaration, |
3398 node, | 3406 node, |
3399 body, | 3407 body, |
3400 definingElement.treeElements, | 3408 definingElement.treeElements, |
3401 definingElement.compilationUnit.script.resourceUri); | 3409 definingElement.compilationUnit.script.resourceUri); |
3402 } | 3410 } |
3403 } | 3411 } |
OLD | NEW |