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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1274 [node]); | 1275 [node]); |
1275 } | 1276 } |
1276 } else if (element.isErroneous()) { | 1277 } else if (element.isErroneous()) { |
1277 element = warnOnErroneousElement(node, element); | 1278 element = warnOnErroneousElement(node, element); |
1278 } else { | 1279 } else { |
1279 if ((element.kind.category & allowedCategory) == 0) { | 1280 if ((element.kind.category & allowedCategory) == 0) { |
1280 // TODO(ahe): Improve error message. Need UX input. | 1281 // TODO(ahe): Improve error message. Need UX input. |
1281 error(node, MessageKind.GENERIC, ["is not an expression $element"]); | 1282 error(node, MessageKind.GENERIC, ["is not an expression $element"]); |
1282 } | 1283 } |
1283 } | 1284 } |
| 1285 if (!Elements.isUnresolved(element) |
| 1286 && element.kind == ElementKind.CLASS) { |
| 1287 ClassElement classElement = element; |
| 1288 classElement.ensureResolved(compiler); |
| 1289 } |
1284 return useElement(node, element); | 1290 return useElement(node, element); |
1285 } | 1291 } |
1286 } | 1292 } |
1287 | 1293 |
1288 Element visitTypeAnnotation(TypeAnnotation node) { | 1294 Element visitTypeAnnotation(TypeAnnotation node) { |
1289 DartType type = resolveTypeAnnotation(node); | 1295 DartType type = resolveTypeAnnotation(node); |
1290 if (type != null) { | 1296 if (type != null) { |
1291 if (inCheckContext) { | 1297 if (inCheckContext) { |
1292 compiler.enqueuer.resolution.registerIsCheck(type); | 1298 compiler.enqueuer.resolution.registerIsCheck(type); |
1293 } | 1299 } |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 error(node.selector, | 1505 error(node.selector, |
1500 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT, | 1506 MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT, |
1501 [selector.argumentCount]); | 1507 [selector.argumentCount]); |
1502 } else if (selector.namedArgumentCount != 0) { | 1508 } else if (selector.namedArgumentCount != 0) { |
1503 error(node.selector, | 1509 error(node.selector, |
1504 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS, | 1510 MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS, |
1505 [selector.namedArgumentCount]); | 1511 [selector.namedArgumentCount]); |
1506 } | 1512 } |
1507 return compiler.assertMethod; | 1513 return compiler.assertMethod; |
1508 } | 1514 } |
| 1515 |
1509 return node.selector.accept(this); | 1516 return node.selector.accept(this); |
1510 } | 1517 } |
1511 | 1518 |
1512 var oldCategory = allowedCategory; | 1519 var oldCategory = allowedCategory; |
1513 allowedCategory |= | 1520 allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER; |
1514 ElementCategory.CLASS | ElementCategory.PREFIX | ElementCategory.SUPER; | |
1515 Element resolvedReceiver = visit(node.receiver); | 1521 Element resolvedReceiver = visit(node.receiver); |
1516 allowedCategory = oldCategory; | 1522 allowedCategory = oldCategory; |
1517 | 1523 |
1518 Element target; | 1524 Element target; |
1519 SourceString name = node.selector.asIdentifier().source; | 1525 SourceString name = node.selector.asIdentifier().source; |
1520 if (identical(name.stringValue, 'this')) { | 1526 if (identical(name.stringValue, 'this')) { |
1521 error(node.selector, MessageKind.GENERIC, ["expected an identifier"]); | 1527 error(node.selector, MessageKind.GENERIC, ["expected an identifier"]); |
1522 } else if (node.isSuperCall) { | 1528 } else if (node.isSuperCall) { |
1523 if (node.isOperator) { | 1529 if (node.isOperator) { |
1524 if (isUserDefinableOperator(name.stringValue)) { | 1530 if (isUserDefinableOperator(name.stringValue)) { |
(...skipping 14 matching lines...) Expand all Loading... |
1539 // TODO(johnniwinther): Ensure correct behavior if currentClass is a | 1545 // TODO(johnniwinther): Ensure correct behavior if currentClass is a |
1540 // patch. | 1546 // patch. |
1541 target = currentClass.lookupSuperMember(name); | 1547 target = currentClass.lookupSuperMember(name); |
1542 // [target] may be null which means invoking noSuchMethod on | 1548 // [target] may be null which means invoking noSuchMethod on |
1543 // super. | 1549 // super. |
1544 } else if (Elements.isUnresolved(resolvedReceiver)) { | 1550 } else if (Elements.isUnresolved(resolvedReceiver)) { |
1545 return null; | 1551 return null; |
1546 } else if (identical(resolvedReceiver.kind, ElementKind.CLASS)) { | 1552 } else if (identical(resolvedReceiver.kind, ElementKind.CLASS)) { |
1547 ClassElement receiverClass = resolvedReceiver; | 1553 ClassElement receiverClass = resolvedReceiver; |
1548 receiverClass.ensureResolved(compiler); | 1554 receiverClass.ensureResolved(compiler); |
| 1555 if (node.isOperator) { |
| 1556 // When the resolved receiver is a class, we can have two cases: |
| 1557 // 1) a static send: C.foo, or |
| 1558 // 2) an operator send, where the receiver is a class literal: 'C + 1'. |
| 1559 // The following code that looks up the selector on the resolved |
| 1560 // receiver will treat the second as the invocation of a static operator |
| 1561 // if the resolved receiver is not null. |
| 1562 return null; |
| 1563 } |
1549 target = receiverClass.lookupLocalMember(name); | 1564 target = receiverClass.lookupLocalMember(name); |
1550 if (target == null) { | 1565 if (target == null) { |
1551 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1566 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
1552 // try to resolve injected elements if [currentClass] is in the patch | 1567 // try to resolve injected elements if [currentClass] is in the patch |
1553 // library of [receiverClass]. | 1568 // library of [receiverClass]. |
1554 | 1569 |
1555 // TODO(karlklose): this should be reported by the caller of | 1570 // TODO(karlklose): this should be reported by the caller of |
1556 // [resolveSend] to select better warning messages for getters and | 1571 // [resolveSend] to select better warning messages for getters and |
1557 // setters. | 1572 // setters. |
1558 return warnAndCreateErroneousElement(node, name, | 1573 return warnAndCreateErroneousElement(node, name, |
1559 MessageKind.METHOD_NOT_FOUND, | 1574 MessageKind.METHOD_NOT_FOUND, |
1560 [receiverClass.name, name]); | 1575 [receiverClass.name, name]); |
1561 } else if (target.isInstanceMember()) { | 1576 } else if (target.isInstanceMember()) { |
1562 error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]); | 1577 error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]); |
1563 } | 1578 } |
1564 } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { | 1579 } else if (identical(resolvedReceiver.kind, ElementKind.PREFIX)) { |
1565 PrefixElement prefix = resolvedReceiver; | 1580 PrefixElement prefix = resolvedReceiver; |
1566 target = prefix.lookupLocalMember(name); | 1581 target = prefix.lookupLocalMember(name); |
1567 if (target == null) { | 1582 if (Elements.isUnresolved(target)) { |
1568 return warnAndCreateErroneousElement( | 1583 return warnAndCreateErroneousElement( |
1569 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 1584 node, name, MessageKind.NO_SUCH_LIBRARY_MEMBER, |
1570 [prefix.name, name]); | 1585 [prefix.name, name]); |
| 1586 } else if (target.kind == ElementKind.CLASS) { |
| 1587 ClassElement classElement = target; |
| 1588 classElement.ensureResolved(compiler); |
1571 } | 1589 } |
1572 } | 1590 } |
1573 return target; | 1591 return target; |
1574 } | 1592 } |
1575 | 1593 |
1576 DartType resolveTypeTest(Node argument) { | 1594 DartType resolveTypeTest(Node argument) { |
1577 TypeAnnotation node = argument.asTypeAnnotation(); | 1595 TypeAnnotation node = argument.asTypeAnnotation(); |
1578 if (node == null) { | 1596 if (node == null) { |
1579 // node is of the form !Type. | 1597 // node is of the form !Type. |
1580 node = argument.asSend().receiver.asTypeAnnotation(); | 1598 node = argument.asSend().receiver.asTypeAnnotation(); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1700 | 1718 |
1701 if (node.isCall) { | 1719 if (node.isCall) { |
1702 if (Elements.isUnresolved(target) || | 1720 if (Elements.isUnresolved(target) || |
1703 target.isGetter() || | 1721 target.isGetter() || |
1704 Elements.isClosureSend(node, target)) { | 1722 Elements.isClosureSend(node, target)) { |
1705 // If we don't know what we're calling or if we are calling a getter, | 1723 // 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 | 1724 // we need to register that fact that we may be calling a closure |
1707 // with the same arguments. | 1725 // with the same arguments. |
1708 Selector call = new Selector.callClosureFrom(selector); | 1726 Selector call = new Selector.callClosureFrom(selector); |
1709 world.registerDynamicInvocation(call.name, call); | 1727 world.registerDynamicInvocation(call.name, call); |
| 1728 } else if (target.impliesType()) { |
| 1729 // We call 'call()' on a Type instance returned from the reference to a |
| 1730 // class or typedef literal. We do not need to register this call as a |
| 1731 // dynamic invocation, because we statically know what the target is. |
1710 } else if (!selector.applies(target, compiler)) { | 1732 } else if (!selector.applies(target, compiler)) { |
1711 warnArgumentMismatch(node, target); | 1733 warnArgumentMismatch(node, target); |
1712 } | 1734 } |
1713 } | 1735 } |
1714 | 1736 |
1715 // TODO(ngeoffray): Warn if target is null and the send is | 1737 // TODO(ngeoffray): Warn if target is null and the send is |
1716 // unqualified. | 1738 // unqualified. |
1717 useElement(node, target); | 1739 useElement(node, target); |
1718 registerSend(selector, target); | 1740 registerSend(selector, target); |
1719 return node.isPropertyAccess ? target : null; | 1741 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]); | 3012 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, [name]); |
2991 } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) { | 3013 } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) { |
2992 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, [name]); | 3014 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, [name]); |
2993 } else if (!identical(e.kind, ElementKind.CLASS) | 3015 } else if (!identical(e.kind, ElementKind.CLASS) |
2994 && !identical(e.kind, ElementKind.PREFIX)) { | 3016 && !identical(e.kind, ElementKind.PREFIX)) { |
2995 error(node, MessageKind.NOT_A_TYPE, [name]); | 3017 error(node, MessageKind.NOT_A_TYPE, [name]); |
2996 } | 3018 } |
2997 return e; | 3019 return e; |
2998 } | 3020 } |
2999 } | 3021 } |
OLD | NEW |