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

Side by Side Diff: lib/compiler/implementation/resolver.dart

Issue 10942028: Support class and typedef literals as expressions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix two long lines. Created 8 years, 2 months 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 abstract class TreeElements { 5 abstract class TreeElements {
6 Element operator[](Node node); 6 Element operator[](Node node);
7 Selector getSelector(Send send); 7 Selector getSelector(Send send);
8 DartType getType(TypeAnnotation annotation); 8 DartType getType(TypeAnnotation annotation);
9 bool isParameterChecked(Element element); 9 bool isParameterChecked(Element element);
10 } 10 }
(...skipping 1395 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 return scope.lexicalLookup(const SourceString("assert")) !== null; 1406 return scope.lexicalLookup(const SourceString("assert")) !== null;
1407 } 1407 }
1408 1408
1409 /** Check if [node] is the expression of the current expression statement. */ 1409 /** Check if [node] is the expression of the current expression statement. */
1410 bool isExpressionStatementExpression(Node node) { 1410 bool isExpressionStatementExpression(Node node) {
1411 return currentExpressionStatement !== null && 1411 return currentExpressionStatement !== null &&
1412 currentExpressionStatement.expression === node; 1412 currentExpressionStatement.expression === node;
1413 } 1413 }
1414 1414
1415 Element resolveSend(Send node) { 1415 Element resolveSend(Send node) {
1416 void withAdditionalCategories(int categories, void f()) {
1417 var oldCategory = allowedCategory;
1418 allowedCategory |= categories;
1419 f();
1420 allowedCategory = oldCategory;
1421 }
1422
1416 Selector selector = resolveSelector(node); 1423 Selector selector = resolveSelector(node);
1417
1418 if (node.receiver === null) { 1424 if (node.receiver === null) {
1419 // If this send is the expression of an expression statement, and is on 1425 // If this send is the expression of an expression statement, and is of
1420 // the form "assert(expr);", and there is no declaration with name 1426 // the form "assert(expr);", and there is no declaration with name
1421 // "assert" in the lexical scope, then this is actually an assertion. 1427 // "assert" in the lexical scope, then this is actually an assertion.
1422 if (isExpressionStatementExpression(node) && 1428 if (isExpressionStatementExpression(node) &&
1423 selector.isAssertSyntax() && 1429 selector.isAssertSyntax() &&
1424 !isAssertInLexicalScope()) { 1430 !isAssertInLexicalScope()) {
1425 return compiler.assertMethod; 1431 return compiler.assertMethod;
1426 } 1432 }
1427 return node.selector.accept(this); 1433
1434 Element result;
1435 withAdditionalCategories(ElementCategory.CLASS, () {
1436 result = node.selector.accept(this);
1437 });
1438 return result;
1428 } 1439 }
1429 1440
1430 var oldCategory = allowedCategory; 1441 Element resolvedReceiver;
1431 allowedCategory |= 1442 withAdditionalCategories(
1432 ElementCategory.CLASS | ElementCategory.PREFIX | ElementCategory.SUPER; 1443 ElementCategory.CLASS | ElementCategory.PREFIX | ElementCategory.SUPER,
1433 Element resolvedReceiver = visit(node.receiver); 1444 () { resolvedReceiver = visit(node.receiver); });
1434 allowedCategory = oldCategory; 1445
1446 if (resolvedReceiver != null && node.isOperator
ahe 2012/10/08 09:09:36 I don't understand why it is important to test for
karlklose 2012/10/23 10:33:52 For class literals that are targets for operators,
1447 && resolvedReceiver.kind == ElementKind.CLASS) {
1448 // In operator expressions like 'Class + 1', the operator call goes the
1449 // instance of [Type] that is the result of the expression 'Class'.
1450 ClassElement classElement = resolvedReceiver;
1451 resolvedReceiver = null;
1452 // We still have to make sure that the class is resolved, because we need
1453 // to build its runtime type representation.
1454 classElement.ensureResolved(compiler);
1455 }
1435 1456
1436 Element target; 1457 Element target;
1437 SourceString name = node.selector.asIdentifier().source; 1458 SourceString name = node.selector.asIdentifier().source;
1438 if (name.stringValue === 'this') { 1459 if (name.stringValue === 'this') {
1439 error(node.selector, MessageKind.GENERIC, ["expected an identifier"]); 1460 error(node.selector, MessageKind.GENERIC, ["expected an identifier"]);
1440 } else if (node.isSuperCall) { 1461 } else if (node.isSuperCall) {
1441 if (node.isOperator) { 1462 if (node.isOperator) {
1442 if (isUserDefinableOperator(name.stringValue)) { 1463 if (isUserDefinableOperator(name.stringValue)) {
1443 name = selector.name; 1464 name = selector.name;
1444 } else { 1465 } else {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 string === '===' || string === '!==' || 1536 string === '===' || string === '!==' ||
1516 string === '>>>') { 1537 string === '>>>') {
1517 return null; 1538 return null;
1518 } 1539 }
1519 return node.arguments.isEmpty() 1540 return node.arguments.isEmpty()
1520 ? new Selector.unaryOperator(source) 1541 ? new Selector.unaryOperator(source)
1521 : new Selector.binaryOperator(source); 1542 : new Selector.binaryOperator(source);
1522 } 1543 }
1523 1544
1524 Identifier identifier = node.selector.asIdentifier(); 1545 Identifier identifier = node.selector.asIdentifier();
1525 if (node.isPropertyAccess) { 1546 if (node.isPropertyAccessOrTypeReference) {
1526 assert(!isSet); 1547 assert(!isSet);
1527 return new Selector.getter(identifier.source, library); 1548 return new Selector.getter(identifier.source, library);
1528 } else if (isSet) { 1549 } else if (isSet) {
1529 return new Selector.setter(identifier.source, library); 1550 return new Selector.setter(identifier.source, library);
1530 } 1551 }
1531 1552
1532 // Compute the arity and the list of named arguments. 1553 // Compute the arity and the list of named arguments.
1533 int arity = 0; 1554 int arity = 0;
1534 List<SourceString> named = <SourceString>[]; 1555 List<SourceString> named = <SourceString>[];
1535 for (Link<Node> link = node.argumentsNode.nodes; 1556 for (Link<Node> link = node.argumentsNode.nodes;
(...skipping 29 matching lines...) Expand all
1565 if (argument.asNamedArgument() != null) { 1586 if (argument.asNamedArgument() != null) {
1566 seenNamedArgument = true; 1587 seenNamedArgument = true;
1567 } else if (seenNamedArgument) { 1588 } else if (seenNamedArgument) {
1568 error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); 1589 error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED);
1569 } 1590 }
1570 } 1591 }
1571 } 1592 }
1572 1593
1573 visitSend(Send node) { 1594 visitSend(Send node) {
1574 Element target = resolveSend(node); 1595 Element target = resolveSend(node);
1575 if (!Elements.isUnresolved(target) 1596
1576 && target.kind == ElementKind.ABSTRACT_FIELD) { 1597 if (!Elements.isUnresolved(target)) {
1577 AbstractFieldElement field = target; 1598 if (target.kind == ElementKind.ABSTRACT_FIELD) {
1578 target = field.getter; 1599 AbstractFieldElement field = target;
1579 if (target == null && !inInstanceContext) { 1600 target = field.getter;
1580 target = 1601 if (target == null && !inInstanceContext) {
1581 warnAndCreateErroneousElement(node.selector, field.name, 1602 target =
1582 MessageKind.CANNOT_RESOLVE_GETTER, 1603 warnAndCreateErroneousElement(node.selector, field.name,
1583 [node.selector]); 1604 MessageKind.CANNOT_RESOLVE_GETTER,
1605 [node.selector]);
1606 }
1607 } else if (target.kind == ElementKind.CLASS) {
1608 ClassElement classElement = target;
1609 classElement.ensureResolved(compiler);
ahe 2012/10/08 09:09:36 Why is this not done in resolveSend?
karlklose 2012/10/23 10:33:52 Moved.
1584 } 1610 }
1585 } 1611 }
1586 1612
1587 bool resolvedArguments = false; 1613 bool resolvedArguments = false;
1588 if (node.isOperator) { 1614 if (node.isOperator) {
1589 String operatorString = node.selector.asOperator().source.stringValue; 1615 String operatorString = node.selector.asOperator().source.stringValue;
1590 if (operatorString === 'is' || operatorString === 'as') { 1616 if (operatorString === 'is' || operatorString === 'as') {
1591 assert(node.arguments.tail.isEmpty()); 1617 assert(node.arguments.tail.isEmpty());
1592 DartType type = resolveTypeTest(node.arguments.head); 1618 DartType type = resolveTypeTest(node.arguments.head);
1593 if (type != null) { 1619 if (type != null) {
(...skipping 27 matching lines...) Expand all
1621 target.isGetter() || 1647 target.isGetter() ||
1622 Elements.isClosureSend(node, target))) { 1648 Elements.isClosureSend(node, target))) {
1623 Selector call = new Selector.callClosureFrom(selector); 1649 Selector call = new Selector.callClosureFrom(selector);
1624 world.registerDynamicInvocation(call.name, call); 1650 world.registerDynamicInvocation(call.name, call);
1625 } 1651 }
1626 1652
1627 // TODO(ngeoffray): Warn if target is null and the send is 1653 // TODO(ngeoffray): Warn if target is null and the send is
1628 // unqualified. 1654 // unqualified.
1629 useElement(node, target); 1655 useElement(node, target);
1630 registerSend(selector, target); 1656 registerSend(selector, target);
1631 return node.isPropertyAccess ? target : null; 1657 return node.isPropertyAccessOrTypeReference ? target : null;
1632 } 1658 }
1633 1659
1634 visitSendSet(SendSet node) { 1660 visitSendSet(SendSet node) {
1635 Element target = resolveSend(node); 1661 Element target = resolveSend(node);
1662 if (!Elements.isUnresolved(target) && target.kind == ElementKind.CLASS) {
1663 ClassElement classElement = target;
1664 classElement.ensureResolved(compiler);
ahe 2012/10/08 09:09:36 Why is this not done in resolveSend?
karlklose 2012/10/23 10:33:52 Done.
1665 }
1636 Element setter = target; 1666 Element setter = target;
1637 Element getter = target; 1667 Element getter = target;
1638 SourceString operatorName = node.assignmentOperator.source; 1668 SourceString operatorName = node.assignmentOperator.source;
1639 String source = operatorName.stringValue; 1669 String source = operatorName.stringValue;
1640 bool isComplex = source !== '='; 1670 bool isComplex = source !== '=';
1641 if (!Elements.isUnresolved(target) 1671 if (!Elements.isUnresolved(target)
1642 && target.kind == ElementKind.ABSTRACT_FIELD) { 1672 && target.kind == ElementKind.ABSTRACT_FIELD) {
1643 AbstractFieldElement field = target; 1673 AbstractFieldElement field = target;
1644 setter = field.setter; 1674 setter = field.setter;
1645 getter = field.getter; 1675 getter = field.getter;
(...skipping 1491 matching lines...) Expand 10 before | Expand all | Expand 10 after
3137 return result; 3167 return result;
3138 } 3168 }
3139 Element lookup(SourceString name) => localLookup(name); 3169 Element lookup(SourceString name) => localLookup(name);
3140 Element lexicalLookup(SourceString name) => localLookup(name); 3170 Element lexicalLookup(SourceString name) => localLookup(name);
3141 3171
3142 Element add(Element newElement) { 3172 Element add(Element newElement) {
3143 throw "Cannot add an element in a patch library scope"; 3173 throw "Cannot add an element in a patch library scope";
3144 } 3174 }
3145 String toString() => 'PatchLibraryScope($origin,$patch)'; 3175 String toString() => 'PatchLibraryScope($origin,$patch)';
3146 } 3176 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698