OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of resolution; | 5 part of resolution; |
6 | 6 |
7 abstract class TreeElements { | 7 abstract class TreeElements { |
8 Element operator[](Node node); | 8 Element operator[](Node node); |
9 Selector getSelector(Send send); | 9 Selector getSelector(Send send); |
10 DartType getType(Node node); | 10 DartType getType(Node node); |
(...skipping 1158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 Element enclosingElement; | 1169 Element enclosingElement; |
1170 final TypeResolver typeResolver; | 1170 final TypeResolver typeResolver; |
1171 bool inInstanceContext; | 1171 bool inInstanceContext; |
1172 bool inCheckContext; | 1172 bool inCheckContext; |
1173 bool inCatchBlock; | 1173 bool inCatchBlock; |
1174 Scope scope; | 1174 Scope scope; |
1175 ClassElement currentClass; | 1175 ClassElement currentClass; |
1176 ExpressionStatement currentExpressionStatement; | 1176 ExpressionStatement currentExpressionStatement; |
1177 bool typeRequired = false; | 1177 bool typeRequired = false; |
1178 StatementScope statementScope; | 1178 StatementScope statementScope; |
1179 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; | 1179 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION |
| 1180 | ElementCategory.IMPLIES_TYPE; |
1180 | 1181 |
1181 ResolverVisitor(Compiler compiler, Element element, this.mapping) | 1182 ResolverVisitor(Compiler compiler, Element element, this.mapping) |
1182 : this.enclosingElement = element, | 1183 : this.enclosingElement = element, |
1183 // When the element is a field, we are actually resolving its | 1184 // When the element is a field, we are actually resolving its |
1184 // initial value, which should not have access to instance | 1185 // initial value, which should not have access to instance |
1185 // fields. | 1186 // fields. |
1186 inInstanceContext = (element.isInstanceMember() && !element.isField()) | 1187 inInstanceContext = (element.isInstanceMember() && !element.isField()) |
1187 || element.isGenerativeConstructor(), | 1188 || element.isGenerativeConstructor(), |
1188 this.currentClass = element.isMember() ? element.getEnclosingClass() | 1189 this.currentClass = element.isMember() ? element.getEnclosingClass() |
1189 : null, | 1190 : null, |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 error(node.selector, | 1500 error(node.selector, |
1500 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT, | 1501 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT, |
1501 [selector.argumentCount]); | 1502 [selector.argumentCount]); |
1502 } else if (selector.namedArgumentCount != 0) { | 1503 } else if (selector.namedArgumentCount != 0) { |
1503 error(node.selector, | 1504 error(node.selector, |
1504 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS, | 1505 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS, |
1505 [selector.namedArgumentCount]); | 1506 [selector.namedArgumentCount]); |
1506 } | 1507 } |
1507 return compiler.assertMethod; | 1508 return compiler.assertMethod; |
1508 } | 1509 } |
1509 return node.selector.accept(this); | 1510 |
| 1511 Element result = node.selector.accept(this); |
| 1512 if (result != null) { |
| 1513 if (result.kind == ElementKind.CLASS) { |
| 1514 ClassElement classElement = result; |
| 1515 classElement.ensureResolved(compiler); |
| 1516 } |
| 1517 } |
| 1518 return result; |
1510 } | 1519 } |
1511 | 1520 |
1512 var oldCategory = allowedCategory; | 1521 var oldCategory = allowedCategory; |
1513 allowedCategory |= | 1522 allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER; |
1514 ElementCategory.CLASS | ElementCategory.PREFIX | ElementCategory.SUPER; | |
1515 Element resolvedReceiver = visit(node.receiver); | 1523 Element resolvedReceiver = visit(node.receiver); |
1516 allowedCategory = oldCategory; | 1524 allowedCategory = oldCategory; |
1517 | 1525 |
| 1526 if (resolvedReceiver != null |
| 1527 && resolvedReceiver.kind == ElementKind.CLASS) { |
| 1528 ClassElement classElement = resolvedReceiver; |
| 1529 classElement.ensureResolved(compiler); |
| 1530 if (node.isOperator) { |
| 1531 // When the resolved receiver is a class, we can have two cases: |
| 1532 // 1) a static send: C.foo, or |
| 1533 // 2) an operator send, where the receiver is a class literal: 'C + 1'. |
| 1534 // The following code that looks up the selector on the resolved |
| 1535 // receiver will treat the second as the invocation of a static operator |
| 1536 // if the resolved receiver is not null. |
| 1537 resolvedReceiver = null; |
| 1538 } |
| 1539 } |
| 1540 |
1518 Element target; | 1541 Element target; |
1519 SourceString name = node.selector.asIdentifier().source; | 1542 SourceString name = node.selector.asIdentifier().source; |
1520 if (identical(name.stringValue, 'this')) { | 1543 if (identical(name.stringValue, 'this')) { |
1521 error(node.selector, MessageKind.GENERIC, ["expected an identifier"]); | 1544 error(node.selector, MessageKind.GENERIC, ["expected an identifier"]); |
1522 } else if (node.isSuperCall) { | 1545 } else if (node.isSuperCall) { |
1523 if (node.isOperator) { | 1546 if (node.isOperator) { |
1524 if (isUserDefinableOperator(name.stringValue)) { | 1547 if (isUserDefinableOperator(name.stringValue)) { |
1525 name = selector.name; | 1548 name = selector.name; |
1526 } else { | 1549 } else { |
1527 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, [name]); | 1550 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, [name]); |
(...skipping 29 matching lines...) Expand all Loading... |
1557 // setters. | 1580 // setters. |
1558 return warnAndCreateErroneousElement(node, name, | 1581 return warnAndCreateErroneousElement(node, name, |
1559 MessageKind.METHOD_NOT_FOUND, | 1582 MessageKind.METHOD_NOT_FOUND, |
1560 [receiverClass.name, name]); | 1583 [receiverClass.name, name]); |
1561 } else if (target.isInstanceMember()) { | 1584 } else if (target.isInstanceMember()) { |
1562 error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]); | 1585 error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]); |
1563 } | 1586 } |
1564 } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { | 1587 } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { |
1565 PrefixElement prefix = resolvedReceiver; | 1588 PrefixElement prefix = resolvedReceiver; |
1566 target = prefix.lookupLocalMember(name); | 1589 target = prefix.lookupLocalMember(name); |
1567 if (target == null) { | 1590 if (Elements.isUnresolved(target)) { |
1568 return warnAndCreateErroneousElement( | 1591 return warnAndCreateErroneousElement( |
1569 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 1592 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, |
1570 [prefix.name, name]); | 1593 [prefix.name, name]); |
| 1594 } else if (target.kind == ElementKind.CLASS) { |
| 1595 ClassElement classElement = target; |
| 1596 classElement.ensureResolved(compiler); |
1571 } | 1597 } |
1572 } | 1598 } |
1573 return target; | 1599 return target; |
1574 } | 1600 } |
1575 | 1601 |
1576 DartType resolveTypeTest(Node argument) { | 1602 DartType resolveTypeTest(Node argument) { |
1577 TypeAnnotation node = argument.asTypeAnnotation(); | 1603 TypeAnnotation node = argument.asTypeAnnotation(); |
1578 if (node == null) { | 1604 if (node == null) { |
1579 // node is of the form !Type. | 1605 // node is of the form !Type. |
1580 node = argument.asSend().receiver.asTypeAnnotation(); | 1606 node = argument.asSend().receiver.asTypeAnnotation(); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1700 | 1726 |
1701 if (node.isCall) { | 1727 if (node.isCall) { |
1702 if (Elements.isUnresolved(target) || | 1728 if (Elements.isUnresolved(target) || |
1703 target.isGetter() || | 1729 target.isGetter() || |
1704 Elements.isClosureSend(node, target)) { | 1730 Elements.isClosureSend(node, target)) { |
1705 // If we don't know what we're calling or if we are calling a getter, | 1731 // If we don't know what we're calling or if we are calling a getter, |
1706 // we need to register that fact that we may be calling a closure | 1732 // we need to register that fact that we may be calling a closure |
1707 // with the same arguments. | 1733 // with the same arguments. |
1708 Selector call = new Selector.callClosureFrom(selector); | 1734 Selector call = new Selector.callClosureFrom(selector); |
1709 world.registerDynamicInvocation(call.name, call); | 1735 world.registerDynamicInvocation(call.name, call); |
| 1736 } else if (target.impliesType()) { |
| 1737 // We call 'call()' on a Type instance returned from the reference to a |
| 1738 // class or typedef literal. We do not need to register this call as a |
| 1739 // dynamic invocation, because we statically know what the target is. |
1710 } else if (!selector.applies(target, compiler)) { | 1740 } else if (!selector.applies(target, compiler)) { |
1711 warnArgumentMismatch(node, target); | 1741 warnArgumentMismatch(node, target); |
1712 } | 1742 } |
1713 } | 1743 } |
1714 | 1744 |
1715 // TODO(ngeoffray): Warn if target is null and the send is | 1745 // TODO(ngeoffray): Warn if target is null and the send is |
1716 // unqualified. | 1746 // unqualified. |
1717 useElement(node, target); | 1747 useElement(node, target); |
1718 registerSend(selector, target); | 1748 registerSend(selector, target); |
1719 return node.isPropertyAccess ? target : null; | 1749 return node.isPropertyAccess ? target : null; |
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2990 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [name]); | 3020 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [name]); |
2991 } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) { | 3021 } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) { |
2992 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, [name]); | 3022 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, [name]); |
2993 } else if (!identical(e.kind, ElementKind.CLASS) | 3023 } else if (!identical(e.kind, ElementKind.CLASS) |
2994 && !identical(e.kind, ElementKind.PREFIX)) { | 3024 && !identical(e.kind, ElementKind.PREFIX)) { |
2995 error(node, MessageKind.NOT_A_TYPE, [name]); | 3025 error(node, MessageKind.NOT_A_TYPE, [name]); |
2996 } | 3026 } |
2997 return e; | 3027 return e; |
2998 } | 3028 } |
2999 } | 3029 } |
OLD | NEW |