Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |