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

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: Address Peter's comments. 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698