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

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

Issue 1149403009: Refactoring resolution of local access and unqualified access of statics (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Fix after rebase 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 795 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 /// Check that access to `this` is currently allowed. 806 /// Check that access to `this` is currently allowed.
807 bool checkThisAccess(Send node) { 807 bool checkThisAccess(Send node) {
808 if (!inInstanceContext) { 808 if (!inInstanceContext) {
809 compiler.reportError(node, MessageKind.NO_THIS_AVAILABLE); 809 compiler.reportError(node, MessageKind.NO_THIS_AVAILABLE);
810 return false; 810 return false;
811 } 811 }
812 return true; 812 return true;
813 } 813 }
814 814
815 /// Compute the [AccessSemantics] corresponding to a super access of [target]. 815 /// Compute the [AccessSemantics] corresponding to a super access of [target].
816 AccessSemantics computeSuperAccess(Spannable node, Element target) { 816 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) {
817 if (target.isErroneous) { 817 if (target.isErroneous) {
818 return new StaticAccess.unresolvedSuper(target); 818 return new StaticAccess.unresolvedSuper(target);
819 } else if (target.isGetter) { 819 } else if (target.isGetter) {
820 return new StaticAccess.superGetter(target); 820 return new StaticAccess.superGetter(target);
821 } else if (target.isSetter) { 821 } else if (target.isSetter) {
822 return new StaticAccess.superSetter(target); 822 return new StaticAccess.superSetter(target);
823 } else if (target.isField) { 823 } else if (target.isField) {
824 return new StaticAccess.superField(target); 824 if (target.isFinal) {
825 return new StaticAccess.superFinalField(target);
826 } else {
827 return new StaticAccess.superField(target);
828 }
825 } else { 829 } else {
826 assert(invariant(node, target.isFunction, 830 assert(invariant(node, target.isFunction,
827 message: "Unexpected super target '$target'.")); 831 message: "Unexpected super target '$target'."));
828 return new StaticAccess.superMethod(target); 832 return new StaticAccess.superMethod(target);
829 } 833 }
830 } 834 }
831 835
836 /// Compute the [AccessSemantics] corresponding to a local access of [target].
837 AccessSemantics computeLocalAccessSemantics(Spannable node,
838 LocalElement target) {
839 if (target.isParameter) {
840 if (target.isFinal || target.isConst) {
841 return new StaticAccess.finalParameter(target);
842 } else {
843 return new StaticAccess.parameter(target);
844 }
845 } else if (target.isVariable) {
846 if (target.isFinal || target.isConst) {
847 return new StaticAccess.finalLocalVariable(target);
848 } else {
849 return new StaticAccess.localVariable(target);
850 }
851 } else {
852 assert(invariant(node, target.isFunction,
853 message: "Unexpected local target '$target'."));
854 return new StaticAccess.localFunction(target);
855 }
856 }
857
858 /// Compute the [AccessSemantics] corresponding to a static or toplevel access
859 /// of [target].
860 AccessSemantics computeStaticOrTopLevelAccessSemantics(
861 Spannable node,
862 Element target) {
863
864 target = target.declaration;
865 if (target.isErroneous) {
866 // This handles elements with parser errors.
867 // TODO(johnniwinther): Elements with parse error should not set
868 // [isErroneous] to `true`.
869 return new StaticAccess.unresolved(target);
870 }
871 if (target.isStatic) {
872 if (target.isGetter) {
873 return new StaticAccess.staticGetter(target);
874 } else if (target.isSetter) {
875 return new StaticAccess.staticSetter(target);
876 } else if (target.isField) {
877 if (target.isFinal || target.isConst) {
878 return new StaticAccess.finalStaticField(target);
879 } else {
880 return new StaticAccess.staticField(target);
881 }
882 } else {
883 assert(invariant(node, target.isFunction,
884 message: "Unexpected static target '$target'."));
885 return new StaticAccess.staticMethod(target);
886 }
887 } else {
888 assert(invariant(node, target.isTopLevel,
889 message: "Unexpected statically resolved target '$target'."));
890 if (target.isGetter) {
891 return new StaticAccess.topLevelGetter(target);
892 } else if (target.isSetter) {
893 return new StaticAccess.topLevelSetter(target);
894 } else if (target.isField) {
895 if (target.isFinal) {
896 return new StaticAccess.finalTopLevelField(target);
897 } else {
898 return new StaticAccess.topLevelField(target);
899 }
900 } else {
901 assert(invariant(node, target.isFunction,
902 message: "Unexpected top level target '$target'."));
903 return new StaticAccess.topLevelMethod(target);
904 }
905 }
906 }
907
832 /// Compute the [AccessSemantics] for accessing the name of [selector] on the 908 /// Compute the [AccessSemantics] for accessing the name of [selector] on the
833 /// super class. 909 /// super class.
834 /// 910 ///
835 /// If no matching super member is found and error is reported and 911 /// If no matching super member is found and error is reported and
836 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName] 912 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName]
837 /// is provided, the [AccessSemantics] corresponding to the alternate name is 913 /// is provided, the [AccessSemantics] corresponding to the alternate name is
838 /// returned. For instance, the access of a super setter for an unresolved 914 /// returned. For instance, the access of a super setter for an unresolved
839 /// getter: 915 /// getter:
840 /// 916 ///
841 /// class Super { 917 /// class Super {
842 /// set name(_) {} 918 /// set name(_) {}
843 /// } 919 /// }
844 /// class Sub extends Super { 920 /// class Sub extends Super {
845 /// foo => super.name; // Access to the setter. 921 /// foo => super.name; // Access to the setter.
846 /// } 922 /// }
847 /// 923 ///
848 AccessSemantics computeSuperSemantics(Spannable node, 924 AccessSemantics computeSuperAccessSemanticsForSelector(
849 Selector selector, 925 Spannable node,
850 {Name alternateName}) { 926 Selector selector,
927 {Name alternateName}) {
928
851 Name name = selector.memberName; 929 Name name = selector.memberName;
852 // TODO(johnniwinther): Ensure correct behavior if currentClass is a 930 // TODO(johnniwinther): Ensure correct behavior if currentClass is a
853 // patch. 931 // patch.
854 Element target = currentClass.lookupSuperByName(name); 932 Element target = currentClass.lookupSuperByName(name);
855 // [target] may be null which means invoking noSuchMethod on super. 933 // [target] may be null which means invoking noSuchMethod on super.
856 if (target == null) { 934 if (target == null) {
857 Element error = reportAndCreateErroneousElement( 935 Element error = reportAndCreateErroneousElement(
858 node, name.text, MessageKind.NO_SUCH_SUPER_MEMBER, 936 node, name.text, MessageKind.NO_SUCH_SUPER_MEMBER,
859 {'className': currentClass.name, 'memberName': name}); 937 {'className': currentClass.name, 'memberName': name});
860 if (alternateName != null) { 938 if (alternateName != null) {
861 target = currentClass.lookupSuperByName(alternateName); 939 target = currentClass.lookupSuperByName(alternateName);
862 } 940 }
863 if (target == null) { 941 if (target == null) {
864 // If a setter wasn't resolved, use the [ErroneousElement]. 942 // If a setter wasn't resolved, use the [ErroneousElement].
865 target = error; 943 target = error;
866 } 944 }
867 // We still need to register the invocation, because we might 945 // We still need to register the invocation, because we might
868 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. 946 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
869 registry.registerDynamicInvocation(selector); 947 registry.registerDynamicInvocation(selector);
870 registry.registerSuperNoSuchMethod(); 948 registry.registerSuperNoSuchMethod();
871 } 949 }
872 return computeSuperAccess(node, target); 950 return computeSuperAccessSemantics(node, target);
873 } 951 }
874 952
875 /// Resolve [node] as subexpression that is _not_ the prefix of a member 953 /// Resolve [node] as subexpression that is _not_ the prefix of a member
876 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`. 954 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`.
877 ResolutionResult visitExpression(Node node) { 955 ResolutionResult visitExpression(Node node) {
878 bool oldSendIsMemberAccess = sendIsMemberAccess; 956 bool oldSendIsMemberAccess = sendIsMemberAccess;
879 sendIsMemberAccess = false; 957 sendIsMemberAccess = false;
880 ResolutionResult result = visit(node); 958 ResolutionResult result = visit(node);
881 sendIsMemberAccess = oldSendIsMemberAccess; 959 sendIsMemberAccess = oldSendIsMemberAccess;
882 return result; 960 return result;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 ResolutionResult result = const NoneResult(); 1019 ResolutionResult result = const NoneResult();
942 Node expression = node.receiver; 1020 Node expression = node.receiver;
943 Selector selector = operator.selector; 1021 Selector selector = operator.selector;
944 // TODO(johnniwinther): Remove this when all information goes through the 1022 // TODO(johnniwinther): Remove this when all information goes through the
945 // [SendStructure]. 1023 // [SendStructure].
946 registry.setSelector(node, selector); 1024 registry.setSelector(node, selector);
947 1025
948 AccessSemantics semantics; 1026 AccessSemantics semantics;
949 if (node.isSuperCall) { 1027 if (node.isSuperCall) {
950 if (checkSuperAccess(node)) { 1028 if (checkSuperAccess(node)) {
951 semantics = computeSuperSemantics(node, selector); 1029 semantics = computeSuperAccessSemanticsForSelector(node, selector);
952 // TODO(johnniwinther): Add information to [AccessSemantics] about 1030 // TODO(johnniwinther): Add information to [AccessSemantics] about
953 // whether it is erroneous. 1031 // whether it is erroneous.
954 if (semantics.kind == AccessKind.SUPER_METHOD) { 1032 if (semantics.kind == AccessKind.SUPER_METHOD) {
955 registry.registerStaticUse(semantics.element.declaration); 1033 registry.registerStaticUse(semantics.element.declaration);
956 } 1034 }
957 // TODO(johnniwinther): Remove this when all information goes through 1035 // TODO(johnniwinther): Remove this when all information goes through
958 // the [SendStructure]. 1036 // the [SendStructure].
959 registry.useElement(node, semantics.element); 1037 registry.useElement(node, semantics.element);
960 } 1038 }
961 } else { 1039 } else {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 selector = new Selector.index(); 1193 selector = new Selector.index();
1116 } else { 1194 } else {
1117 selector = new Selector.binaryOperator(operator.selectorName); 1195 selector = new Selector.binaryOperator(operator.selectorName);
1118 } 1196 }
1119 // TODO(johnniwinther): Remove this when all information goes through the 1197 // TODO(johnniwinther): Remove this when all information goes through the
1120 // [SendStructure]. 1198 // [SendStructure].
1121 registry.setSelector(node, selector); 1199 registry.setSelector(node, selector);
1122 1200
1123 if (node.isSuperCall) { 1201 if (node.isSuperCall) {
1124 if (checkSuperAccess(node)) { 1202 if (checkSuperAccess(node)) {
1125 semantics = computeSuperSemantics(node, selector); 1203 semantics = computeSuperAccessSemanticsForSelector(node, selector);
1126 // TODO(johnniwinther): Add information to [AccessSemantics] about 1204 // TODO(johnniwinther): Add information to [AccessSemantics] about
1127 // whether it is erroneous. 1205 // whether it is erroneous.
1128 if (semantics.kind == AccessKind.SUPER_METHOD) { 1206 if (semantics.kind == AccessKind.SUPER_METHOD) {
1129 registry.registerStaticUse(semantics.element.declaration); 1207 registry.registerStaticUse(semantics.element.declaration);
1130 } 1208 }
1131 // TODO(johnniwinther): Remove this when all information goes through 1209 // TODO(johnniwinther): Remove this when all information goes through
1132 // the [SendStructure]. 1210 // the [SendStructure].
1133 registry.useElement(node, semantics.element); 1211 registry.useElement(node, semantics.element);
1134 } 1212 }
1135 visitExpression(right); 1213 visitExpression(right);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 Element target; 1433 Element target;
1356 Selector selector; 1434 Selector selector;
1357 CallStructure callStructure = CallStructure.NO_ARGS; 1435 CallStructure callStructure = CallStructure.NO_ARGS;
1358 if (node.isCall) { 1436 if (node.isCall) {
1359 callStructure = resolveArguments(node.argumentsNode); 1437 callStructure = resolveArguments(node.argumentsNode);
1360 selector = new Selector(SelectorKind.CALL, name, callStructure); 1438 selector = new Selector(SelectorKind.CALL, name, callStructure);
1361 } else { 1439 } else {
1362 selector = new Selector(SelectorKind.GETTER, name, callStructure); 1440 selector = new Selector(SelectorKind.GETTER, name, callStructure);
1363 } 1441 }
1364 if (checkSuperAccess(node)) { 1442 if (checkSuperAccess(node)) {
1365 AccessSemantics semantics = computeSuperSemantics( 1443 AccessSemantics semantics = computeSuperAccessSemanticsForSelector(
1366 node, selector, alternateName: name.setter); 1444 node, selector, alternateName: name.setter);
1367 if (node.isCall) { 1445 if (node.isCall) {
1368 bool isIncompatibleInvoke = false; 1446 bool isIncompatibleInvoke = false;
1369 switch (semantics.kind) { 1447 switch (semantics.kind) {
1370 case AccessKind.SUPER_METHOD: 1448 case AccessKind.SUPER_METHOD:
1371 MethodElementX superMethod = semantics.element; 1449 MethodElementX superMethod = semantics.element;
1372 superMethod.computeSignature(compiler); 1450 superMethod.computeSignature(compiler);
1373 if (!callStructure.signatureApplies(superMethod)) { 1451 if (!callStructure.signatureApplies(superMethod)) {
1374 registry.registerThrowNoSuchMethod(); 1452 registry.registerThrowNoSuchMethod();
1375 registry.registerDynamicInvocation(selector); 1453 registry.registerDynamicInvocation(selector);
1376 registry.registerSuperNoSuchMethod(); 1454 registry.registerSuperNoSuchMethod();
1377 isIncompatibleInvoke = true; 1455 isIncompatibleInvoke = true;
1378 } else { 1456 } else {
1379 registry.registerStaticInvocation(semantics.element); 1457 registry.registerStaticInvocation(semantics.element);
1380 } 1458 }
1381 break; 1459 break;
1382 case AccessKind.SUPER_FIELD: 1460 case AccessKind.SUPER_FIELD:
1461 case AccessKind.SUPER_FINAL_FIELD:
1383 case AccessKind.SUPER_GETTER: 1462 case AccessKind.SUPER_GETTER:
1384 registry.registerStaticUse(semantics.element); 1463 registry.registerStaticUse(semantics.element);
1385 selector = callStructure.callSelector; 1464 selector = callStructure.callSelector;
1386 registry.registerDynamicInvocation(selector); 1465 registry.registerDynamicInvocation(selector);
1387 break; 1466 break;
1388 case AccessKind.SUPER_SETTER: 1467 case AccessKind.SUPER_SETTER:
1389 case AccessKind.UNRESOLVED_SUPER: 1468 case AccessKind.UNRESOLVED_SUPER:
1390 // NoSuchMethod registered in [computeSuperSemantics]. 1469 // NoSuchMethod registered in [computeSuperSemantics].
1391 break; 1470 break;
1392 default: 1471 default:
1393 internalError(node, "Unexpected super property access $semantics."); 1472 internalError(node, "Unexpected super property access $semantics.");
1394 break; 1473 break;
1395 } 1474 }
1396 registry.registerSendStructure(node, 1475 registry.registerSendStructure(node,
1397 isIncompatibleInvoke 1476 isIncompatibleInvoke
1398 ? new IncompatibleInvokeStructure(semantics, selector) 1477 ? new IncompatibleInvokeStructure(semantics, selector)
1399 : new InvokeStructure(semantics, selector)); 1478 : new InvokeStructure(semantics, selector));
1400 } else { 1479 } else {
1401 switch (semantics.kind) { 1480 switch (semantics.kind) {
1402 case AccessKind.SUPER_METHOD: 1481 case AccessKind.SUPER_METHOD:
1403 // TODO(johnniwinther): Method this should be registered as a 1482 // TODO(johnniwinther): Method this should be registered as a
1404 // closurization. 1483 // closurization.
1405 registry.registerStaticUse(semantics.element); 1484 registry.registerStaticUse(semantics.element);
1406 break; 1485 break;
1407 case AccessKind.SUPER_FIELD: 1486 case AccessKind.SUPER_FIELD:
1487 case AccessKind.SUPER_FINAL_FIELD:
1408 case AccessKind.SUPER_GETTER: 1488 case AccessKind.SUPER_GETTER:
1409 registry.registerStaticUse(semantics.element); 1489 registry.registerStaticUse(semantics.element);
1410 break; 1490 break;
1411 case AccessKind.SUPER_SETTER: 1491 case AccessKind.SUPER_SETTER:
1412 case AccessKind.UNRESOLVED_SUPER: 1492 case AccessKind.UNRESOLVED_SUPER:
1413 // NoSuchMethod registered in [computeSuperSemantics]. 1493 // NoSuchMethod registered in [computeSuperSemantics].
1414 break; 1494 break;
1415 default: 1495 default:
1416 internalError(node, "Unexpected super property access $semantics."); 1496 internalError(node, "Unexpected super property access $semantics.");
1417 break; 1497 break;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1507 // TODO(johnniwinther): Handle remaining qualified sends. 1587 // TODO(johnniwinther): Handle remaining qualified sends.
1508 return oldVisitSend(node); 1588 return oldVisitSend(node);
1509 } 1589 }
1510 1590
1511 /// Handle access unresolved access to [name] in a non-instance context. 1591 /// Handle access unresolved access to [name] in a non-instance context.
1512 ResolutionResult handleUnresolvedAccess( 1592 ResolutionResult handleUnresolvedAccess(
1513 Send node, Name name, Element element) { 1593 Send node, Name name, Element element) {
1514 // TODO(johnniwinther): Support unresolved top level access as an 1594 // TODO(johnniwinther): Support unresolved top level access as an
1515 // [AccessSemantics]. 1595 // [AccessSemantics].
1516 AccessSemantics accessSemantics = new StaticAccess.unresolved(element); 1596 AccessSemantics accessSemantics = new StaticAccess.unresolved(element);
1597 return handleErroneousAccess(node, name, element, accessSemantics);
1598 }
1599
1600 /// Handle erroneous access of [element] of the given [accessSemantics].
1601 ResolutionResult handleErroneousAccess(
1602 Send node, Name name, Element element, AccessSemantics accessSemantics) {
1517 SendStructure sendStructure; 1603 SendStructure sendStructure;
1518 Selector selector; 1604 Selector selector;
1519 if (node.isCall) { 1605 if (node.isCall) {
1520 CallStructure callStructure = resolveArguments(node.argumentsNode); 1606 CallStructure callStructure = resolveArguments(node.argumentsNode);
1521 selector = new Selector(SelectorKind.CALL, name, callStructure); 1607 selector = new Selector(SelectorKind.CALL, name, callStructure);
1522 registry.registerDynamicInvocation(selector); 1608 registry.registerDynamicInvocation(selector);
1523 sendStructure = new InvokeStructure(accessSemantics, selector); 1609 sendStructure = new InvokeStructure(accessSemantics, selector);
1524 } else { 1610 } else {
1525 assert(invariant(node, node.isPropertyAccess)); 1611 assert(invariant(node, node.isPropertyAccess));
1526 selector = new Selector( 1612 selector = new Selector(
1527 SelectorKind.GETTER, name, CallStructure.NO_ARGS); 1613 SelectorKind.GETTER, name, CallStructure.NO_ARGS);
1528 registry.registerDynamicGetter(selector); 1614 registry.registerDynamicGetter(selector);
1529 sendStructure = new GetStructure(accessSemantics, selector); 1615 sendStructure = new GetStructure(accessSemantics, selector);
1530 } 1616 }
1531 // TODO(johnniwinther): Remove this when all information goes through 1617 // TODO(johnniwinther): Remove this when all information goes through
1532 // the [SendStructure]. 1618 // the [SendStructure].
1533 registry.setSelector(node, selector); 1619 registry.setSelector(node, selector);
1534 registry.useElement(node, element); 1620 registry.useElement(node, element);
1535 registry.registerSendStructure(node, sendStructure); 1621 registry.registerSendStructure(node, sendStructure);
1536 return const NoneResult(); 1622 return const NoneResult();
1537 } 1623 }
1538 1624
1625 /// Handle access to an ambiguous element, that is, a name imported twice.
1626 ResolutionResult handleAmbiguousSend(
1627 Send node,
1628 Name name,
1629 AmbiguousElement element) {
1630
1631 compiler.reportError(
1632 node, element.messageKind, element.messageArguments);
1633 element.diagnose(enclosingElement, compiler);
1634
1635 ErroneousElement error = new ErroneousElementX(
1636 element.messageKind,
1637 element.messageArguments,
1638 name.text,
1639 enclosingElement);
1640
1641 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics].
1642 AccessSemantics accessSemantics = new StaticAccess.unresolved(error);
1643 return handleErroneousAccess(node, name, error, accessSemantics);
1644 }
1645
1646 /// Handle access of an instance [member] from a non-instance context.
1647 ResolutionResult handleStaticInstanceSend(
1648 Send node, Name name, MemberElement member) {
1649 compiler.reportError(
1650 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': member.name});
1651 ErroneousElement error = new ErroneousElementX(
1652 MessageKind.NO_INSTANCE_AVAILABLE,
1653 {'name': name},
1654 name.text,
1655 enclosingElement);
1656
1657 // TODO(johnniwinther): Support static instance access as an
1658 // [AccessSemantics].
1659 AccessSemantics accessSemantics = new StaticAccess.unresolved(error);
1660 return handleErroneousAccess(node, name, error, accessSemantics);
1661 }
1662
1663 /// Handle access of a parameter, local variable or local function.
1664 ResolutionResult handleLocalAccess(Send node, Name name, Element element) {
1665 AccessSemantics semantics = computeLocalAccessSemantics(node, element);
1666 Selector selector;
1667 CallStructure callStructure = CallStructure.NO_ARGS;
1668 if (node.isCall) {
1669 callStructure = resolveArguments(node.argumentsNode);
1670 selector = new Selector(SelectorKind.CALL, name, callStructure);
1671 } else {
1672 selector = new Selector(SelectorKind.GETTER, name, callStructure);
1673 }
1674 if (node.isCall) {
1675 bool isIncompatibleInvoke = false;
1676 switch (semantics.kind) {
1677 case AccessKind.LOCAL_FUNCTION:
1678 LocalFunctionElementX function = semantics.element;
1679 function.computeSignature(compiler);
1680 if (!callStructure.signatureApplies(function)) {
1681 registry.registerThrowNoSuchMethod();
1682 registry.registerDynamicInvocation(selector);
1683 isIncompatibleInvoke = true;
1684 }
1685 break;
1686 case AccessKind.PARAMETER:
1687 case AccessKind.FINAL_PARAMETER:
1688 case AccessKind.LOCAL_VARIABLE:
1689 case AccessKind.FINAL_LOCAL_VARIABLE:
1690 selector = callStructure.callSelector;
1691 registry.registerDynamicInvocation(selector);
1692 break;
1693 default:
1694 internalError(node,
1695 "Unexpected local access $semantics.");
1696 break;
1697 }
1698 registry.registerSendStructure(node,
1699 isIncompatibleInvoke
1700 ? new IncompatibleInvokeStructure(semantics, selector)
1701 : new InvokeStructure(semantics, selector));
1702 } else {
1703 registry.registerSendStructure(node,
1704 new GetStructure(semantics, selector));
1705 }
1706
1707 // TODO(johnniwinther): Remove these when all information goes through
1708 // the [SendStructure].
1709 registry.useElement(node, element);
1710 registry.setSelector(node, selector);
1711
1712 registerPotentialAccessInClosure(node, element);
1713
1714 return node.isPropertyAccess
1715 ? new ElementResult(element) : const NoneResult();
1716 }
1717
1718 /// Handle access of a static or top level [element].
1719 ResolutionResult handleStaticOrTopLevelAccess(
1720 Send node, Name name, Element element) {
1721
1722 if (element.isAbstractField) {
1723 AbstractFieldElement abstractField = element;
1724 if (abstractField.getter != null) {
1725 element = abstractField.getter;
1726 } else {
1727 element = abstractField.setter;
1728 }
1729 }
1730 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery
1731 // of parse errors to make [element] erroneous. Fix this!
1732 element.computeType(compiler);
1733
1734 Selector selector;
1735 CallStructure callStructure = CallStructure.NO_ARGS;
1736 if (node.isCall) {
1737 callStructure = resolveArguments(node.argumentsNode);
1738 selector = new Selector(SelectorKind.CALL, name, callStructure);
1739 } else {
1740 selector = new Selector(SelectorKind.GETTER, name, callStructure);
1741 }
1742 AccessSemantics semantics =
1743 computeStaticOrTopLevelAccessSemantics(node, element);
1744 if (node.isCall) {
1745 bool isIncompatibleInvoke = false;
1746 switch (semantics.kind) {
1747 case AccessKind.STATIC_METHOD:
1748 case AccessKind.TOPLEVEL_METHOD:
1749 MethodElementX method = semantics.element;
1750 method.computeSignature(compiler);
1751 if (!callStructure.signatureApplies(method)) {
1752 registry.registerThrowNoSuchMethod();
1753 registry.registerDynamicInvocation(selector);
1754 isIncompatibleInvoke = true;
1755 } else {
1756 registry.registerStaticUse(semantics.element);
1757 handleForeignCall(node, semantics.element, selector);
1758 }
1759 break;
1760 case AccessKind.STATIC_FIELD:
1761 case AccessKind.FINAL_STATIC_FIELD:
1762 case AccessKind.STATIC_GETTER:
1763 case AccessKind.TOPLEVEL_FIELD:
1764 case AccessKind.FINAL_TOPLEVEL_FIELD:
1765 case AccessKind.TOPLEVEL_GETTER:
1766 registry.registerStaticUse(semantics.element);
1767 selector = callStructure.callSelector;
1768 registry.registerDynamicInvocation(selector);
1769 break;
1770 case AccessKind.STATIC_SETTER:
1771 case AccessKind.TOPLEVEL_SETTER:
1772 case AccessKind.UNRESOLVED:
1773 registry.registerThrowNoSuchMethod();
1774 element = reportAndCreateErroneousElement(
1775 node.selector, name.text,
1776 MessageKind.CANNOT_RESOLVE_GETTER, const {});
1777 break;
1778 default:
1779 internalError(node,
1780 "Unexpected statically resolved access $semantics.");
1781 break;
1782 }
1783 registry.registerSendStructure(node,
1784 isIncompatibleInvoke
1785 ? new IncompatibleInvokeStructure(semantics, selector)
1786 : new InvokeStructure(semantics, selector));
1787 } else {
1788 switch (semantics.kind) {
1789 case AccessKind.STATIC_METHOD:
1790 case AccessKind.TOPLEVEL_METHOD:
1791 // TODO(johnniwinther): Method this should be registered as a
1792 // closurization.
1793 registry.registerStaticUse(semantics.element);
1794 registry.registerGetOfStaticFunction(semantics.element);
1795 break;
1796 case AccessKind.STATIC_FIELD:
1797 case AccessKind.FINAL_STATIC_FIELD:
1798 case AccessKind.STATIC_GETTER:
1799 case AccessKind.TOPLEVEL_FIELD:
1800 case AccessKind.FINAL_TOPLEVEL_FIELD:
1801 case AccessKind.TOPLEVEL_GETTER:
1802 registry.registerStaticUse(semantics.element);
1803 break;
1804 case AccessKind.STATIC_SETTER:
1805 case AccessKind.TOPLEVEL_SETTER:
1806 case AccessKind.UNRESOLVED:
1807 registry.registerThrowNoSuchMethod();
1808 element = reportAndCreateErroneousElement(
1809 node.selector, name.text,
1810 MessageKind.CANNOT_RESOLVE_GETTER, const {});
1811 break;
1812 default:
1813 internalError(node,
1814 "Unexpected statically resolved access $semantics.");
1815 break;
1816 }
1817 registry.registerSendStructure(node,
1818 new GetStructure(semantics, selector));
1819 }
1820
1821 // TODO(johnniwinther): Remove these when all information goes through
1822 // the [SendStructure].
1823 registry.useElement(node, element);
1824 registry.setSelector(node, selector);
1825
1826 return node.isPropertyAccess
1827 ? new ElementResult(element) : const NoneResult();
1828 }
1829
1830 /// Handle access to resolved [element].
1831 ResolutionResult handleResolvedSend(Send node, Name name, Element element) {
1832 if (element.isAmbiguous) {
1833 return handleAmbiguousSend(node, name, element);
1834 }
1835 if (element.isErroneous) {
1836 // This handles elements with parser errors.
1837 // TODO(johnniwinther): Elements with parse error should not set
1838 // [isErroneous] to `true`.
1839 assert(invariant(node, element is! ErroneousElement,
1840 message: "Unexpected erroneous element $element."));
1841 return handleErroneousAccess(node, name, element,
1842 new StaticAccess.unresolved(element));
1843 }
1844 if (element.isInstanceMember) {
1845 if (inInstanceContext) {
1846 // TODO(johnniwinther): Maybe use the found [element].
1847 return handleThisPropertyAccess(node, name);
1848 } else {
1849 return handleStaticInstanceSend(node, name, element);
1850 }
1851 }
1852 if (element.isClass || element.isTypedef) {
1853 return oldVisitSend(node);
1854 } else if (element.isTypeVariable) {
1855 return oldVisitSend(node);
1856 } else if (element.isPrefix) {
1857 return oldVisitSend(node);
1858 } else if (element.isLocal) {
1859 return handleLocalAccess(node, name, element);
1860 } else if (element.isStatic || element.isTopLevel) {
1861 return handleStaticOrTopLevelAccess(node, name, element);
1862 }
1863 return internalError(node, "Unexpected resolved send: $element");
1864 }
1865
1539 /// Handle an unqualified [Send], that is where the `node.receiver` is null, 1866 /// Handle an unqualified [Send], that is where the `node.receiver` is null,
1540 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. 1867 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`.
1541 ResolutionResult handleUnqualifiedSend(Send node) { 1868 ResolutionResult handleUnqualifiedSend(Send node) {
1542 Identifier selector = node.selector.asIdentifier(); 1869 Identifier selector = node.selector.asIdentifier();
1543 if (selector == null) { 1870 if (selector == null) {
1544 // `(){}()` and `(foo)()`. 1871 // `(){}()` and `(foo)()`.
1545 return handleExpressionInvoke(node); 1872 return handleExpressionInvoke(node);
1546 } 1873 }
1547 String text = selector.source; 1874 String text = selector.source;
1548 if (text == 'assert') { 1875 if (text == 'assert') {
(...skipping 12 matching lines...) Expand all
1561 Element element = lookupInScope(compiler, node, scope, text); 1888 Element element = lookupInScope(compiler, node, scope, text);
1562 if (element == null) { 1889 if (element == null) {
1563 if (inInstanceContext) { 1890 if (inInstanceContext) {
1564 // Implicitly `this.name`. 1891 // Implicitly `this.name`.
1565 return handleThisPropertyAccess(node, name); 1892 return handleThisPropertyAccess(node, name);
1566 } else { 1893 } else {
1567 // Create [ErroneousElement] for unresolved access. 1894 // Create [ErroneousElement] for unresolved access.
1568 ErroneousElement error = reportCannotResolve(node, text); 1895 ErroneousElement error = reportCannotResolve(node, text);
1569 return handleUnresolvedAccess(node, name, error); 1896 return handleUnresolvedAccess(node, name, error);
1570 } 1897 }
1898 } else {
1899 return handleResolvedSend(node, name, element);
1571 } 1900 }
1572 return oldVisitSend(node);
1573 } 1901 }
1574 1902
1575 ResolutionResult visitSend(Send node) { 1903 ResolutionResult visitSend(Send node) {
1576 if (node.isOperator) { 1904 if (node.isOperator) {
1905 // `a && b`, `a + b`, `-a`, or `a is T`.
1577 return handleOperatorSend(node); 1906 return handleOperatorSend(node);
1578 } else if (node.receiver != null) { 1907 } else if (node.receiver != null) {
1908 // `a.b`.
1579 return handleQualifiedSend(node); 1909 return handleQualifiedSend(node);
1580 } else { 1910 } else {
1911 // `a`.
1581 return handleUnqualifiedSend(node); 1912 return handleUnqualifiedSend(node);
1582 } 1913 }
1583 return oldVisitSend(node); 1914 }
1915
1916 /// Regigster read access of [target] inside a closure.
1917 void registerPotentialAccessInClosure(Send node, Element target) {
1918 if (isPotentiallyMutableTarget(target)) {
1919 if (enclosingElement != target.enclosingElement) {
1920 for (Node scope in promotionScope) {
1921 registry.setAccessedByClosureIn(scope, target, node);
1922 }
1923 }
1924 }
1584 } 1925 }
1585 1926
1586 ResolutionResult oldVisitSend(Send node) { 1927 ResolutionResult oldVisitSend(Send node) {
1587 bool oldSendIsMemberAccess = sendIsMemberAccess; 1928 bool oldSendIsMemberAccess = sendIsMemberAccess;
1588 sendIsMemberAccess = node.isPropertyAccess || node.isCall; 1929 sendIsMemberAccess = node.isPropertyAccess || node.isCall;
1589 1930
1590 ResolutionResult result = resolveSend(node); 1931 ResolutionResult result = resolveSend(node);
1591 sendIsMemberAccess = oldSendIsMemberAccess; 1932 sendIsMemberAccess = oldSendIsMemberAccess;
1592 1933
1593 Element target = result.element; 1934 Element target = result.element;
(...skipping 27 matching lines...) Expand all
1621 compiler.reportError(node, 1962 compiler.reportError(node,
1622 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, 1963 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
1623 {'typeVariableName': node.selector}); 1964 {'typeVariableName': node.selector});
1624 } 1965 }
1625 registry.registerClassUsingVariableExpression(cls); 1966 registry.registerClassUsingVariableExpression(cls);
1626 registry.registerTypeVariableExpression(); 1967 registry.registerTypeVariableExpression();
1627 registerTypeLiteralAccess(node, target); 1968 registerTypeLiteralAccess(node, target);
1628 } else if (target.impliesType && (!sendIsMemberAccess || node.isCall)) { 1969 } else if (target.impliesType && (!sendIsMemberAccess || node.isCall)) {
1629 registerTypeLiteralAccess(node, target); 1970 registerTypeLiteralAccess(node, target);
1630 } 1971 }
1631 if (isPotentiallyMutableTarget(target)) { 1972 registerPotentialAccessInClosure(node, target);
1632 if (enclosingElement != target.enclosingElement) {
1633 for (Node scope in promotionScope) {
1634 registry.setAccessedByClosureIn(scope, target, node);
1635 }
1636 }
1637 }
1638 } 1973 }
1639 1974
1640 bool resolvedArguments = false; 1975 bool resolvedArguments = false;
1641 resolveArguments(node.argumentsNode); 1976 resolveArguments(node.argumentsNode);
1642 1977
1643 // If the selector is null, it means that we will not be generating 1978 // If the selector is null, it means that we will not be generating
1644 // code for this as a send. 1979 // code for this as a send.
1645 Selector selector = registry.getSelector(node); 1980 Selector selector = registry.getSelector(node);
1646 if (selector == null) return const NoneResult(); 1981 if (selector == null) return const NoneResult();
1647 1982
(...skipping 17 matching lines...) Expand all
1665 function.computeSignature(compiler); 2000 function.computeSignature(compiler);
1666 } 2001 }
1667 if (!selector.applies(target, compiler.world)) { 2002 if (!selector.applies(target, compiler.world)) {
1668 registry.registerThrowNoSuchMethod(); 2003 registry.registerThrowNoSuchMethod();
1669 if (node.isSuperCall) { 2004 if (node.isSuperCall) {
1670 internalError(node, "Unexpected super call $node"); 2005 internalError(node, "Unexpected super call $node");
1671 } 2006 }
1672 } 2007 }
1673 } 2008 }
1674 2009
1675 if (target != null && compiler.backend.isForeign(target)) { 2010 handleForeignCall(node, target, selector);
1676 if (selector.name == 'JS') {
1677 registry.registerJsCall(node, this);
1678 } else if (selector.name == 'JS_EMBEDDED_GLOBAL') {
1679 registry.registerJsEmbeddedGlobalCall(node, this);
1680 } else if (selector.name == 'JS_BUILTIN') {
1681 registry.registerJsBuiltinCall(node, this);
1682 } else if (selector.name == 'JS_INTERCEPTOR_CONSTANT') {
1683 if (!node.argumentsNode.isEmpty) {
1684 Node argument = node.argumentsNode.nodes.head;
1685 if (argumentsToJsInterceptorConstant == null) {
1686 argumentsToJsInterceptorConstant = new Set<Node>();
1687 }
1688 argumentsToJsInterceptorConstant.add(argument);
1689 }
1690 }
1691 }
1692 } 2011 }
1693 2012
1694 registry.useElement(node, target); 2013 registry.useElement(node, target);
1695 registerSend(selector, target); 2014 registerSend(selector, target);
1696 if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) { 2015 if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) {
1697 registry.registerGetOfStaticFunction(target.declaration); 2016 registry.registerGetOfStaticFunction(target.declaration);
1698 } 2017 }
1699 return node.isPropertyAccess 2018 return node.isPropertyAccess
1700 ? new ResolutionResult.forElement(target) : const NoneResult(); 2019 ? new ResolutionResult.forElement(target) : const NoneResult();
1701 } 2020 }
1702 2021
2022 // TODO(johnniwinther): Move this to the backend resolution callbacks.
2023 void handleForeignCall(Send node, Element target, Selector selector) {
2024 if (target != null && compiler.backend.isForeign(target)) {
2025 if (selector.name == 'JS') {
2026 registry.registerJsCall(node, this);
2027 } else if (selector.name == 'JS_EMBEDDED_GLOBAL') {
2028 registry.registerJsEmbeddedGlobalCall(node, this);
2029 } else if (selector.name == 'JS_BUILTIN') {
2030 registry.registerJsBuiltinCall(node, this);
2031 } else if (selector.name == 'JS_INTERCEPTOR_CONSTANT') {
2032 if (!node.argumentsNode.isEmpty) {
2033 Node argument = node.argumentsNode.nodes.head;
2034 if (argumentsToJsInterceptorConstant == null) {
2035 argumentsToJsInterceptorConstant = new Set<Node>();
2036 }
2037 argumentsToJsInterceptorConstant.add(argument);
2038 }
2039 }
2040 }
2041 }
2042
1703 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. 2043 /// Callback for native enqueuer to parse a type. Returns [:null:] on error.
1704 DartType resolveTypeFromString(Node node, String typeName) { 2044 DartType resolveTypeFromString(Node node, String typeName) {
1705 Element element = lookupInScope(compiler, node, scope, typeName); 2045 Element element = lookupInScope(compiler, node, scope, typeName);
1706 if (element == null) return null; 2046 if (element == null) return null;
1707 if (element is! ClassElement) return null; 2047 if (element is! ClassElement) return null;
1708 ClassElement cls = element; 2048 ClassElement cls = element;
1709 cls.ensureResolved(compiler); 2049 cls.ensureResolved(compiler);
1710 return cls.computeType(compiler); 2050 return cls.computeType(compiler);
1711 } 2051 }
1712 2052
(...skipping 1212 matching lines...) Expand 10 before | Expand all | Expand 10 after
2925 } 3265 }
2926 return const NoneResult(); 3266 return const NoneResult();
2927 } 3267 }
2928 } 3268 }
2929 3269
2930 /// Looks up [name] in [scope] and unwraps the result. 3270 /// Looks up [name] in [scope] and unwraps the result.
2931 Element lookupInScope(Compiler compiler, Node node, 3271 Element lookupInScope(Compiler compiler, Node node,
2932 Scope scope, String name) { 3272 Scope scope, String name) {
2933 return Elements.unwrap(scope.lookup(name), compiler, node); 3273 return Elements.unwrap(scope.lookup(name), compiler, node);
2934 } 3274 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/simple_types_inferrer.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