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 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1481 visit(node.condition); | 1482 visit(node.condition); |
1482 visit(node.thenPart); | 1483 visit(node.thenPart); |
1483 visit(node.elsePart); | 1484 visit(node.elsePart); |
1484 } | 1485 } |
1485 | 1486 |
1486 static bool isLogicalOperator(Identifier op) { | 1487 static bool isLogicalOperator(Identifier op) { |
1487 String str = op.source.stringValue; | 1488 String str = op.source.stringValue; |
1488 return (identical(str, '&&') || str == '||' || str == '!'); | 1489 return (identical(str, '&&') || str == '||' || str == '!'); |
1489 } | 1490 } |
1490 | 1491 |
1491 Element resolveSend(Send node) { | 1492 Element resolveSend(Send node) { |
ahe
2012/11/01 13:55:27
Mostly my own fault, but this method is crap. I re
karlklose
2012/11/01 14:34:20
I agree.
| |
1492 Selector selector = resolveSelector(node); | 1493 Selector selector = resolveSelector(node); |
1493 | 1494 |
1494 if (node.receiver == null) { | 1495 if (node.receiver == null) { |
1495 // If this send is of the form "assert(expr);", then | 1496 // If this send is of the form "assert(expr);", then |
1496 // this is an assertion. | 1497 // this is an assertion. |
1497 if (selector.isAssert()) { | 1498 if (selector.isAssert()) { |
1498 if (selector.argumentCount != 1) { | 1499 if (selector.argumentCount != 1) { |
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) { | |
ahe
2012/11/01 13:55:27
I think this belongs in visitIdentifier.
karlklose
2012/11/01 14:34:20
Done.
| |
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); | |
ahe
2012/11/01 13:55:27
Couldn't this code be merged with lines 1569-1571?
karlklose
2012/11/01 14:34:20
Done.
| |
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 (target == null) { |
ngeoffray
2012/11/01 09:57:59
Should you check isUnresolved here?
karlklose
2012/11/01 14:34:20
Done.
| |
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 |