Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: lib/compiler/implementation/resolution/members.dart

Issue 10942028: Support class and typedef literals as expressions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698