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

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

Issue 1262363003: Handle super index SendSet operations. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 5 years, 4 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 /// The state of constants in resolutions. 7 /// The state of constants in resolutions.
8 enum ConstantState { 8 enum ConstantState {
9 /// Expressions are not required to be constants. 9 /// Expressions are not required to be constants.
10 NON_CONSTANT, 10 NON_CONSTANT,
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 // This is a hack for the case of prefix.Type, we need to store 867 // This is a hack for the case of prefix.Type, we need to store
868 // the element on the selector, so [analyzeConstant] can build 868 // the element on the selector, so [analyzeConstant] can build
869 // the type literal from the selector. 869 // the type literal from the selector.
870 registry.useElement(node.selector, target); 870 registry.useElement(node.selector, target);
871 } 871 }
872 analyzeConstantDeferred(node.selector, enforceConst: false); 872 analyzeConstantDeferred(node.selector, enforceConst: false);
873 } 873 }
874 } 874 }
875 } 875 }
876 876
877 /// Check that access to `super` is currently allowed. 877 /// Check that access to `super` is currently allowed. Returns an
878 bool checkSuperAccess(Send node) { 878 /// [AccessSemantics] in case of an error, `null` otherwise.
879 AccessSemantics checkSuperAccess(Send node) {
879 if (!inInstanceContext) { 880 if (!inInstanceContext) {
880 compiler.reportError(node, MessageKind.NO_SUPER_IN_STATIC); 881 return new StaticAccess.invalid(
881 return false; 882 reportAndCreateErroneousElement(
883 node, 'super',
884 MessageKind.NO_SUPER_IN_STATIC, {},
885 isError: true));
882 } 886 }
883 if (node.isConditional) { 887 if (node.isConditional) {
884 // `super?.foo` is not allowed. 888 // `super?.foo` is not allowed.
885 compiler.reportError(node, MessageKind.INVALID_USE_OF_SUPER); 889 return new StaticAccess.invalid(
886 return false; 890 reportAndCreateErroneousElement(
891 node, 'super',
892 MessageKind.INVALID_USE_OF_SUPER, {},
893 isError: true));
887 } 894 }
888 if (currentClass.supertype == null) { 895 if (currentClass.supertype == null) {
889 // This is just to guard against internal errors, so no need 896 // This is just to guard against internal errors, so no need
890 // for a real error message. 897 // for a real error message.
891 compiler.reportError(node, MessageKind.GENERIC, 898 return new StaticAccess.invalid(
892 {'text': "Object has no superclass"}); 899 reportAndCreateErroneousElement(
893 return false; 900 node, 'super',
901 MessageKind.GENERIC,
902 {'text': "Object has no superclass"},
903 isError: true));
894 } 904 }
895 registry.registerSuperUse(node); 905 registry.registerSuperUse(node);
896 return true; 906 return null;
897 } 907 }
898 908
899 /// Check that access to `this` is currently allowed. 909 /// Check that access to `this` is currently allowed.
900 bool checkThisAccess(Send node) { 910 bool checkThisAccess(Send node) {
901 if (!inInstanceContext) { 911 if (!inInstanceContext) {
902 compiler.reportError(node, MessageKind.NO_THIS_AVAILABLE); 912 compiler.reportError(node, MessageKind.NO_THIS_AVAILABLE);
903 return false; 913 return false;
904 } 914 }
905 return true; 915 return true;
906 } 916 }
(...skipping 12 matching lines...) Expand all
919 } else { 929 } else {
920 return new StaticAccess.superField(target); 930 return new StaticAccess.superField(target);
921 } 931 }
922 } else { 932 } else {
923 assert(invariant(node, target.isFunction, 933 assert(invariant(node, target.isFunction,
924 message: "Unexpected super target '$target'.")); 934 message: "Unexpected super target '$target'."));
925 return new StaticAccess.superMethod(target); 935 return new StaticAccess.superMethod(target);
926 } 936 }
927 } 937 }
928 938
939 /// Compute the [AccessSemantics] corresponding to a compound super access
940 /// reading from [getter] and writing to [setter].
941 AccessSemantics computeCompoundSuperAccessSemantics(
942 Spannable node,
943 Element getter,
944 Element setter) {
945 if (getter.isErroneous) {
946 if (setter.isErroneous) {
947 return new StaticAccess.unresolvedSuper(getter);
948 } else if (setter.isFunction) {
949 assert(invariant(node, setter.name == '[]=',
950 message: "Unexpected super setter '$setter'."));
951 return new CompoundAccessSemantics(
952 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter);
953 } else {
954 assert(invariant(node, setter.isSetter,
955 message: "Unexpected super setter '$setter'."));
956 return new CompoundAccessSemantics(
957 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter);
958 }
959 } else if (getter.isField) {
960 if (setter.isField) {
961 if (getter == setter) {
962 return new StaticAccess.superField(getter);
963 } else {
964 return new CompoundAccessSemantics(
965 CompoundAccessKind.SUPER_FIELD_FIELD, getter, setter);
966 }
967 } else {
968 // Either the field is accessible directly, or a setter shadows the
969 // setter access. If there was another instance member it would shadow
970 // the field.
971 assert(invariant(node, setter.isSetter,
972 message: "Unexpected super setter '$setter'."));
973 return new CompoundAccessSemantics(
974 CompoundAccessKind.SUPER_FIELD_SETTER, getter, setter);
975 }
976 } else if (getter.isGetter) {
977 if (setter.isErroneous) {
978 return new CompoundAccessSemantics(
979 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
980 } else if (setter.isField) {
981 return new CompoundAccessSemantics(
982 CompoundAccessKind.SUPER_GETTER_FIELD, getter, setter);
983 } else {
984 assert(invariant(node, setter.isSetter,
985 message: "Unexpected super setter '$setter'."));
986 return new CompoundAccessSemantics(
987 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter);
988 }
989 } else {
990 assert(invariant(node, getter.isFunction,
991 message: "Unexpected super getter '$getter'."));
992 if (setter.isErroneous) {
993 return new CompoundAccessSemantics(
994 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
995 } else if (setter.isFunction) {
996 assert(invariant(node, getter.name == '[]',
997 message: "Unexpected super getter '$getter'."));
998 assert(invariant(node, setter.name == '[]=',
999 message: "Unexpected super setter '$setter'."));
1000 return new CompoundAccessSemantics(
1001 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter);
1002 } else {
1003 assert(invariant(node, setter.isSetter,
1004 message: "Unexpected super setter '$setter'."));
1005 return new CompoundAccessSemantics(
1006 CompoundAccessKind.SUPER_METHOD_SETTER, getter, setter);
1007 }
1008 }
1009 }
1010
929 /// Compute the [AccessSemantics] corresponding to a local access of [target]. 1011 /// Compute the [AccessSemantics] corresponding to a local access of [target].
930 AccessSemantics computeLocalAccessSemantics(Spannable node, 1012 AccessSemantics computeLocalAccessSemantics(Spannable node,
931 LocalElement target) { 1013 LocalElement target) {
932 if (target.isParameter) { 1014 if (target.isParameter) {
933 if (target.isFinal || target.isConst) { 1015 if (target.isFinal || target.isConst) {
934 return new StaticAccess.finalParameter(target); 1016 return new StaticAccess.finalParameter(target);
935 } else { 1017 } else {
936 return new StaticAccess.parameter(target); 1018 return new StaticAccess.parameter(target);
937 } 1019 }
938 } else if (target.isVariable) { 1020 } else if (target.isVariable) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 target = error; 1118 target = error;
1037 } 1119 }
1038 // We still need to register the invocation, because we might 1120 // We still need to register the invocation, because we might
1039 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. 1121 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
1040 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); 1122 registry.registerDynamicInvocation(new UniverseSelector(selector, null));
1041 registry.registerSuperNoSuchMethod(); 1123 registry.registerSuperNoSuchMethod();
1042 } 1124 }
1043 return computeSuperAccessSemantics(node, target); 1125 return computeSuperAccessSemantics(node, target);
1044 } 1126 }
1045 1127
1128 /// Compute the [AccessSemantics] for accessing the name of [selector] on the
1129 /// super class.
1130 ///
1131 /// If no matching super member is found and error is reported and
1132 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName]
1133 /// is provided, the [AccessSemantics] corresponding to the alternate name is
1134 /// returned. For instance, the access of a super setter for an unresolved
1135 /// getter:
1136 ///
1137 /// class Super {
1138 /// set name(_) {}
1139 /// }
1140 /// class Sub extends Super {
1141 /// foo => super.name; // Access to the setter.
1142 /// }
1143 ///
1144 AccessSemantics computeSuperAccessSemanticsForSelectors(
1145 Spannable node,
1146 Selector getterSelector, Selector setterSelector) {
1147
1148 // TODO(johnniwinther): Ensure correct behavior if currentClass is a
1149 // patch.
1150 Element getter = currentClass.lookupSuperByName(getterSelector.memberName);
1151 // [target] may be null which means invoking noSuchMethod on super.
1152 if (getter == null) {
1153 getter = reportAndCreateErroneousElement(
1154 node, getterSelector.name, MessageKind.NO_SUCH_SUPER_MEMBER,
1155 {'className': currentClass.name, 'memberName': getterSelector.name});
1156 // We still need to register the invocation, because we might
1157 // call `super.noSuchMethod` which calls [JSInvocationMirror._invokeOn].
1158 registry.registerDynamicInvocation(
1159 new UniverseSelector(getterSelector, null));
1160 registry.registerSuperNoSuchMethod();
1161 }
1162 Element setter = currentClass.lookupSuperByName(setterSelector.memberName);
1163 // [target] may be null which means invoking noSuchMethod on super.
1164 if (setter == null) {
1165 setter = reportAndCreateErroneousElement(
1166 node, setterSelector.name, MessageKind.NO_SUCH_SUPER_MEMBER,
1167 {'className': currentClass.name, 'memberName': setterSelector.name});
1168 // We still need to register the invocation, because we might
1169 // call `super.noSuchMethod` which calls [JSInvocationMirror._invokeOn].
1170 registry.registerDynamicInvocation(
1171 new UniverseSelector(setterSelector, null));
1172 registry.registerSuperNoSuchMethod();
1173 }
1174 return computeCompoundSuperAccessSemantics(node, getter, setter);
1175 }
1176
1046 /// Resolve [node] as a subexpression that is _not_ the prefix of a member 1177 /// Resolve [node] as a subexpression that is _not_ the prefix of a member
1047 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`. 1178 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`.
1048 ResolutionResult visitExpression(Node node) { 1179 ResolutionResult visitExpression(Node node) {
1049 bool oldSendIsMemberAccess = sendIsMemberAccess; 1180 bool oldSendIsMemberAccess = sendIsMemberAccess;
1050 sendIsMemberAccess = false; 1181 sendIsMemberAccess = false;
1051 ResolutionResult result = visit(node); 1182 ResolutionResult result = visit(node);
1052 sendIsMemberAccess = oldSendIsMemberAccess; 1183 sendIsMemberAccess = oldSendIsMemberAccess;
1053 return result; 1184 return result;
1054 } 1185 }
1055 1186
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) { 1275 ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) {
1145 ResolutionResult result = const NoneResult(); 1276 ResolutionResult result = const NoneResult();
1146 Node expression = node.receiver; 1277 Node expression = node.receiver;
1147 Selector selector = operator.selector; 1278 Selector selector = operator.selector;
1148 // TODO(johnniwinther): Remove this when all information goes through the 1279 // TODO(johnniwinther): Remove this when all information goes through the
1149 // [SendStructure]. 1280 // [SendStructure].
1150 registry.setSelector(node, selector); 1281 registry.setSelector(node, selector);
1151 1282
1152 AccessSemantics semantics; 1283 AccessSemantics semantics;
1153 if (node.isSuperCall) { 1284 if (node.isSuperCall) {
1154 if (checkSuperAccess(node)) { 1285 semantics = checkSuperAccess(node);
1286 if (semantics == null) {
1155 semantics = computeSuperAccessSemanticsForSelector(node, selector); 1287 semantics = computeSuperAccessSemanticsForSelector(node, selector);
1156 // TODO(johnniwinther): Add information to [AccessSemantics] about 1288 // TODO(johnniwinther): Add information to [AccessSemantics] about
1157 // whether it is erroneous. 1289 // whether it is erroneous.
1158 if (semantics.kind == AccessKind.SUPER_METHOD) { 1290 if (semantics.kind == AccessKind.SUPER_METHOD) {
1159 registry.registerStaticUse(semantics.element.declaration); 1291 registry.registerStaticUse(semantics.element.declaration);
1160 } 1292 }
1161 // TODO(johnniwinther): Remove this when all information goes through 1293 // TODO(johnniwinther): Remove this when all information goes through
1162 // the [SendStructure]. 1294 // the [SendStructure].
1163 registry.useElement(node, semantics.element); 1295 registry.useElement(node, semantics.element);
1164 } 1296 }
(...skipping 25 matching lines...) Expand all
1190 // TODO(johnniwinther): Handle potentially invalid constant 1322 // TODO(johnniwinther): Handle potentially invalid constant
1191 // expressions. 1323 // expressions.
1192 ConstantExpression constant = 1324 ConstantExpression constant =
1193 new UnaryConstantExpression(operator, expressionConstant); 1325 new UnaryConstantExpression(operator, expressionConstant);
1194 registry.setConstant(node, constant); 1326 registry.setConstant(node, constant);
1195 result = new ConstantResult(node, constant); 1327 result = new ConstantResult(node, constant);
1196 } 1328 }
1197 } 1329 }
1198 } 1330 }
1199 if (semantics != null) { 1331 if (semantics != null) {
1200 // TODO(johnniwinther): Support invalid super access as an
1201 // [AccessSemantics].
1202 registry.registerSendStructure(node, 1332 registry.registerSendStructure(node,
1203 new UnaryStructure(semantics, operator)); 1333 new UnaryStructure(semantics, operator));
1204 } 1334 }
1205 return result; 1335 return result;
1206 } 1336 }
1207 1337
1208 /// Handle a not expression, like `!a`. 1338 /// Handle a not expression, like `!a`.
1209 ResolutionResult handleNot(Send node, UnaryOperator operator) { 1339 ResolutionResult handleNot(Send node, UnaryOperator operator) {
1210 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); 1340 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT));
1211 1341
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 if (operator.kind == BinaryOperatorKind.INDEX) { 1448 if (operator.kind == BinaryOperatorKind.INDEX) {
1319 selector = new Selector.index(); 1449 selector = new Selector.index();
1320 } else { 1450 } else {
1321 selector = new Selector.binaryOperator(operator.selectorName); 1451 selector = new Selector.binaryOperator(operator.selectorName);
1322 } 1452 }
1323 // TODO(johnniwinther): Remove this when all information goes through the 1453 // TODO(johnniwinther): Remove this when all information goes through the
1324 // [SendStructure]. 1454 // [SendStructure].
1325 registry.setSelector(node, selector); 1455 registry.setSelector(node, selector);
1326 1456
1327 if (node.isSuperCall) { 1457 if (node.isSuperCall) {
1328 if (checkSuperAccess(node)) { 1458 semantics = checkSuperAccess(node);
1459 if (semantics == null) {
1329 semantics = computeSuperAccessSemanticsForSelector(node, selector); 1460 semantics = computeSuperAccessSemanticsForSelector(node, selector);
1330 // TODO(johnniwinther): Add information to [AccessSemantics] about 1461 // TODO(johnniwinther): Add information to [AccessSemantics] about
1331 // whether it is erroneous. 1462 // whether it is erroneous.
1332 if (semantics.kind == AccessKind.SUPER_METHOD) { 1463 if (semantics.kind == AccessKind.SUPER_METHOD) {
1333 registry.registerStaticUse(semantics.element.declaration); 1464 registry.registerStaticUse(semantics.element.declaration);
1334 } 1465 }
1335 // TODO(johnniwinther): Remove this when all information goes through 1466 // TODO(johnniwinther): Remove this when all information goes through
1336 // the [SendStructure]. 1467 // the [SendStructure].
1337 registry.useElement(node, semantics.element); 1468 registry.useElement(node, semantics.element);
1338 } 1469 }
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 Element target; 1676 Element target;
1546 Selector selector; 1677 Selector selector;
1547 CallStructure callStructure = CallStructure.NO_ARGS; 1678 CallStructure callStructure = CallStructure.NO_ARGS;
1548 if (node.isCall) { 1679 if (node.isCall) {
1549 callStructure = 1680 callStructure =
1550 resolveArguments(node.argumentsNode).callStructure; 1681 resolveArguments(node.argumentsNode).callStructure;
1551 selector = new Selector(SelectorKind.CALL, name, callStructure); 1682 selector = new Selector(SelectorKind.CALL, name, callStructure);
1552 } else { 1683 } else {
1553 selector = new Selector(SelectorKind.GETTER, name, callStructure); 1684 selector = new Selector(SelectorKind.GETTER, name, callStructure);
1554 } 1685 }
1555 if (checkSuperAccess(node)) { 1686 AccessSemantics semantics = checkSuperAccess(node);
1556 AccessSemantics semantics = computeSuperAccessSemanticsForSelector( 1687 if (semantics == null) {
1688 semantics = computeSuperAccessSemanticsForSelector(
1557 node, selector, alternateName: name.setter); 1689 node, selector, alternateName: name.setter);
1558 if (node.isCall) { 1690 }
1559 bool isIncompatibleInvoke = false; 1691 if (node.isCall) {
1560 switch (semantics.kind) { 1692 bool isIncompatibleInvoke = false;
1561 case AccessKind.SUPER_METHOD: 1693 switch (semantics.kind) {
1562 MethodElementX superMethod = semantics.element; 1694 case AccessKind.SUPER_METHOD:
1563 superMethod.computeSignature(compiler); 1695 MethodElementX superMethod = semantics.element;
1564 if (!callStructure.signatureApplies( 1696 superMethod.computeSignature(compiler);
1565 superMethod.functionSignature)) { 1697 if (!callStructure.signatureApplies(
1566 registry.registerThrowNoSuchMethod(); 1698 superMethod.functionSignature)) {
1567 registry.registerDynamicInvocation( 1699 registry.registerThrowNoSuchMethod();
1568 new UniverseSelector(selector, null));
1569 registry.registerSuperNoSuchMethod();
1570 isIncompatibleInvoke = true;
1571 } else {
1572 registry.registerStaticInvocation(semantics.element);
1573 }
1574 break;
1575 case AccessKind.SUPER_FIELD:
1576 case AccessKind.SUPER_FINAL_FIELD:
1577 case AccessKind.SUPER_GETTER:
1578 registry.registerStaticUse(semantics.element);
1579 selector = callStructure.callSelector;
1580 registry.registerDynamicInvocation( 1700 registry.registerDynamicInvocation(
1581 new UniverseSelector(selector, null)); 1701 new UniverseSelector(selector, null));
1582 break; 1702 registry.registerSuperNoSuchMethod();
1583 case AccessKind.SUPER_SETTER: 1703 isIncompatibleInvoke = true;
1584 case AccessKind.UNRESOLVED_SUPER: 1704 } else {
1585 // NoSuchMethod registered in [computeSuperSemantics]. 1705 registry.registerStaticInvocation(semantics.element);
1586 break; 1706 }
1587 default: 1707 break;
1588 internalError(node, "Unexpected super property access $semantics."); 1708 case AccessKind.SUPER_FIELD:
1589 break; 1709 case AccessKind.SUPER_FINAL_FIELD:
1590 } 1710 case AccessKind.SUPER_GETTER:
1591 registry.registerSendStructure(node, 1711 registry.registerStaticUse(semantics.element);
1592 isIncompatibleInvoke 1712 selector = callStructure.callSelector;
1593 ? new IncompatibleInvokeStructure(semantics, selector) 1713 registry.registerDynamicInvocation(
1594 : new InvokeStructure(semantics, selector)); 1714 new UniverseSelector(selector, null));
1595 } else { 1715 break;
1596 switch (semantics.kind) { 1716 case AccessKind.SUPER_SETTER:
1597 case AccessKind.SUPER_METHOD: 1717 case AccessKind.UNRESOLVED_SUPER:
1598 // TODO(johnniwinther): Method this should be registered as a 1718 // NoSuchMethod registered in [computeSuperSemantics].
1599 // closurization. 1719 break;
1600 registry.registerStaticUse(semantics.element); 1720 case AccessKind.INVALID:
1601 break; 1721 // 'super' is not allowed.
1602 case AccessKind.SUPER_FIELD: 1722 break;
1603 case AccessKind.SUPER_FINAL_FIELD: 1723 default:
1604 case AccessKind.SUPER_GETTER: 1724 internalError(node, "Unexpected super property access $semantics.");
1605 registry.registerStaticUse(semantics.element); 1725 break;
1606 break;
1607 case AccessKind.SUPER_SETTER:
1608 case AccessKind.UNRESOLVED_SUPER:
1609 // NoSuchMethod registered in [computeSuperSemantics].
1610 break;
1611 default:
1612 internalError(node, "Unexpected super property access $semantics.");
1613 break;
1614 }
1615 registry.registerSendStructure(node,
1616 new GetStructure(semantics, selector));
1617 } 1726 }
1618 target = semantics.element; 1727 registry.registerSendStructure(node,
1728 isIncompatibleInvoke
1729 ? new IncompatibleInvokeStructure(semantics, selector)
1730 : new InvokeStructure(semantics, selector));
1731 } else {
1732 switch (semantics.kind) {
1733 case AccessKind.SUPER_METHOD:
1734 // TODO(johnniwinther): Method this should be registered as a
1735 // closurization.
1736 registry.registerStaticUse(semantics.element);
1737 break;
1738 case AccessKind.SUPER_FIELD:
1739 case AccessKind.SUPER_FINAL_FIELD:
1740 case AccessKind.SUPER_GETTER:
1741 registry.registerStaticUse(semantics.element);
1742 break;
1743 case AccessKind.SUPER_SETTER:
1744 case AccessKind.UNRESOLVED_SUPER:
1745 // NoSuchMethod registered in [computeSuperSemantics].
1746 break;
1747 case AccessKind.INVALID:
1748 // 'super' is not allowed.
1749 break;
1750 default:
1751 internalError(node, "Unexpected super property access $semantics.");
1752 break;
1753 }
1754 registry.registerSendStructure(node,
1755 new GetStructure(semantics, selector));
1619 } 1756 }
1757 target = semantics.element;
1620 1758
1621 // TODO(johnniwinther): Remove these when all information goes through 1759 // TODO(johnniwinther): Remove these when all information goes through
1622 // the [SendStructure]. 1760 // the [SendStructure].
1623 registry.useElement(node, target); 1761 registry.useElement(node, target);
1624 registry.setSelector(node, selector); 1762 registry.setSelector(node, selector);
1625 return const NoneResult(); 1763 return const NoneResult();
1626 } 1764 }
1627 1765
1628 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`, 1766 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`,
1629 /// `a + b`, and `~a`. 1767 /// `a + b`, and `~a`.
(...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after
2614 new UniverseSelector(operatorSelector, null)); 2752 new UniverseSelector(operatorSelector, null));
2615 2753
2616 SendStructure sendStructure = new CompoundIndexSetStructure( 2754 SendStructure sendStructure = new CompoundIndexSetStructure(
2617 semantics, operator, getterSelector, setterSelector); 2755 semantics, operator, getterSelector, setterSelector);
2618 registry.registerSendStructure(node, sendStructure); 2756 registry.registerSendStructure(node, sendStructure);
2619 return const NoneResult(); 2757 return const NoneResult();
2620 } 2758 }
2621 } 2759 }
2622 } 2760 }
2623 2761
2762 /// Handle super index operations like `super[a] = b`, `super[a] += b`, and
2763 /// `super[a]++`.
2764 // TODO(johnniwinther): Share code with [handleIndexSendSet].
2765 ResolutionResult handleSuperIndexSendSet(SendSet node) {
2766 String operatorText = node.assignmentOperator.source;
2767 Node index = node.arguments.head;
2768 visitExpression(index);
2769 AccessSemantics semantics = checkSuperAccess(node);
2770 if (node.isPrefix || node.isPostfix) {
2771 // `super[a]++` or `++super[a]`.
2772 IncDecOperator operator = IncDecOperator.parse(operatorText);
2773 Selector getterSelector = new Selector.index();
2774 Selector setterSelector = new Selector.indexSet();
2775 Selector operatorSelector =
2776 new Selector.binaryOperator(operator.selectorName);
2777
2778 // TODO(johnniwinther): Remove these when selectors are only accessed
2779 // through the send structure.
2780 registry.setGetterSelectorInComplexSendSet(node, getterSelector);
2781 registry.setSelector(node, setterSelector);
2782 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
2783
2784 if (semantics == null) {
2785 semantics = computeSuperAccessSemanticsForSelectors(
2786 node, getterSelector, setterSelector);
2787
2788 registry.registerStaticInvocation(semantics.getter);
2789 registry.registerStaticInvocation(semantics.setter);
2790
2791 // TODO(johnniwinther): Remove these when elements are only accessed
2792 // through the send structure.
2793 registry.useElement(node, semantics.setter);
2794 registry.useElement(node.selector, semantics.getter);
2795 }
2796 registry.registerDynamicInvocation(
2797 new UniverseSelector(operatorSelector, null));
2798
2799 SendStructure sendStructure = node.isPrefix
2800 ? new IndexPrefixStructure(
2801 semantics, operator, getterSelector, setterSelector)
2802 : new IndexPostfixStructure(
2803 semantics, operator, getterSelector, setterSelector);
2804 registry.registerSendStructure(node, sendStructure);
2805 return const NoneResult();
2806 } else {
2807 Node rhs = node.arguments.tail.head;
2808 visitExpression(rhs);
2809
2810 AssignmentOperator operator = AssignmentOperator.parse(operatorText);
2811 if (operator.kind == AssignmentOperatorKind.ASSIGN) {
2812 // `super[a] = b`.
2813 Selector setterSelector = new Selector.indexSet();
2814 if (semantics == null) {
2815 semantics =
2816 computeSuperAccessSemanticsForSelector(node, setterSelector);
2817
2818 // TODO(johnniwinther): Remove these when elements are only accessed
2819 // through the send structure.
2820 registry.useElement(node, semantics.setter);
2821 }
2822
2823 // TODO(johnniwinther): Remove this when selectors are only accessed
2824 // through the send structure.
2825 registry.setSelector(node, setterSelector);
2826 registry.registerStaticInvocation(semantics.setter);
2827
2828 SendStructure sendStructure =
2829 new IndexSetStructure(semantics, setterSelector);
2830 registry.registerSendStructure(node, sendStructure);
2831 return const NoneResult();
2832 } else {
2833 // `super[a] += b`.
2834 Selector getterSelector = new Selector.index();
2835 Selector setterSelector = new Selector.indexSet();
2836 Selector operatorSelector =
2837 new Selector.binaryOperator(operator.selectorName);
2838 if (semantics == null) {
2839 semantics = computeSuperAccessSemanticsForSelectors(
2840 node, getterSelector, setterSelector);
2841
2842 registry.registerStaticInvocation(semantics.getter);
2843 registry.registerStaticInvocation(semantics.setter);
2844
2845 // TODO(johnniwinther): Remove these when elements are only accessed
2846 // through the send structure.
2847 registry.useElement(node, semantics.setter);
2848 registry.useElement(node.selector, semantics.getter);
2849 }
2850
2851 // TODO(johnniwinther): Remove these when selectors are only accessed
2852 // through the send structure.
2853 registry.setGetterSelectorInComplexSendSet(node, getterSelector);
2854 registry.setSelector(node, setterSelector);
2855 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
2856
2857 registry.registerDynamicInvocation(
2858 new UniverseSelector(operatorSelector, null));
2859
2860 SendStructure sendStructure = new CompoundIndexSetStructure(
2861 semantics, operator, getterSelector, setterSelector);
2862 registry.registerSendStructure(node, sendStructure);
2863 return const NoneResult();
2864 }
2865 }
2866 }
2867
2624 ResolutionResult visitSendSet(SendSet node) { 2868 ResolutionResult visitSendSet(SendSet node) {
2625 if (node.isIndex) { 2869 if (node.isIndex) {
2626 if (node.isSuperCall) { 2870 if (node.isSuperCall) {
2627 // TODO(johnniwinther): Refactor index operations on super. 2871 return handleSuperIndexSendSet(node);
2628 } else { 2872 } else {
2629 return handleIndexSendSet(node); 2873 return handleIndexSendSet(node);
2630 } 2874 }
2631 } 2875 }
2632 return oldVisitSendSet(node); 2876 return oldVisitSendSet(node);
2633 } 2877 }
2634 2878
2635 ResolutionResult oldVisitSendSet(SendSet node) { 2879 ResolutionResult oldVisitSendSet(SendSet node) {
2636 bool oldSendIsMemberAccess = sendIsMemberAccess; 2880 bool oldSendIsMemberAccess = sendIsMemberAccess;
2637 sendIsMemberAccess = node.isPropertyAccess || node.isCall; 2881 sendIsMemberAccess = node.isPropertyAccess || node.isCall;
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after
3917 } 4161 }
3918 return const NoneResult(); 4162 return const NoneResult();
3919 } 4163 }
3920 } 4164 }
3921 4165
3922 /// Looks up [name] in [scope] and unwraps the result. 4166 /// Looks up [name] in [scope] and unwraps the result.
3923 Element lookupInScope(Compiler compiler, Node node, 4167 Element lookupInScope(Compiler compiler, Node node,
3924 Scope scope, String name) { 4168 Scope scope, String name) {
3925 return Elements.unwrap(scope.lookup(name), compiler, node); 4169 return Elements.unwrap(scope.lookup(name), compiler, node);
3926 } 4170 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/access_semantics.dart ('k') | pkg/compiler/lib/src/resolution/semantic_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698