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

Side by Side Diff: pkg/compiler/lib/src/resolution/members.dart

Issue 1185483004: Revert "Handle most qualified sends." (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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
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 /** 7 /**
8 * Core implementation of resolution. 8 * Core implementation of resolution.
9 * 9 *
10 * Do not subclass or instantiate this class outside this library 10 * Do not subclass or instantiate this class outside this library
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 if (node.isConditional) { 533 if (node.isConditional) {
534 sendIsMemberAccess = oldSendIsMemberAccess; 534 sendIsMemberAccess = oldSendIsMemberAccess;
535 allowedCategory = oldAllowedCategory; 535 allowedCategory = oldAllowedCategory;
536 } 536 }
537 537
538 allowedCategory = oldCategory; 538 allowedCategory = oldCategory;
539 539
540 Element target; 540 Element target;
541 String name = node.selector.asIdentifier().source; 541 String name = node.selector.asIdentifier().source;
542 if (identical(name, 'this')) { 542 if (identical(name, 'this')) {
543 error(node.selector, MessageKind.THIS_PROPERTY); 543 // TODO(ahe): Why is this using GENERIC?
544 error(node.selector, MessageKind.GENERIC,
545 {'text': "expected an identifier"});
544 return const NoneResult(); 546 return const NoneResult();
545 } else if (node.isSuperCall) { 547 } else if (node.isSuperCall) {
546 if (node.isOperator) { 548 if (node.isOperator) {
547 if (isUserDefinableOperator(name)) { 549 if (isUserDefinableOperator(name)) {
548 name = selector.name; 550 name = selector.name;
549 } else { 551 } else {
550 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name}); 552 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name});
551 return const NoneResult(); 553 return const NoneResult();
552 } 554 }
553 } 555 }
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 target = error; 950 target = error;
949 } 951 }
950 // We still need to register the invocation, because we might 952 // We still need to register the invocation, because we might
951 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. 953 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
952 registry.registerDynamicInvocation(selector); 954 registry.registerDynamicInvocation(selector);
953 registry.registerSuperNoSuchMethod(); 955 registry.registerSuperNoSuchMethod();
954 } 956 }
955 return computeSuperAccessSemantics(node, target); 957 return computeSuperAccessSemantics(node, target);
956 } 958 }
957 959
958 /// Resolve [node] as a subexpression that is _not_ the prefix of a member 960 /// Resolve [node] as subexpression that is _not_ the prefix of a member
959 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`. 961 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`.
960 ResolutionResult visitExpression(Node node) { 962 ResolutionResult visitExpression(Node node) {
961 bool oldSendIsMemberAccess = sendIsMemberAccess; 963 bool oldSendIsMemberAccess = sendIsMemberAccess;
962 sendIsMemberAccess = false; 964 sendIsMemberAccess = false;
963 ResolutionResult result = visit(node); 965 ResolutionResult result = visit(node);
964 sendIsMemberAccess = oldSendIsMemberAccess; 966 sendIsMemberAccess = oldSendIsMemberAccess;
965 return result; 967 return result;
966 } 968 }
967 969
968 /// Resolve [node] as a subexpression that _is_ the prefix of a member access.
969 /// For instance `a` in `a.b`, as opposed to `a` in `a + b`.
970 ResolutionResult visitExpressionPrefix(Node node) {
971 int oldAllowedCategory = allowedCategory;
972 bool oldSendIsMemberAccess = sendIsMemberAccess;
973 allowedCategory |= ElementCategory.PREFIX | ElementCategory.SUPER;
974 sendIsMemberAccess = true;
975 ResolutionResult result = visit(node);
976 sendIsMemberAccess = oldSendIsMemberAccess;
977 allowedCategory = oldAllowedCategory;
978 return result;
979 }
980
981 /// Resolved [node] as a subexpression that is the prefix of a conditional
982 /// access. For instance `a` in `a?.b`.
983 // TODO(johnniwinther): Is this equivalent to [visitExpression]?
984 ResolutionResult visitConditionalPrefix(Node node) {
985 // Conditional sends like `e?.foo` treat the receiver as an expression. So
986 // `C?.foo` needs to be treated like `(C).foo`, not like C.foo. Prefixes and
987 // super are not allowed on their own in that context.
988 int oldAllowedCategory = allowedCategory;
989 bool oldSendIsMemberAccess = sendIsMemberAccess;
990 sendIsMemberAccess = false;
991 allowedCategory =
992 ElementCategory.VARIABLE |
993 ElementCategory.FUNCTION |
994 ElementCategory.IMPLIES_TYPE;
995 ResolutionResult result = visit(node);
996 sendIsMemberAccess = oldSendIsMemberAccess;
997 allowedCategory = oldAllowedCategory;
998 return result;
999 }
1000
1001 /// Handle a type test expression, like `a is T` and `a is! T`. 970 /// Handle a type test expression, like `a is T` and `a is! T`.
1002 ResolutionResult handleIs(Send node) { 971 ResolutionResult handleIs(Send node) {
1003 Node expression = node.receiver; 972 Node expression = node.receiver;
1004 visitExpression(expression); 973 visitExpression(expression);
1005 974
1006 // TODO(johnniwinther): Use seen type tests to avoid registration of 975 // TODO(johnniwinther): Use seen type tests to avoid registration of
1007 // mutation/access to unpromoted variables. 976 // mutation/access to unpromoted variables.
1008 977
1009 Send notTypeNode = node.arguments.head.asSend(); 978 Send notTypeNode = node.arguments.head.asSend();
1010 DartType type; 979 DartType type;
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 sendStructure = const InvalidAssertStructure(); 1382 sendStructure = const InvalidAssertStructure();
1414 } 1383 }
1415 registry.registerAssert(node); 1384 registry.registerAssert(node);
1416 registry.registerSendStructure(node, sendStructure); 1385 registry.registerSendStructure(node, sendStructure);
1417 return const AssertResult(); 1386 return const AssertResult();
1418 } 1387 }
1419 1388
1420 /// Handle access of a property of [name] on `this`, like `this.name` and 1389 /// Handle access of a property of [name] on `this`, like `this.name` and
1421 /// `this.name()`, or `name` and `name()` in instance context. 1390 /// `this.name()`, or `name` and `name()` in instance context.
1422 ResolutionResult handleThisPropertyAccess(Send node, Name name) { 1391 ResolutionResult handleThisPropertyAccess(Send node, Name name) {
1423 AccessSemantics semantics = new AccessSemantics.thisProperty(); 1392 AccessSemantics accessSemantics = new AccessSemantics.thisProperty();
1424 return handleDynamicAccessSemantics(node, name, semantics); 1393 SendStructure sendStructure;
1394 Selector selector;
1395 if (node.isCall) {
1396 CallStructure callStructure = resolveArguments(node.argumentsNode);
1397 selector = new Selector(SelectorKind.CALL, name, callStructure);
1398 registry.registerDynamicInvocation(selector);
1399 sendStructure = new InvokeStructure(accessSemantics, selector);
1400 } else {
1401 assert(invariant(node, node.isPropertyAccess));
1402 selector = new Selector(
1403 SelectorKind.GETTER, name, CallStructure.NO_ARGS);
1404 registry.registerDynamicGetter(selector);
1405 sendStructure = new GetStructure(accessSemantics, selector);
1406 }
1407 registry.registerSendStructure(node, sendStructure);
1408 // TODO(johnniwinther): Remove this when all information goes through
1409 // the [SendStructure].
1410 registry.setSelector(node, selector);
1411 return const NoneResult();
1425 } 1412 }
1426 1413
1427 /// Handle access on `this`, like `this()` and `this` when it is parsed as a 1414 /// Handle access on `this`, like `this()` and `this` when it is parsed as a
1428 /// [Send] node. 1415 /// [Send] node.
1429 ResolutionResult handleThisAccess(Send node) { 1416 ResolutionResult handleThisAccess(Send node) {
1430 AccessSemantics accessSemantics = new AccessSemantics.thisAccess(); 1417 AccessSemantics accessSemantics = new AccessSemantics.thisAccess();
1431 if (node.isCall) { 1418 if (node.isCall) {
1432 CallStructure callStructure = resolveArguments(node.argumentsNode); 1419 CallStructure callStructure = resolveArguments(node.argumentsNode);
1433 Selector selector = callStructure.callSelector; 1420 Selector selector = callStructure.callSelector;
1434 // TODO(johnniwinther): Handle invalid this access as an 1421 // TODO(johnniwinther): Handle invalid this access as an
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1582 case BinaryOperatorKind.LT: 1569 case BinaryOperatorKind.LT:
1583 case BinaryOperatorKind.AND: 1570 case BinaryOperatorKind.AND:
1584 case BinaryOperatorKind.OR: 1571 case BinaryOperatorKind.OR:
1585 case BinaryOperatorKind.XOR: 1572 case BinaryOperatorKind.XOR:
1586 return handleUserDefinableBinary(node, operator); 1573 return handleUserDefinableBinary(node, operator);
1587 } 1574 }
1588 } 1575 }
1589 } 1576 }
1590 } 1577 }
1591 1578
1592 /// Handle qualified access to an unresolved static class member, like `a.b`
1593 /// or `a.b()` where `a` is a class and `b` is unresolved.
1594 ResolutionResult handleUnresolvedStaticMemberAccess(
1595 Send node, Name name, ClassElement receiverClass) {
1596 // TODO(johnniwinther): Share code with [handleStaticInstanceMemberAccess]
1597 // and [handlePrivateStaticMemberAccess].
1598 registry.registerThrowNoSuchMethod();
1599 // TODO(johnniwinther): Produce a different error if [name] is resolves to
1600 // a constructor.
1601
1602 // TODO(johnniwinther): With the simplified [TreeElements] invariant,
1603 // try to resolve injected elements if [currentClass] is in the patch
1604 // library of [receiverClass].
1605
1606 // TODO(karlklose): this should be reported by the caller of
1607 // [resolveSend] to select better warning messages for getters and
1608 // setters.
1609 ErroneousElement error = reportAndCreateErroneousElement(
1610 node, name.text, MessageKind.MEMBER_NOT_FOUND,
1611 {'className': receiverClass.name, 'memberName': name.text});
1612 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
1613 // member access.
1614 return handleErroneousAccess(
1615 node, name, error, new StaticAccess.unresolved(error));
1616 }
1617
1618 /// Handle qualified access of an instance member, like `a.b` or `a.b()` where
1619 /// `a` is a class and `b` is a non-static member.
1620 ResolutionResult handleStaticInstanceMemberAccess(
1621 Send node, Name name, ClassElement receiverClass, Element member) {
1622
1623 registry.registerThrowNoSuchMethod();
1624 // TODO(johnniwinther): With the simplified [TreeElements] invariant,
1625 // try to resolve injected elements if [currentClass] is in the patch
1626 // library of [receiverClass].
1627
1628 // TODO(karlklose): this should be reported by the caller of
1629 // [resolveSend] to select better warning messages for getters and
1630 // setters.
1631 ErroneousElement error = reportAndCreateErroneousElement(
1632 node, name.text, MessageKind.MEMBER_NOT_STATIC,
1633 {'className': receiverClass.name, 'memberName': name});
1634
1635 // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed
1636 // instance members.
1637 return handleErroneousAccess(
1638 node, name, error, new StaticAccess.unresolved(error));
1639 }
1640
1641 /// Handle qualified access of an inaccessible private static class member,
1642 /// like `a._b` or `a.b()` where `a` is class, `_b` is static member of `a`
1643 /// but `a` is not defined in the current library.
1644 ResolutionResult handlePrivateStaticMemberAccess(
1645 Send node, Name name, ClassElement receiverClass, Element member) {
1646 registry.registerThrowNoSuchMethod();
1647 ErroneousElement error = reportAndCreateErroneousElement(
1648 node, name.text, MessageKind.PRIVATE_ACCESS,
1649 {'libraryName': member.library.getLibraryOrScriptName(),
1650 'name': name});
1651 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static
1652 // member access.
1653 return handleErroneousAccess(
1654 node, name, error, new StaticAccess.unresolved(error));
1655 }
1656
1657 /// Handle qualified access to a static member, like `a.b` or `a.b()` where
1658 /// `a` is a class and `b` is a static member of `a`.
1659 ResolutionResult handleStaticMemberAccess(
1660 Send node, Name memberName, ClassElement receiverClass) {
1661 String name = memberName.text;
1662 receiverClass.ensureResolved(compiler);
1663 if (node.isOperator) {
1664 // When the resolved receiver is a class, we can have two cases:
1665 // 1) a static send: C.foo, or
1666 // 2) an operator send, where the receiver is a class literal: 'C + 1'.
1667 // The following code that looks up the selector on the resolved
1668 // receiver will treat the second as the invocation of a static operator
1669 // if the resolved receiver is not null.
1670 return const NoneResult();
1671 }
1672 MembersCreator.computeClassMembersByName(
1673 compiler, receiverClass.declaration, name);
1674 Element member = receiverClass.lookupLocalMember(name);
1675 if (member == null) {
1676 return handleUnresolvedStaticMemberAccess(
1677 node, memberName, receiverClass);
1678 } else if (member.isInstanceMember) {
1679 return handleStaticInstanceMemberAccess(
1680 node, memberName, receiverClass, member);
1681 } else if (memberName.isPrivate && memberName.library != member.library) {
1682 return handlePrivateStaticMemberAccess(
1683 node, memberName, receiverClass, member);
1684 } else {
1685 return handleStaticOrTopLevelAccess(node, memberName, member);
1686 }
1687 }
1688
1689 /// Handle qualified [Send] where the receiver resolves to an [Element], like
1690 /// `a.b` where `a` is a local, field, class, or prefix, etc.
1691 ResolutionResult handleResolvedQualifiedSend(
1692 Send node, Name name, Element element) {
1693 if (element.isPrefix) {
1694 return oldVisitSend(node);
1695 } else if (element.isClass) {
1696 return handleStaticMemberAccess(node, name, element);
1697 }
1698 return oldVisitSend(node);
1699 }
1700
1701 /// Handle dynamic access of [semantics].
1702 ResolutionResult handleDynamicAccessSemantics(
1703 Send node, Name name, AccessSemantics semantics) {
1704 SendStructure sendStructure;
1705 Selector selector;
1706 if (node.isCall) {
1707 CallStructure callStructure = resolveArguments(node.argumentsNode);
1708 selector = new Selector(SelectorKind.CALL, name, callStructure);
1709 registry.registerDynamicInvocation(selector);
1710 sendStructure = new InvokeStructure(semantics, selector);
1711 } else {
1712 assert(invariant(node, node.isPropertyAccess));
1713 selector = new Selector(
1714 SelectorKind.GETTER, name, CallStructure.NO_ARGS);
1715 registry.registerDynamicGetter(selector);
1716 sendStructure = new GetStructure(semantics, selector);
1717 }
1718 registry.registerSendStructure(node, sendStructure);
1719 // TODO(johnniwinther): Remove this when all information goes through
1720 // the [SendStructure].
1721 registry.setSelector(node, selector);
1722 return const NoneResult();
1723 }
1724
1725 /// Handle dynamic property access, like `a.b` or `a.b()` where `a` is not a
1726 /// prefix or class.
1727 ResolutionResult handleDynamicPropertyAccess(Send node, Name name) {
1728 AccessSemantics semantics =
1729 new DynamicAccess.dynamicProperty(node.receiver);
1730 return handleDynamicAccessSemantics(node, name, semantics);
1731 }
1732
1733 /// Handle conditional access, like `a?.b` or `a?.b()`.
1734 ResolutionResult handleConditionalAccess(Send node, Name name) {
1735 Node receiver = node.receiver;
1736 visitConditionalPrefix(receiver);
1737 AccessSemantics semantics =
1738 new DynamicAccess.ifNotNullProperty(receiver);
1739 return handleDynamicAccessSemantics(node, name, semantics);
1740 }
1741
1742 /// Handle `this` as a qualified property, like `a.this`.
1743 ResolutionResult handleQualifiedThisAccess(Send node, Name name) {
1744 ErroneousElement error = reportAndCreateErroneousElement(
1745 node.selector,
1746 name.text,
1747 MessageKind.THIS_PROPERTY, {},
1748 isError: true);
1749 // TODO(johnniwinther): Support `this` as property as an [AccessSemantics].
1750 AccessSemantics accessSemantics = new StaticAccess.unresolved(error);
1751 return handleErroneousAccess(node, name, error, accessSemantics);
1752 }
1753
1754 /// Handle a qualified [Send], that is where the receiver is non-null, like 1579 /// Handle a qualified [Send], that is where the receiver is non-null, like
1755 /// `a.b`, `a.b()`, `this.a()` and `super.a()`. 1580 /// `a.b`, `a.b()`, `this.a()` and `super.a()`.
1756 ResolutionResult handleQualifiedSend(Send node) { 1581 ResolutionResult handleQualifiedSend(Send node) {
1757 Identifier selector = node.selector.asIdentifier(); 1582 Identifier selector = node.selector.asIdentifier();
1758 String text = selector.source; 1583 Name name = new Name(selector.source, enclosingElement.library);
1759 Name name = new Name(text, enclosingElement.library); 1584 if (node.isSuperCall) {
1760 if (text == 'this') {
1761 return handleQualifiedThisAccess(node, name);
1762 } else if (node.isSuperCall) {
1763 return handleSuperPropertyAccess(node, name); 1585 return handleSuperPropertyAccess(node, name);
1764 } else if (node.receiver.isThis()) { 1586 } else if (node.receiver.isThis()) {
1765 if (checkThisAccess(node)) { 1587 if (checkThisAccess(node)) {
1766 return handleThisPropertyAccess(node, name); 1588 return handleThisPropertyAccess(node, name);
1767 } 1589 }
1768 // TODO(johnniwinther): Handle invalid this access as an 1590 // TODO(johnniwinther): Handle invalid this access as an
1769 // [AccessSemantics]. 1591 // [AccessSemantics].
1770 return const NoneResult(); 1592 return const NoneResult();
1771 } else if (node.isConditional) {
1772 return handleConditionalAccess(node, name);
1773 } 1593 }
1774 ResolutionResult result = visitExpressionPrefix(node.receiver); 1594 // TODO(johnniwinther): Handle remaining qualified sends.
1775 if (result.element != null) { 1595 return oldVisitSend(node);
1776 return handleResolvedQualifiedSend(node, name, result.element);
1777 } else {
1778 return handleDynamicPropertyAccess(node, name);
1779 }
1780 } 1596 }
1781 1597
1782 /// Handle access unresolved access to [name] in a non-instance context. 1598 /// Handle access unresolved access to [name] in a non-instance context.
1783 ResolutionResult handleUnresolvedAccess( 1599 ResolutionResult handleUnresolvedAccess(
1784 Send node, Name name, Element element) { 1600 Send node, Name name, Element element) {
1785 // TODO(johnniwinther): Support unresolved top level access as an 1601 // TODO(johnniwinther): Support unresolved top level access as an
1786 // [AccessSemantics]. 1602 // [AccessSemantics].
1787 AccessSemantics accessSemantics = new StaticAccess.unresolved(element); 1603 AccessSemantics accessSemantics = new StaticAccess.unresolved(element);
1788 return handleErroneousAccess(node, name, element, accessSemantics); 1604 return handleErroneousAccess(node, name, element, accessSemantics);
1789 } 1605 }
(...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after
2641 ResolutionResult visitWhile(While node) { 2457 ResolutionResult visitWhile(While node) {
2642 visit(node.condition); 2458 visit(node.condition);
2643 visitLoopBodyIn(node, node.body, new BlockScope(scope)); 2459 visitLoopBodyIn(node, node.body, new BlockScope(scope));
2644 return const NoneResult(); 2460 return const NoneResult();
2645 } 2461 }
2646 2462
2647 ResolutionResult visitParenthesizedExpression(ParenthesizedExpression node) { 2463 ResolutionResult visitParenthesizedExpression(ParenthesizedExpression node) {
2648 bool oldSendIsMemberAccess = sendIsMemberAccess; 2464 bool oldSendIsMemberAccess = sendIsMemberAccess;
2649 sendIsMemberAccess = false; 2465 sendIsMemberAccess = false;
2650 var oldCategory = allowedCategory; 2466 var oldCategory = allowedCategory;
2651 allowedCategory = 2467 allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION
2652 ElementCategory.VARIABLE | 2468 | ElementCategory.IMPLIES_TYPE;
2653 ElementCategory.FUNCTION |
2654 ElementCategory.IMPLIES_TYPE;
2655 ResolutionResult result = visit(node.expression); 2469 ResolutionResult result = visit(node.expression);
2656 allowedCategory = oldCategory; 2470 allowedCategory = oldCategory;
2657 sendIsMemberAccess = oldSendIsMemberAccess; 2471 sendIsMemberAccess = oldSendIsMemberAccess;
2658 if (result.kind == ResultKind.CONSTANT) { 2472 if (result.kind == ResultKind.CONSTANT) {
2659 return result; 2473 return result;
2660 } 2474 }
2661 return const NoneResult(); 2475 return const NoneResult();
2662 } 2476 }
2663 2477
2664 ResolutionResult visitNewExpression(NewExpression node) { 2478 ResolutionResult visitNewExpression(NewExpression node) {
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
3459 } 3273 }
3460 return const NoneResult(); 3274 return const NoneResult();
3461 } 3275 }
3462 } 3276 }
3463 3277
3464 /// Looks up [name] in [scope] and unwraps the result. 3278 /// Looks up [name] in [scope] and unwraps the result.
3465 Element lookupInScope(Compiler compiler, Node node, 3279 Element lookupInScope(Compiler compiler, Node node,
3466 Scope scope, String name) { 3280 Scope scope, String name) {
3467 return Elements.unwrap(scope.lookup(name), compiler, node); 3281 return Elements.unwrap(scope.lookup(name), compiler, node);
3468 } 3282 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/access_semantics.dart ('k') | pkg/compiler/lib/src/resolution/resolution_common.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698