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

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: Update 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 {
floitsch 2015/07/31 12:30:37 Maybe add a short comment, explaining why it's not
Johnni Winther 2015/07/31 13:38:29 Done.
968 assert(invariant(node, setter.isSetter,
969 message: "Unexpected super setter '$setter'."));
970 return new CompoundAccessSemantics(
971 CompoundAccessKind.SUPER_FIELD_SETTER, getter, setter);
972 }
973 } else if (getter.isGetter) {
974 if (setter.isErroneous) {
975 return new CompoundAccessSemantics(
976 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
977 } else if (setter.isField) {
978 return new CompoundAccessSemantics(
979 CompoundAccessKind.SUPER_GETTER_FIELD, getter, setter);
980 } else {
981 assert(invariant(node, setter.isSetter,
982 message: "Unexpected super setter '$setter'."));
983 return new CompoundAccessSemantics(
984 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter);
985 }
986 } else {
987 assert(invariant(node, getter.isFunction,
988 message: "Unexpected super getter '$getter'."));
989 if (setter.isErroneous) {
990 return new CompoundAccessSemantics(
991 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter);
992 } else if (setter.isFunction) {
993 assert(invariant(node, getter.name == '[]',
994 message: "Unexpected super getter '$getter'."));
995 assert(invariant(node, setter.name == '[]=',
996 message: "Unexpected super setter '$setter'."));
997 return new CompoundAccessSemantics(
998 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter);
999 } else {
1000 assert(invariant(node, setter.isSetter,
1001 message: "Unexpected super setter '$setter'."));
1002 return new CompoundAccessSemantics(
1003 CompoundAccessKind.SUPER_METHOD_SETTER, getter, setter);
1004 }
1005 }
1006 }
1007
929 /// Compute the [AccessSemantics] corresponding to a local access of [target]. 1008 /// Compute the [AccessSemantics] corresponding to a local access of [target].
930 AccessSemantics computeLocalAccessSemantics(Spannable node, 1009 AccessSemantics computeLocalAccessSemantics(Spannable node,
931 LocalElement target) { 1010 LocalElement target) {
932 if (target.isParameter) { 1011 if (target.isParameter) {
933 if (target.isFinal || target.isConst) { 1012 if (target.isFinal || target.isConst) {
934 return new StaticAccess.finalParameter(target); 1013 return new StaticAccess.finalParameter(target);
935 } else { 1014 } else {
936 return new StaticAccess.parameter(target); 1015 return new StaticAccess.parameter(target);
937 } 1016 }
938 } else if (target.isVariable) { 1017 } else if (target.isVariable) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 target = error; 1115 target = error;
1037 } 1116 }
1038 // We still need to register the invocation, because we might 1117 // We still need to register the invocation, because we might
1039 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. 1118 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
1040 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); 1119 registry.registerDynamicInvocation(new UniverseSelector(selector, null));
1041 registry.registerSuperNoSuchMethod(); 1120 registry.registerSuperNoSuchMethod();
1042 } 1121 }
1043 return computeSuperAccessSemantics(node, target); 1122 return computeSuperAccessSemantics(node, target);
1044 } 1123 }
1045 1124
1125 /// Compute the [AccessSemantics] for accessing the name of [selector] on the
1126 /// super class.
1127 ///
1128 /// If no matching super member is found and error is reported and
1129 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName]
1130 /// is provided, the [AccessSemantics] corresponding to the alternate name is
1131 /// returned. For instance, the access of a super setter for an unresolved
1132 /// getter:
1133 ///
1134 /// class Super {
1135 /// set name(_) {}
1136 /// }
1137 /// class Sub extends Super {
1138 /// foo => super.name; // Access to the setter.
1139 /// }
1140 ///
1141 AccessSemantics computeSuperAccessSemanticsForSelectors(
1142 Spannable node,
1143 Selector getterSelector, Selector setterSelector) {
1144
1145 // TODO(johnniwinther): Ensure correct behavior if currentClass is a
1146 // patch.
1147 Element getter = currentClass.lookupSuperByName(getterSelector.memberName);
1148 // [target] may be null which means invoking noSuchMethod on super.
1149 if (getter == null) {
1150 getter = reportAndCreateErroneousElement(
1151 node, getterSelector.name, MessageKind.NO_SUCH_SUPER_MEMBER,
1152 {'className': currentClass.name, 'memberName': getterSelector.name});
1153 // We still need to register the invocation, because we might
1154 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
floitsch 2015/07/31 12:30:37 nit. I prefer `super.noSuchMethod`.
Johnni Winther 2015/07/31 13:38:29 Done.
1155 registry.registerDynamicInvocation(
1156 new UniverseSelector(getterSelector, null));
1157 registry.registerSuperNoSuchMethod();
1158 }
1159 Element setter = currentClass.lookupSuperByName(setterSelector.memberName);
1160 // [target] may be null which means invoking noSuchMethod on super.
1161 if (setter == null) {
1162 setter = reportAndCreateErroneousElement(
1163 node, setterSelector.name, MessageKind.NO_SUCH_SUPER_MEMBER,
1164 {'className': currentClass.name, 'memberName': setterSelector.name});
1165 // We still need to register the invocation, because we might
1166 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
1167 registry.registerDynamicInvocation(
1168 new UniverseSelector(setterSelector, null));
1169 registry.registerSuperNoSuchMethod();
1170 }
1171 return computeCompoundSuperAccessSemantics(node, getter, setter);
1172 }
1173
1046 /// Resolve [node] as a subexpression that is _not_ the prefix of a member 1174 /// 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`. 1175 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`.
1048 ResolutionResult visitExpression(Node node) { 1176 ResolutionResult visitExpression(Node node) {
1049 bool oldSendIsMemberAccess = sendIsMemberAccess; 1177 bool oldSendIsMemberAccess = sendIsMemberAccess;
1050 sendIsMemberAccess = false; 1178 sendIsMemberAccess = false;
1051 ResolutionResult result = visit(node); 1179 ResolutionResult result = visit(node);
1052 sendIsMemberAccess = oldSendIsMemberAccess; 1180 sendIsMemberAccess = oldSendIsMemberAccess;
1053 return result; 1181 return result;
1054 } 1182 }
1055 1183
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1144 ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) { 1272 ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) {
1145 ResolutionResult result = const NoneResult(); 1273 ResolutionResult result = const NoneResult();
1146 Node expression = node.receiver; 1274 Node expression = node.receiver;
1147 Selector selector = operator.selector; 1275 Selector selector = operator.selector;
1148 // TODO(johnniwinther): Remove this when all information goes through the 1276 // TODO(johnniwinther): Remove this when all information goes through the
1149 // [SendStructure]. 1277 // [SendStructure].
1150 registry.setSelector(node, selector); 1278 registry.setSelector(node, selector);
1151 1279
1152 AccessSemantics semantics; 1280 AccessSemantics semantics;
1153 if (node.isSuperCall) { 1281 if (node.isSuperCall) {
1154 if (checkSuperAccess(node)) { 1282 semantics = checkSuperAccess(node);
1283 if (semantics == null) {
1155 semantics = computeSuperAccessSemanticsForSelector(node, selector); 1284 semantics = computeSuperAccessSemanticsForSelector(node, selector);
1156 // TODO(johnniwinther): Add information to [AccessSemantics] about 1285 // TODO(johnniwinther): Add information to [AccessSemantics] about
1157 // whether it is erroneous. 1286 // whether it is erroneous.
1158 if (semantics.kind == AccessKind.SUPER_METHOD) { 1287 if (semantics.kind == AccessKind.SUPER_METHOD) {
1159 registry.registerStaticUse(semantics.element.declaration); 1288 registry.registerStaticUse(semantics.element.declaration);
1160 } 1289 }
1161 // TODO(johnniwinther): Remove this when all information goes through 1290 // TODO(johnniwinther): Remove this when all information goes through
1162 // the [SendStructure]. 1291 // the [SendStructure].
1163 registry.useElement(node, semantics.element); 1292 registry.useElement(node, semantics.element);
1164 } 1293 }
(...skipping 25 matching lines...) Expand all
1190 // TODO(johnniwinther): Handle potentially invalid constant 1319 // TODO(johnniwinther): Handle potentially invalid constant
1191 // expressions. 1320 // expressions.
1192 ConstantExpression constant = 1321 ConstantExpression constant =
1193 new UnaryConstantExpression(operator, expressionConstant); 1322 new UnaryConstantExpression(operator, expressionConstant);
1194 registry.setConstant(node, constant); 1323 registry.setConstant(node, constant);
1195 result = new ConstantResult(node, constant); 1324 result = new ConstantResult(node, constant);
1196 } 1325 }
1197 } 1326 }
1198 } 1327 }
1199 if (semantics != null) { 1328 if (semantics != null) {
1200 // TODO(johnniwinther): Support invalid super access as an
1201 // [AccessSemantics].
1202 registry.registerSendStructure(node, 1329 registry.registerSendStructure(node,
1203 new UnaryStructure(semantics, operator)); 1330 new UnaryStructure(semantics, operator));
1204 } 1331 }
1205 return result; 1332 return result;
1206 } 1333 }
1207 1334
1208 /// Handle a not expression, like `!a`. 1335 /// Handle a not expression, like `!a`.
1209 ResolutionResult handleNot(Send node, UnaryOperator operator) { 1336 ResolutionResult handleNot(Send node, UnaryOperator operator) {
1210 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); 1337 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT));
1211 1338
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 if (operator.kind == BinaryOperatorKind.INDEX) { 1445 if (operator.kind == BinaryOperatorKind.INDEX) {
1319 selector = new Selector.index(); 1446 selector = new Selector.index();
1320 } else { 1447 } else {
1321 selector = new Selector.binaryOperator(operator.selectorName); 1448 selector = new Selector.binaryOperator(operator.selectorName);
1322 } 1449 }
1323 // TODO(johnniwinther): Remove this when all information goes through the 1450 // TODO(johnniwinther): Remove this when all information goes through the
1324 // [SendStructure]. 1451 // [SendStructure].
1325 registry.setSelector(node, selector); 1452 registry.setSelector(node, selector);
1326 1453
1327 if (node.isSuperCall) { 1454 if (node.isSuperCall) {
1328 if (checkSuperAccess(node)) { 1455 semantics = checkSuperAccess(node);
1456 if (semantics == null) {
1329 semantics = computeSuperAccessSemanticsForSelector(node, selector); 1457 semantics = computeSuperAccessSemanticsForSelector(node, selector);
1330 // TODO(johnniwinther): Add information to [AccessSemantics] about 1458 // TODO(johnniwinther): Add information to [AccessSemantics] about
1331 // whether it is erroneous. 1459 // whether it is erroneous.
1332 if (semantics.kind == AccessKind.SUPER_METHOD) { 1460 if (semantics.kind == AccessKind.SUPER_METHOD) {
1333 registry.registerStaticUse(semantics.element.declaration); 1461 registry.registerStaticUse(semantics.element.declaration);
1334 } 1462 }
1335 // TODO(johnniwinther): Remove this when all information goes through 1463 // TODO(johnniwinther): Remove this when all information goes through
1336 // the [SendStructure]. 1464 // the [SendStructure].
1337 registry.useElement(node, semantics.element); 1465 registry.useElement(node, semantics.element);
1338 } 1466 }
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 Element target; 1673 Element target;
1546 Selector selector; 1674 Selector selector;
1547 CallStructure callStructure = CallStructure.NO_ARGS; 1675 CallStructure callStructure = CallStructure.NO_ARGS;
1548 if (node.isCall) { 1676 if (node.isCall) {
1549 callStructure = 1677 callStructure =
1550 resolveArguments(node.argumentsNode).callStructure; 1678 resolveArguments(node.argumentsNode).callStructure;
1551 selector = new Selector(SelectorKind.CALL, name, callStructure); 1679 selector = new Selector(SelectorKind.CALL, name, callStructure);
1552 } else { 1680 } else {
1553 selector = new Selector(SelectorKind.GETTER, name, callStructure); 1681 selector = new Selector(SelectorKind.GETTER, name, callStructure);
1554 } 1682 }
1555 if (checkSuperAccess(node)) { 1683 AccessSemantics semantics = checkSuperAccess(node);
1556 AccessSemantics semantics = computeSuperAccessSemanticsForSelector( 1684 if (semantics == null) {
1685 semantics = computeSuperAccessSemanticsForSelector(
1557 node, selector, alternateName: name.setter); 1686 node, selector, alternateName: name.setter);
1558 if (node.isCall) { 1687 }
1559 bool isIncompatibleInvoke = false; 1688 if (node.isCall) {
1560 switch (semantics.kind) { 1689 bool isIncompatibleInvoke = false;
1561 case AccessKind.SUPER_METHOD: 1690 switch (semantics.kind) {
1562 MethodElementX superMethod = semantics.element; 1691 case AccessKind.SUPER_METHOD:
1563 superMethod.computeSignature(compiler); 1692 MethodElementX superMethod = semantics.element;
1564 if (!callStructure.signatureApplies( 1693 superMethod.computeSignature(compiler);
1565 superMethod.functionSignature)) { 1694 if (!callStructure.signatureApplies(
1566 registry.registerThrowNoSuchMethod(); 1695 superMethod.functionSignature)) {
1567 registry.registerDynamicInvocation( 1696 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( 1697 registry.registerDynamicInvocation(
1581 new UniverseSelector(selector, null)); 1698 new UniverseSelector(selector, null));
1582 break; 1699 registry.registerSuperNoSuchMethod();
1583 case AccessKind.SUPER_SETTER: 1700 isIncompatibleInvoke = true;
1584 case AccessKind.UNRESOLVED_SUPER: 1701 } else {
1585 // NoSuchMethod registered in [computeSuperSemantics]. 1702 registry.registerStaticInvocation(semantics.element);
1586 break; 1703 }
1587 default: 1704 break;
1588 internalError(node, "Unexpected super property access $semantics."); 1705 case AccessKind.SUPER_FIELD:
1589 break; 1706 case AccessKind.SUPER_FINAL_FIELD:
1590 } 1707 case AccessKind.SUPER_GETTER:
1591 registry.registerSendStructure(node, 1708 registry.registerStaticUse(semantics.element);
1592 isIncompatibleInvoke 1709 selector = callStructure.callSelector;
1593 ? new IncompatibleInvokeStructure(semantics, selector) 1710 registry.registerDynamicInvocation(
1594 : new InvokeStructure(semantics, selector)); 1711 new UniverseSelector(selector, null));
1595 } else { 1712 break;
1596 switch (semantics.kind) { 1713 case AccessKind.SUPER_SETTER:
1597 case AccessKind.SUPER_METHOD: 1714 case AccessKind.UNRESOLVED_SUPER:
1598 // TODO(johnniwinther): Method this should be registered as a 1715 // NoSuchMethod registered in [computeSuperSemantics].
1599 // closurization. 1716 break;
1600 registry.registerStaticUse(semantics.element); 1717 case AccessKind.INVALID:
1601 break; 1718 // 'super' is not allowed.
1602 case AccessKind.SUPER_FIELD: 1719 break;
1603 case AccessKind.SUPER_FINAL_FIELD: 1720 default:
1604 case AccessKind.SUPER_GETTER: 1721 internalError(node, "Unexpected super property access $semantics.");
1605 registry.registerStaticUse(semantics.element); 1722 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 } 1723 }
1618 target = semantics.element; 1724 registry.registerSendStructure(node,
1725 isIncompatibleInvoke
1726 ? new IncompatibleInvokeStructure(semantics, selector)
1727 : new InvokeStructure(semantics, selector));
1728 } else {
1729 switch (semantics.kind) {
1730 case AccessKind.SUPER_METHOD:
1731 // TODO(johnniwinther): Method this should be registered as a
1732 // closurization.
1733 registry.registerStaticUse(semantics.element);
1734 break;
1735 case AccessKind.SUPER_FIELD:
1736 case AccessKind.SUPER_FINAL_FIELD:
1737 case AccessKind.SUPER_GETTER:
1738 registry.registerStaticUse(semantics.element);
1739 break;
1740 case AccessKind.SUPER_SETTER:
1741 case AccessKind.UNRESOLVED_SUPER:
1742 // NoSuchMethod registered in [computeSuperSemantics].
1743 break;
1744 case AccessKind.INVALID:
1745 // 'super' is not allowed.
1746 break;
1747 default:
1748 internalError(node, "Unexpected super property access $semantics.");
1749 break;
1750 }
1751 registry.registerSendStructure(node,
1752 new GetStructure(semantics, selector));
1619 } 1753 }
1754 target = semantics.element;
1620 1755
1621 // TODO(johnniwinther): Remove these when all information goes through 1756 // TODO(johnniwinther): Remove these when all information goes through
1622 // the [SendStructure]. 1757 // the [SendStructure].
1623 registry.useElement(node, target); 1758 registry.useElement(node, target);
1624 registry.setSelector(node, selector); 1759 registry.setSelector(node, selector);
1625 return const NoneResult(); 1760 return const NoneResult();
1626 } 1761 }
1627 1762
1628 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`, 1763 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`,
1629 /// `a + b`, and `~a`. 1764 /// `a + b`, and `~a`.
(...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after
2614 new UniverseSelector(operatorSelector, null)); 2749 new UniverseSelector(operatorSelector, null));
2615 2750
2616 SendStructure sendStructure = new CompoundIndexSetStructure( 2751 SendStructure sendStructure = new CompoundIndexSetStructure(
2617 semantics, operator, getterSelector, setterSelector); 2752 semantics, operator, getterSelector, setterSelector);
2618 registry.registerSendStructure(node, sendStructure); 2753 registry.registerSendStructure(node, sendStructure);
2619 return const NoneResult(); 2754 return const NoneResult();
2620 } 2755 }
2621 } 2756 }
2622 } 2757 }
2623 2758
2759 /// Handle super index operations like `super[a] = b`, `super[a] += b`, and
2760 /// `super[a]++`.
2761 // TODO(johnniwinther): Share code with [handleIndexSendSet].
2762 ResolutionResult handleSuperIndexSendSet(SendSet node) {
2763 String operatorText = node.assignmentOperator.source;
2764 Node index = node.arguments.head;
2765 visitExpression(index);
2766 AccessSemantics semantics = checkSuperAccess(node);
2767 if (node.isPrefix || node.isPostfix) {
2768 // `super[a]++` or `++super[a]`.
2769 IncDecOperator operator = IncDecOperator.parse(operatorText);
2770 Selector getterSelector = new Selector.index();
2771 Selector setterSelector = new Selector.indexSet();
2772 Selector operatorSelector =
2773 new Selector.binaryOperator(operator.selectorName);
2774
2775 // TODO(johnniwinther): Remove these when selectors are only accessed
2776 // through the send structure.
2777 registry.setGetterSelectorInComplexSendSet(node, getterSelector);
2778 registry.setSelector(node, setterSelector);
2779 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
2780
2781 if (semantics == null) {
2782 semantics = computeSuperAccessSemanticsForSelectors(
2783 node, getterSelector, setterSelector);
2784
2785 registry.registerStaticInvocation(semantics.getter);
2786 registry.registerStaticInvocation(semantics.setter);
2787
2788 // TODO(johnniwinther): Remove these when elements are only accessed
2789 // through the send structure.
2790 registry.useElement(node, semantics.setter);
2791 registry.useElement(node.selector, semantics.getter);
2792 }
2793 registry.registerDynamicInvocation(
2794 new UniverseSelector(operatorSelector, null));
2795
2796 SendStructure sendStructure = node.isPrefix
2797 ? new IndexPrefixStructure(
2798 semantics, operator, getterSelector, setterSelector)
2799 : new IndexPostfixStructure(
2800 semantics, operator, getterSelector, setterSelector);
2801 registry.registerSendStructure(node, sendStructure);
2802 return const NoneResult();
2803 } else {
2804 Node rhs = node.arguments.tail.head;
2805 visitExpression(rhs);
2806
2807 AssignmentOperator operator = AssignmentOperator.parse(operatorText);
2808 if (operator.kind == AssignmentOperatorKind.ASSIGN) {
2809 // `super[a] = b`.
2810 Selector setterSelector = new Selector.indexSet();
2811 if (semantics == null) {
2812 semantics =
2813 computeSuperAccessSemanticsForSelector(node, setterSelector);
2814
2815 // TODO(johnniwinther): Remove these when elements are only accessed
2816 // through the send structure.
2817 registry.useElement(node, semantics.setter);
2818 }
2819
2820 // TODO(johnniwinther): Remove this when selectors are only accessed
2821 // through the send structure.
2822 registry.setSelector(node, setterSelector);
2823 registry.registerStaticInvocation(semantics.setter);
2824
2825 SendStructure sendStructure =
2826 new IndexSetStructure(semantics, setterSelector);
2827 registry.registerSendStructure(node, sendStructure);
2828 return const NoneResult();
2829 } else {
2830 // `super[a] += b`.
2831 Selector getterSelector = new Selector.index();
2832 Selector setterSelector = new Selector.indexSet();
2833 Selector operatorSelector =
2834 new Selector.binaryOperator(operator.selectorName);
2835 if (semantics == null) {
2836 semantics = computeSuperAccessSemanticsForSelectors(
2837 node, getterSelector, setterSelector);
2838
2839 registry.registerStaticInvocation(semantics.getter);
2840 registry.registerStaticInvocation(semantics.setter);
2841
2842 // TODO(johnniwinther): Remove these when elements are only accessed
2843 // through the send structure.
2844 registry.useElement(node, semantics.setter);
2845 registry.useElement(node.selector, semantics.getter);
2846 }
2847
2848 // TODO(johnniwinther): Remove these when selectors are only accessed
2849 // through the send structure.
2850 registry.setGetterSelectorInComplexSendSet(node, getterSelector);
2851 registry.setSelector(node, setterSelector);
2852 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
2853
2854 registry.registerDynamicInvocation(
2855 new UniverseSelector(operatorSelector, null));
2856
2857 SendStructure sendStructure = new CompoundIndexSetStructure(
2858 semantics, operator, getterSelector, setterSelector);
2859 registry.registerSendStructure(node, sendStructure);
2860 return const NoneResult();
2861 }
2862 }
2863 }
2864
2624 ResolutionResult visitSendSet(SendSet node) { 2865 ResolutionResult visitSendSet(SendSet node) {
2625 if (node.isIndex) { 2866 if (node.isIndex) {
2626 if (node.isSuperCall) { 2867 if (node.isSuperCall) {
2627 // TODO(johnniwinther): Refactor index operations on super. 2868 return handleSuperIndexSendSet(node);
2628 } else { 2869 } else {
2629 return handleIndexSendSet(node); 2870 return handleIndexSendSet(node);
2630 } 2871 }
2631 } 2872 }
2632 return oldVisitSendSet(node); 2873 return oldVisitSendSet(node);
2633 } 2874 }
2634 2875
2635 ResolutionResult oldVisitSendSet(SendSet node) { 2876 ResolutionResult oldVisitSendSet(SendSet node) {
2636 bool oldSendIsMemberAccess = sendIsMemberAccess; 2877 bool oldSendIsMemberAccess = sendIsMemberAccess;
2637 sendIsMemberAccess = node.isPropertyAccess || node.isCall; 2878 sendIsMemberAccess = node.isPropertyAccess || node.isCall;
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after
3917 } 4158 }
3918 return const NoneResult(); 4159 return const NoneResult();
3919 } 4160 }
3920 } 4161 }
3921 4162
3922 /// Looks up [name] in [scope] and unwraps the result. 4163 /// Looks up [name] in [scope] and unwraps the result.
3923 Element lookupInScope(Compiler compiler, Node node, 4164 Element lookupInScope(Compiler compiler, Node node,
3924 Scope scope, String name) { 4165 Scope scope, String name) {
3925 return Elements.unwrap(scope.lookup(name), compiler, node); 4166 return Elements.unwrap(scope.lookup(name), compiler, node);
3926 } 4167 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698