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

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

Issue 1160313006: Revert "Refactoring resolution of local access and unqualified access of statics" (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of resolution; 5 part of resolution;
6 6
7 /** 7 /**
8 * Core implementation of resolution. 8 * Core implementation of resolution.
9 * 9 *
10 * Do not subclass or instantiate this class outside this library 10 * Do not subclass or instantiate this class outside this library
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 /// Check that access to `this` is currently allowed. 797 /// Check that access to `this` is currently allowed.
798 bool checkThisAccess(Send node) { 798 bool checkThisAccess(Send node) {
799 if (!inInstanceContext) { 799 if (!inInstanceContext) {
800 compiler.reportError(node, MessageKind.NO_THIS_AVAILABLE); 800 compiler.reportError(node, MessageKind.NO_THIS_AVAILABLE);
801 return false; 801 return false;
802 } 802 }
803 return true; 803 return true;
804 } 804 }
805 805
806 /// Compute the [AccessSemantics] corresponding to a super access of [target]. 806 /// Compute the [AccessSemantics] corresponding to a super access of [target].
807 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) { 807 AccessSemantics computeSuperAccess(Spannable node, Element target) {
808 if (target.isErroneous) { 808 if (target.isErroneous) {
809 return new StaticAccess.unresolvedSuper(target); 809 return new StaticAccess.unresolvedSuper(target);
810 } else if (target.isGetter) { 810 } else if (target.isGetter) {
811 return new StaticAccess.superGetter(target); 811 return new StaticAccess.superGetter(target);
812 } else if (target.isSetter) { 812 } else if (target.isSetter) {
813 return new StaticAccess.superSetter(target); 813 return new StaticAccess.superSetter(target);
814 } else if (target.isField) { 814 } else if (target.isField) {
815 if (target.isFinal) { 815 return new StaticAccess.superField(target);
816 return new StaticAccess.superFinalField(target);
817 } else {
818 return new StaticAccess.superField(target);
819 }
820 } else { 816 } else {
821 assert(invariant(node, target.isFunction, 817 assert(invariant(node, target.isFunction,
822 message: "Unexpected super target '$target'.")); 818 message: "Unexpected super target '$target'."));
823 return new StaticAccess.superMethod(target); 819 return new StaticAccess.superMethod(target);
824 } 820 }
825 } 821 }
826 822
827 /// Compute the [AccessSemantics] corresponding to a local access of [target].
828 AccessSemantics computeLocalAccessSemantics(Spannable node,
829 LocalElement target) {
830 if (target.isParameter) {
831 if (target.isFinal || target.isConst) {
832 return new StaticAccess.finalParameter(target);
833 } else {
834 return new StaticAccess.parameter(target);
835 }
836 } else if (target.isVariable) {
837 if (target.isFinal || target.isConst) {
838 return new StaticAccess.finalLocalVariable(target);
839 } else {
840 return new StaticAccess.localVariable(target);
841 }
842 } else {
843 assert(invariant(node, target.isFunction,
844 message: "Unexpected local target '$target'."));
845 return new StaticAccess.localFunction(target);
846 }
847 }
848
849 /// Compute the [AccessSemantics] corresponding to a static or toplevel access
850 /// of [target].
851 AccessSemantics computeStaticOrTopLevelAccessSemantics(
852 Spannable node,
853 Element target) {
854
855 target = target.declaration;
856 if (target.isErroneous) {
857 // This handles elements with parser errors.
858 // TODO(johnniwinther): Elements with parse error should not set
859 // [isErroneous] to `true`.
860 return new StaticAccess.unresolved(target);
861 }
862 if (target.isStatic) {
863 if (target.isGetter) {
864 return new StaticAccess.staticGetter(target);
865 } else if (target.isSetter) {
866 return new StaticAccess.staticSetter(target);
867 } else if (target.isField) {
868 if (target.isFinal || target.isConst) {
869 return new StaticAccess.finalStaticField(target);
870 } else {
871 return new StaticAccess.staticField(target);
872 }
873 } else {
874 assert(invariant(node, target.isFunction,
875 message: "Unexpected static target '$target'."));
876 return new StaticAccess.staticMethod(target);
877 }
878 } else {
879 assert(invariant(node, target.isTopLevel,
880 message: "Unexpected statically resolved target '$target'."));
881 if (target.isGetter) {
882 return new StaticAccess.topLevelGetter(target);
883 } else if (target.isSetter) {
884 return new StaticAccess.topLevelSetter(target);
885 } else if (target.isField) {
886 if (target.isFinal) {
887 return new StaticAccess.finalTopLevelField(target);
888 } else {
889 return new StaticAccess.topLevelField(target);
890 }
891 } else {
892 assert(invariant(node, target.isFunction,
893 message: "Unexpected top level target '$target'."));
894 return new StaticAccess.topLevelMethod(target);
895 }
896 }
897 }
898
899 /// Compute the [AccessSemantics] for accessing the name of [selector] on the 823 /// Compute the [AccessSemantics] for accessing the name of [selector] on the
900 /// super class. 824 /// super class.
901 /// 825 ///
902 /// If no matching super member is found and error is reported and 826 /// If no matching super member is found and error is reported and
903 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName] 827 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName]
904 /// is provided, the [AccessSemantics] corresponding to the alternate name is 828 /// is provided, the [AccessSemantics] corresponding to the alternate name is
905 /// returned. For instance, the access of a super setter for an unresolved 829 /// returned. For instance, the access of a super setter for an unresolved
906 /// getter: 830 /// getter:
907 /// 831 ///
908 /// class Super { 832 /// class Super {
909 /// set name(_) {} 833 /// set name(_) {}
910 /// } 834 /// }
911 /// class Sub extends Super { 835 /// class Sub extends Super {
912 /// foo => super.name; // Access to the setter. 836 /// foo => super.name; // Access to the setter.
913 /// } 837 /// }
914 /// 838 ///
915 AccessSemantics computeSuperAccessSemanticsForSelector( 839 AccessSemantics computeSuperSemantics(Spannable node,
916 Spannable node, 840 Selector selector,
917 Selector selector, 841 {Name alternateName}) {
918 {Name alternateName}) {
919
920 Name name = selector.memberName; 842 Name name = selector.memberName;
921 // TODO(johnniwinther): Ensure correct behavior if currentClass is a 843 // TODO(johnniwinther): Ensure correct behavior if currentClass is a
922 // patch. 844 // patch.
923 Element target = currentClass.lookupSuperByName(name); 845 Element target = currentClass.lookupSuperByName(name);
924 // [target] may be null which means invoking noSuchMethod on super. 846 // [target] may be null which means invoking noSuchMethod on super.
925 if (target == null) { 847 if (target == null) {
926 Element error = reportAndCreateErroneousElement( 848 Element error = reportAndCreateErroneousElement(
927 node, name.text, MessageKind.NO_SUCH_SUPER_MEMBER, 849 node, name.text, MessageKind.NO_SUCH_SUPER_MEMBER,
928 {'className': currentClass.name, 'memberName': name}); 850 {'className': currentClass.name, 'memberName': name});
929 if (alternateName != null) { 851 if (alternateName != null) {
930 target = currentClass.lookupSuperByName(alternateName); 852 target = currentClass.lookupSuperByName(alternateName);
931 } 853 }
932 if (target == null) { 854 if (target == null) {
933 // If a setter wasn't resolved, use the [ErroneousElement]. 855 // If a setter wasn't resolved, use the [ErroneousElement].
934 target = error; 856 target = error;
935 } 857 }
936 // We still need to register the invocation, because we might 858 // We still need to register the invocation, because we might
937 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. 859 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn].
938 registry.registerDynamicInvocation(selector); 860 registry.registerDynamicInvocation(selector);
939 registry.registerSuperNoSuchMethod(); 861 registry.registerSuperNoSuchMethod();
940 } 862 }
941 return computeSuperAccessSemantics(node, target); 863 return computeSuperAccess(node, target);
942 } 864 }
943 865
944 /// Resolve [node] as subexpression that is _not_ the prefix of a member 866 /// Resolve [node] as subexpression that is _not_ the prefix of a member
945 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`. 867 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`.
946 ResolutionResult visitExpression(Node node) { 868 ResolutionResult visitExpression(Node node) {
947 bool oldSendIsMemberAccess = sendIsMemberAccess; 869 bool oldSendIsMemberAccess = sendIsMemberAccess;
948 sendIsMemberAccess = false; 870 sendIsMemberAccess = false;
949 ResolutionResult result = visit(node); 871 ResolutionResult result = visit(node);
950 sendIsMemberAccess = oldSendIsMemberAccess; 872 sendIsMemberAccess = oldSendIsMemberAccess;
951 return result; 873 return result;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) { 931 ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) {
1010 Node expression = node.receiver; 932 Node expression = node.receiver;
1011 Selector selector = operator.selector; 933 Selector selector = operator.selector;
1012 // TODO(johnniwinther): Remove this when all information goes through the 934 // TODO(johnniwinther): Remove this when all information goes through the
1013 // [SendStructure]. 935 // [SendStructure].
1014 registry.setSelector(node, selector); 936 registry.setSelector(node, selector);
1015 937
1016 AccessSemantics semantics; 938 AccessSemantics semantics;
1017 if (node.isSuperCall) { 939 if (node.isSuperCall) {
1018 if (checkSuperAccess(node)) { 940 if (checkSuperAccess(node)) {
1019 semantics = computeSuperAccessSemanticsForSelector(node, selector); 941 semantics = computeSuperSemantics(node, selector);
1020 // TODO(johnniwinther): Add information to [AccessSemantics] about 942 // TODO(johnniwinther): Add information to [AccessSemantics] about
1021 // whether it is erroneous. 943 // whether it is erroneous.
1022 if (semantics.kind == AccessKind.SUPER_METHOD) { 944 if (semantics.kind == AccessKind.SUPER_METHOD) {
1023 registry.registerStaticUse(semantics.element.declaration); 945 registry.registerStaticUse(semantics.element.declaration);
1024 } 946 }
1025 // TODO(johnniwinther): Remove this when all information goes through 947 // TODO(johnniwinther): Remove this when all information goes through
1026 // the [SendStructure]. 948 // the [SendStructure].
1027 registry.useElement(node, semantics.element); 949 registry.useElement(node, semantics.element);
1028 } 950 }
1029 } else { 951 } else {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 selector = new Selector.index(); 1030 selector = new Selector.index();
1109 } else { 1031 } else {
1110 selector = new Selector.binaryOperator(operator.selectorName); 1032 selector = new Selector.binaryOperator(operator.selectorName);
1111 } 1033 }
1112 // TODO(johnniwinther): Remove this when all information goes through the 1034 // TODO(johnniwinther): Remove this when all information goes through the
1113 // [SendStructure]. 1035 // [SendStructure].
1114 registry.setSelector(node, selector); 1036 registry.setSelector(node, selector);
1115 1037
1116 if (node.isSuperCall) { 1038 if (node.isSuperCall) {
1117 if (checkSuperAccess(node)) { 1039 if (checkSuperAccess(node)) {
1118 semantics = computeSuperAccessSemanticsForSelector(node, selector); 1040 semantics = computeSuperSemantics(node, selector);
1119 // TODO(johnniwinther): Add information to [AccessSemantics] about 1041 // TODO(johnniwinther): Add information to [AccessSemantics] about
1120 // whether it is erroneous. 1042 // whether it is erroneous.
1121 if (semantics.kind == AccessKind.SUPER_METHOD) { 1043 if (semantics.kind == AccessKind.SUPER_METHOD) {
1122 registry.registerStaticUse(semantics.element.declaration); 1044 registry.registerStaticUse(semantics.element.declaration);
1123 } 1045 }
1124 // TODO(johnniwinther): Remove this when all information goes through 1046 // TODO(johnniwinther): Remove this when all information goes through
1125 // the [SendStructure]. 1047 // the [SendStructure].
1126 registry.useElement(node, semantics.element); 1048 registry.useElement(node, semantics.element);
1127 } 1049 }
1128 } else { 1050 } else {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 Element target; 1194 Element target;
1273 Selector selector; 1195 Selector selector;
1274 CallStructure callStructure = CallStructure.NO_ARGS; 1196 CallStructure callStructure = CallStructure.NO_ARGS;
1275 if (node.isCall) { 1197 if (node.isCall) {
1276 callStructure = resolveArguments(node.argumentsNode); 1198 callStructure = resolveArguments(node.argumentsNode);
1277 selector = new Selector(SelectorKind.CALL, name, callStructure); 1199 selector = new Selector(SelectorKind.CALL, name, callStructure);
1278 } else { 1200 } else {
1279 selector = new Selector(SelectorKind.GETTER, name, callStructure); 1201 selector = new Selector(SelectorKind.GETTER, name, callStructure);
1280 } 1202 }
1281 if (checkSuperAccess(node)) { 1203 if (checkSuperAccess(node)) {
1282 AccessSemantics semantics = computeSuperAccessSemanticsForSelector( 1204 AccessSemantics semantics = computeSuperSemantics(
1283 node, selector, alternateName: name.setter); 1205 node, selector, alternateName: name.setter);
1284 if (node.isCall) { 1206 if (node.isCall) {
1285 bool isIncompatibleInvoke = false; 1207 bool isIncompatibleInvoke = false;
1286 switch (semantics.kind) { 1208 switch (semantics.kind) {
1287 case AccessKind.SUPER_METHOD: 1209 case AccessKind.SUPER_METHOD:
1288 MethodElementX superMethod = semantics.element; 1210 MethodElementX superMethod = semantics.element;
1289 superMethod.computeSignature(compiler); 1211 superMethod.computeSignature(compiler);
1290 if (!callStructure.signatureApplies(superMethod)) { 1212 if (!callStructure.signatureApplies(superMethod)) {
1291 registry.registerThrowNoSuchMethod(); 1213 registry.registerThrowNoSuchMethod();
1292 registry.registerDynamicInvocation(selector); 1214 registry.registerDynamicInvocation(selector);
1293 registry.registerSuperNoSuchMethod(); 1215 registry.registerSuperNoSuchMethod();
1294 isIncompatibleInvoke = true; 1216 isIncompatibleInvoke = true;
1295 } else { 1217 } else {
1296 registry.registerStaticInvocation(semantics.element); 1218 registry.registerStaticInvocation(semantics.element);
1297 } 1219 }
1298 break; 1220 break;
1299 case AccessKind.SUPER_FIELD: 1221 case AccessKind.SUPER_FIELD:
1300 case AccessKind.SUPER_FINAL_FIELD:
1301 case AccessKind.SUPER_GETTER: 1222 case AccessKind.SUPER_GETTER:
1302 registry.registerStaticUse(semantics.element); 1223 registry.registerStaticUse(semantics.element);
1303 selector = callStructure.callSelector; 1224 selector = callStructure.callSelector;
1304 registry.registerDynamicInvocation(selector); 1225 registry.registerDynamicInvocation(selector);
1305 break; 1226 break;
1306 case AccessKind.SUPER_SETTER: 1227 case AccessKind.SUPER_SETTER:
1307 case AccessKind.UNRESOLVED_SUPER: 1228 case AccessKind.UNRESOLVED_SUPER:
1308 // NoSuchMethod registered in [computeSuperSemantics]. 1229 // NoSuchMethod registered in [computeSuperSemantics].
1309 break; 1230 break;
1310 default: 1231 default:
1311 internalError(node, "Unexpected super property access $semantics."); 1232 internalError(node, "Unexpected super property access $semantics.");
1312 break; 1233 break;
1313 } 1234 }
1314 registry.registerSendStructure(node, 1235 registry.registerSendStructure(node,
1315 isIncompatibleInvoke 1236 isIncompatibleInvoke
1316 ? new IncompatibleInvokeStructure(semantics, selector) 1237 ? new IncompatibleInvokeStructure(semantics, selector)
1317 : new InvokeStructure(semantics, selector)); 1238 : new InvokeStructure(semantics, selector));
1318 } else { 1239 } else {
1319 switch (semantics.kind) { 1240 switch (semantics.kind) {
1320 case AccessKind.SUPER_METHOD: 1241 case AccessKind.SUPER_METHOD:
1321 // TODO(johnniwinther): Method this should be registered as a 1242 // TODO(johnniwinther): Method this should be registered as a
1322 // closurization. 1243 // closurization.
1323 registry.registerStaticUse(semantics.element); 1244 registry.registerStaticUse(semantics.element);
1324 break; 1245 break;
1325 case AccessKind.SUPER_FIELD: 1246 case AccessKind.SUPER_FIELD:
1326 case AccessKind.SUPER_FINAL_FIELD:
1327 case AccessKind.SUPER_GETTER: 1247 case AccessKind.SUPER_GETTER:
1328 registry.registerStaticUse(semantics.element); 1248 registry.registerStaticUse(semantics.element);
1329 break; 1249 break;
1330 case AccessKind.SUPER_SETTER: 1250 case AccessKind.SUPER_SETTER:
1331 case AccessKind.UNRESOLVED_SUPER: 1251 case AccessKind.UNRESOLVED_SUPER:
1332 // NoSuchMethod registered in [computeSuperSemantics]. 1252 // NoSuchMethod registered in [computeSuperSemantics].
1333 break; 1253 break;
1334 default: 1254 default:
1335 internalError(node, "Unexpected super property access $semantics."); 1255 internalError(node, "Unexpected super property access $semantics.");
1336 break; 1256 break;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 // TODO(johnniwinther): Handle remaining qualified sends. 1346 // TODO(johnniwinther): Handle remaining qualified sends.
1427 return oldVisitSend(node); 1347 return oldVisitSend(node);
1428 } 1348 }
1429 1349
1430 /// Handle access unresolved access to [name] in a non-instance context. 1350 /// Handle access unresolved access to [name] in a non-instance context.
1431 ResolutionResult handleUnresolvedAccess( 1351 ResolutionResult handleUnresolvedAccess(
1432 Send node, Name name, Element element) { 1352 Send node, Name name, Element element) {
1433 // TODO(johnniwinther): Support unresolved top level access as an 1353 // TODO(johnniwinther): Support unresolved top level access as an
1434 // [AccessSemantics]. 1354 // [AccessSemantics].
1435 AccessSemantics accessSemantics = new StaticAccess.unresolved(element); 1355 AccessSemantics accessSemantics = new StaticAccess.unresolved(element);
1436 return handleErroneousAccess(node, name, element, accessSemantics);
1437 }
1438
1439 /// Handle erroneous access of [element] of the given [accessSemantics].
1440 ResolutionResult handleErroneousAccess(
1441 Send node, Name name, Element element, AccessSemantics accessSemantics) {
1442 SendStructure sendStructure; 1356 SendStructure sendStructure;
1443 Selector selector; 1357 Selector selector;
1444 if (node.isCall) { 1358 if (node.isCall) {
1445 CallStructure callStructure = resolveArguments(node.argumentsNode); 1359 CallStructure callStructure = resolveArguments(node.argumentsNode);
1446 selector = new Selector(SelectorKind.CALL, name, callStructure); 1360 selector = new Selector(SelectorKind.CALL, name, callStructure);
1447 registry.registerDynamicInvocation(selector); 1361 registry.registerDynamicInvocation(selector);
1448 sendStructure = new InvokeStructure(accessSemantics, selector); 1362 sendStructure = new InvokeStructure(accessSemantics, selector);
1449 } else { 1363 } else {
1450 assert(invariant(node, node.isPropertyAccess)); 1364 assert(invariant(node, node.isPropertyAccess));
1451 selector = new Selector( 1365 selector = new Selector(
1452 SelectorKind.GETTER, name, CallStructure.NO_ARGS); 1366 SelectorKind.GETTER, name, CallStructure.NO_ARGS);
1453 registry.registerDynamicGetter(selector); 1367 registry.registerDynamicGetter(selector);
1454 sendStructure = new GetStructure(accessSemantics, selector); 1368 sendStructure = new GetStructure(accessSemantics, selector);
1455 } 1369 }
1456 // TODO(johnniwinther): Remove this when all information goes through 1370 // TODO(johnniwinther): Remove this when all information goes through
1457 // the [SendStructure]. 1371 // the [SendStructure].
1458 registry.setSelector(node, selector); 1372 registry.setSelector(node, selector);
1459 registry.useElement(node, element); 1373 registry.useElement(node, element);
1460 registry.registerSendStructure(node, sendStructure); 1374 registry.registerSendStructure(node, sendStructure);
1461 return null; 1375 return null;
1462 } 1376 }
1463 1377
1464 /// Handle access to an ambiguous element, that is, a name imported twice.
1465 ResolutionResult handleAmbiguousSend(
1466 Send node,
1467 Name name,
1468 AmbiguousElement element) {
1469
1470 compiler.reportError(
1471 node, element.messageKind, element.messageArguments);
1472 element.diagnose(enclosingElement, compiler);
1473
1474 ErroneousElement error = new ErroneousElementX(
1475 element.messageKind,
1476 element.messageArguments,
1477 name.text,
1478 enclosingElement);
1479
1480 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics].
1481 AccessSemantics accessSemantics = new StaticAccess.unresolved(error);
1482 return handleErroneousAccess(node, name, error, accessSemantics);
1483 }
1484
1485 /// Handle access of an instance [member] from a non-instance context.
1486 ResolutionResult handleStaticInstanceSend(
1487 Send node, Name name, MemberElement member) {
1488 compiler.reportError(
1489 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': member.name});
1490 ErroneousElement error = new ErroneousElementX(
1491 MessageKind.NO_INSTANCE_AVAILABLE,
1492 {'name': name},
1493 name.text,
1494 enclosingElement);
1495
1496 // TODO(johnniwinther): Support static instance access as an
1497 // [AccessSemantics].
1498 AccessSemantics accessSemantics = new StaticAccess.unresolved(error);
1499 return handleErroneousAccess(node, name, error, accessSemantics);
1500 }
1501
1502 /// Handle access of a parameter, local variable or local function.
1503 ResolutionResult handleLocalAccess(Send node, Name name, Element element) {
1504 AccessSemantics semantics = computeLocalAccessSemantics(node, element);
1505 Selector selector;
1506 CallStructure callStructure = CallStructure.NO_ARGS;
1507 if (node.isCall) {
1508 callStructure = resolveArguments(node.argumentsNode);
1509 selector = new Selector(SelectorKind.CALL, name, callStructure);
1510 } else {
1511 selector = new Selector(SelectorKind.GETTER, name, callStructure);
1512 }
1513 if (node.isCall) {
1514 bool isIncompatibleInvoke = false;
1515 switch (semantics.kind) {
1516 case AccessKind.LOCAL_FUNCTION:
1517 LocalFunctionElementX function = semantics.element;
1518 function.computeSignature(compiler);
1519 if (!callStructure.signatureApplies(function)) {
1520 registry.registerThrowNoSuchMethod();
1521 registry.registerDynamicInvocation(selector);
1522 isIncompatibleInvoke = true;
1523 }
1524 break;
1525 case AccessKind.PARAMETER:
1526 case AccessKind.FINAL_PARAMETER:
1527 case AccessKind.LOCAL_VARIABLE:
1528 case AccessKind.FINAL_LOCAL_VARIABLE:
1529 selector = callStructure.callSelector;
1530 registry.registerDynamicInvocation(selector);
1531 break;
1532 default:
1533 internalError(node,
1534 "Unexpected local access $semantics.");
1535 break;
1536 }
1537 registry.registerSendStructure(node,
1538 isIncompatibleInvoke
1539 ? new IncompatibleInvokeStructure(semantics, selector)
1540 : new InvokeStructure(semantics, selector));
1541 } else {
1542 registry.registerSendStructure(node,
1543 new GetStructure(semantics, selector));
1544 }
1545
1546 // TODO(johnniwinther): Remove these when all information goes through
1547 // the [SendStructure].
1548 registry.useElement(node, element);
1549 registry.setSelector(node, selector);
1550
1551 registerPotentialAccessInClosure(node, element);
1552
1553 return node.isPropertyAccess ? new ElementResult(element) : null;
1554 }
1555
1556 /// Handle access of a static or top level [element].
1557 ResolutionResult handleStaticOrTopLevelAccess(
1558 Send node, Name name, Element element) {
1559
1560 if (element.isAbstractField) {
1561 AbstractFieldElement abstractField = element;
1562 if (abstractField.getter != null) {
1563 element = abstractField.getter;
1564 } else {
1565 element = abstractField.setter;
1566 }
1567 }
1568
1569 Selector selector;
1570 CallStructure callStructure = CallStructure.NO_ARGS;
1571 if (node.isCall) {
1572 callStructure = resolveArguments(node.argumentsNode);
1573 selector = new Selector(SelectorKind.CALL, name, callStructure);
1574 } else {
1575 selector = new Selector(SelectorKind.GETTER, name, callStructure);
1576 }
1577 AccessSemantics semantics =
1578 computeStaticOrTopLevelAccessSemantics(node, element);
1579 if (node.isCall) {
1580 bool isIncompatibleInvoke = false;
1581 switch (semantics.kind) {
1582 case AccessKind.STATIC_METHOD:
1583 case AccessKind.TOPLEVEL_METHOD:
1584 MethodElementX method = semantics.element;
1585 method.computeSignature(compiler);
1586 if (!callStructure.signatureApplies(method)) {
1587 registry.registerThrowNoSuchMethod();
1588 registry.registerDynamicInvocation(selector);
1589 isIncompatibleInvoke = true;
1590 } else {
1591 registry.registerStaticUse(semantics.element);
1592 handleForeignCall(node, semantics.element, selector);
1593 }
1594 break;
1595 case AccessKind.STATIC_FIELD:
1596 case AccessKind.FINAL_STATIC_FIELD:
1597 case AccessKind.STATIC_GETTER:
1598 case AccessKind.TOPLEVEL_FIELD:
1599 case AccessKind.FINAL_TOPLEVEL_FIELD:
1600 case AccessKind.TOPLEVEL_GETTER:
1601 registry.registerStaticUse(semantics.element);
1602 selector = callStructure.callSelector;
1603 registry.registerDynamicInvocation(selector);
1604 break;
1605 case AccessKind.STATIC_SETTER:
1606 case AccessKind.TOPLEVEL_SETTER:
1607 case AccessKind.UNRESOLVED:
1608 registry.registerThrowNoSuchMethod();
1609 element = reportAndCreateErroneousElement(
1610 node.selector, name.text,
1611 MessageKind.CANNOT_RESOLVE_GETTER, const {});
1612 break;
1613 default:
1614 internalError(node,
1615 "Unexpected statically resolved access $semantics.");
1616 break;
1617 }
1618 registry.registerSendStructure(node,
1619 isIncompatibleInvoke
1620 ? new IncompatibleInvokeStructure(semantics, selector)
1621 : new InvokeStructure(semantics, selector));
1622 } else {
1623 switch (semantics.kind) {
1624 case AccessKind.STATIC_METHOD:
1625 case AccessKind.TOPLEVEL_METHOD:
1626 // TODO(johnniwinther): Method this should be registered as a
1627 // closurization.
1628 registry.registerStaticUse(semantics.element);
1629 registry.registerGetOfStaticFunction(semantics.element);
1630 break;
1631 case AccessKind.STATIC_FIELD:
1632 case AccessKind.FINAL_STATIC_FIELD:
1633 case AccessKind.STATIC_GETTER:
1634 case AccessKind.TOPLEVEL_FIELD:
1635 case AccessKind.FINAL_TOPLEVEL_FIELD:
1636 case AccessKind.TOPLEVEL_GETTER:
1637 registry.registerStaticUse(semantics.element);
1638 break;
1639 case AccessKind.STATIC_SETTER:
1640 case AccessKind.TOPLEVEL_SETTER:
1641 case AccessKind.UNRESOLVED:
1642 registry.registerThrowNoSuchMethod();
1643 element = reportAndCreateErroneousElement(
1644 node.selector, name.text,
1645 MessageKind.CANNOT_RESOLVE_GETTER, const {});
1646 break;
1647 default:
1648 internalError(node,
1649 "Unexpected statically resolved access $semantics.");
1650 break;
1651 }
1652 registry.registerSendStructure(node,
1653 new GetStructure(semantics, selector));
1654 }
1655
1656 // TODO(johnniwinther): Remove these when all information goes through
1657 // the [SendStructure].
1658 registry.useElement(node, element);
1659 registry.setSelector(node, selector);
1660
1661 return node.isPropertyAccess ? new ElementResult(element) : null;
1662 }
1663
1664 /// Handle access to resolved [element].
1665 ResolutionResult handleResolvedSend(Send node, Name name, Element element) {
1666 if (element.isAmbiguous) {
1667 return handleAmbiguousSend(node, name, element);
1668 }
1669 if (element.isErroneous) {
1670 // This handles elements with parser errors.
1671 // TODO(johnniwinther): Elements with parse error should not set
1672 // [isErroneous] to `true`.
1673 assert(invariant(node, element is! ErroneousElement,
1674 message: "Unexpected erroneous element $element."));
1675 return handleErroneousAccess(node, name, element,
1676 new StaticAccess.unresolved(element));
1677 }
1678 if (element.isInstanceMember) {
1679 if (inInstanceContext) {
1680 // TODO(johnniwinther): Maybe use the found [element].
1681 return handleThisPropertyAccess(node, name);
1682 } else {
1683 return handleStaticInstanceSend(node, name, element);
1684 }
1685 }
1686 if (element.isClass || element.isTypedef) {
1687 return oldVisitSend(node);
1688 } else if (element.isTypeVariable) {
1689 return oldVisitSend(node);
1690 } else if (element.isPrefix) {
1691 return oldVisitSend(node);
1692 } else if (element.isLocal) {
1693 return handleLocalAccess(node, name, element);
1694 } else if (element.isStatic || element.isTopLevel) {
1695 return handleStaticOrTopLevelAccess(node, name, element);
1696 }
1697 return internalError(node, "Unexpected resolved send: $element");
1698 }
1699
1700 /// Handle an unqualified [Send], that is where the `node.receiver` is null, 1378 /// Handle an unqualified [Send], that is where the `node.receiver` is null,
1701 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. 1379 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`.
1702 ResolutionResult handleUnqualifiedSend(Send node) { 1380 ResolutionResult handleUnqualifiedSend(Send node) {
1703 Identifier selector = node.selector.asIdentifier(); 1381 Identifier selector = node.selector.asIdentifier();
1704 if (selector == null) { 1382 if (selector == null) {
1705 // `(){}()` and `(foo)()`. 1383 // `(){}()` and `(foo)()`.
1706 return handleExpressionInvoke(node); 1384 return handleExpressionInvoke(node);
1707 } 1385 }
1708 String text = selector.source; 1386 String text = selector.source;
1709 if (text == 'assert') { 1387 if (text == 'assert') {
(...skipping 12 matching lines...) Expand all
1722 Element element = lookupInScope(compiler, node, scope, text); 1400 Element element = lookupInScope(compiler, node, scope, text);
1723 if (element == null) { 1401 if (element == null) {
1724 if (inInstanceContext) { 1402 if (inInstanceContext) {
1725 // Implicitly `this.name`. 1403 // Implicitly `this.name`.
1726 return handleThisPropertyAccess(node, name); 1404 return handleThisPropertyAccess(node, name);
1727 } else { 1405 } else {
1728 // Create [ErroneousElement] for unresolved access. 1406 // Create [ErroneousElement] for unresolved access.
1729 ErroneousElement error = reportCannotResolve(node, text); 1407 ErroneousElement error = reportCannotResolve(node, text);
1730 return handleUnresolvedAccess(node, name, error); 1408 return handleUnresolvedAccess(node, name, error);
1731 } 1409 }
1732 } else {
1733 return handleResolvedSend(node, name, element);
1734 } 1410 }
1411 return oldVisitSend(node);
1735 } 1412 }
1736 1413
1737 ResolutionResult visitSend(Send node) { 1414 ResolutionResult visitSend(Send node) {
1738 if (node.isOperator) { 1415 if (node.isOperator) {
1739 // `a && b`, `a + b`, `-a`, or `a is T`.
1740 return handleOperatorSend(node); 1416 return handleOperatorSend(node);
1741 } else if (node.receiver != null) { 1417 } else if (node.receiver != null) {
1742 // `a.b`.
1743 return handleQualifiedSend(node); 1418 return handleQualifiedSend(node);
1744 } else { 1419 } else {
1745 // `a`.
1746 return handleUnqualifiedSend(node); 1420 return handleUnqualifiedSend(node);
1747 } 1421 }
1748 } 1422 return oldVisitSend(node);
1749
1750 /// Regigster read access of [target] inside a closure.
1751 void registerPotentialAccessInClosure(Send node, Element target) {
1752 if (isPotentiallyMutableTarget(target)) {
1753 if (enclosingElement != target.enclosingElement) {
1754 for (Node scope in promotionScope) {
1755 registry.setAccessedByClosureIn(scope, target, node);
1756 }
1757 }
1758 }
1759 } 1423 }
1760 1424
1761 ResolutionResult oldVisitSend(Send node) { 1425 ResolutionResult oldVisitSend(Send node) {
1762 bool oldSendIsMemberAccess = sendIsMemberAccess; 1426 bool oldSendIsMemberAccess = sendIsMemberAccess;
1763 sendIsMemberAccess = node.isPropertyAccess || node.isCall; 1427 sendIsMemberAccess = node.isPropertyAccess || node.isCall;
1764 1428
1765 ResolutionResult result = resolveSend(node); 1429 ResolutionResult result = resolveSend(node);
1766 sendIsMemberAccess = oldSendIsMemberAccess; 1430 sendIsMemberAccess = oldSendIsMemberAccess;
1767 1431
1768 Element target = result != null ? result.element : null; 1432 Element target = result != null ? result.element : null;
(...skipping 27 matching lines...) Expand all
1796 compiler.reportError(node, 1460 compiler.reportError(node,
1797 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, 1461 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
1798 {'typeVariableName': node.selector}); 1462 {'typeVariableName': node.selector});
1799 } 1463 }
1800 registry.registerClassUsingVariableExpression(cls); 1464 registry.registerClassUsingVariableExpression(cls);
1801 registry.registerTypeVariableExpression(); 1465 registry.registerTypeVariableExpression();
1802 registerTypeLiteralAccess(node, target); 1466 registerTypeLiteralAccess(node, target);
1803 } else if (target.impliesType && (!sendIsMemberAccess || node.isCall)) { 1467 } else if (target.impliesType && (!sendIsMemberAccess || node.isCall)) {
1804 registerTypeLiteralAccess(node, target); 1468 registerTypeLiteralAccess(node, target);
1805 } 1469 }
1806 registerPotentialAccessInClosure(node, target); 1470 if (isPotentiallyMutableTarget(target)) {
1471 if (enclosingElement != target.enclosingElement) {
1472 for (Node scope in promotionScope) {
1473 registry.setAccessedByClosureIn(scope, target, node);
1474 }
1475 }
1476 }
1807 } 1477 }
1808 1478
1809 bool resolvedArguments = false; 1479 bool resolvedArguments = false;
1810 resolveArguments(node.argumentsNode); 1480 resolveArguments(node.argumentsNode);
1811 1481
1812 // If the selector is null, it means that we will not be generating 1482 // If the selector is null, it means that we will not be generating
1813 // code for this as a send. 1483 // code for this as a send.
1814 Selector selector = registry.getSelector(node); 1484 Selector selector = registry.getSelector(node);
1815 if (selector == null) return null; 1485 if (selector == null) return null;
1816 1486
(...skipping 17 matching lines...) Expand all
1834 function.computeSignature(compiler); 1504 function.computeSignature(compiler);
1835 } 1505 }
1836 if (!selector.applies(target, compiler.world)) { 1506 if (!selector.applies(target, compiler.world)) {
1837 registry.registerThrowNoSuchMethod(); 1507 registry.registerThrowNoSuchMethod();
1838 if (node.isSuperCall) { 1508 if (node.isSuperCall) {
1839 internalError(node, "Unexpected super call $node"); 1509 internalError(node, "Unexpected super call $node");
1840 } 1510 }
1841 } 1511 }
1842 } 1512 }
1843 1513
1844 handleForeignCall(node, target, selector); 1514 if (target != null && compiler.backend.isForeign(target)) {
1515 if (selector.name == 'JS') {
1516 registry.registerJsCall(node, this);
1517 } else if (selector.name == 'JS_EMBEDDED_GLOBAL') {
1518 registry.registerJsEmbeddedGlobalCall(node, this);
1519 } else if (selector.name == 'JS_BUILTIN') {
1520 registry.registerJsBuiltinCall(node, this);
1521 } else if (selector.name == 'JS_INTERCEPTOR_CONSTANT') {
1522 if (!node.argumentsNode.isEmpty) {
1523 Node argument = node.argumentsNode.nodes.head;
1524 if (argumentsToJsInterceptorConstant == null) {
1525 argumentsToJsInterceptorConstant = new Set<Node>();
1526 }
1527 argumentsToJsInterceptorConstant.add(argument);
1528 }
1529 }
1530 }
1845 } 1531 }
1846 1532
1847 registry.useElement(node, target); 1533 registry.useElement(node, target);
1848 registerSend(selector, target); 1534 registerSend(selector, target);
1849 if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) { 1535 if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) {
1850 registry.registerGetOfStaticFunction(target.declaration); 1536 registry.registerGetOfStaticFunction(target.declaration);
1851 } 1537 }
1852 return node.isPropertyAccess ? new ElementResult(target) : null; 1538 return node.isPropertyAccess ? new ElementResult(target) : null;
1853 } 1539 }
1854 1540
1855 // TODO(johnniwinther): Move this to the backend resolution callbacks.
1856 void handleForeignCall(Send node, Element target, Selector selector) {
1857 if (target != null && compiler.backend.isForeign(target)) {
1858 if (selector.name == 'JS') {
1859 registry.registerJsCall(node, this);
1860 } else if (selector.name == 'JS_EMBEDDED_GLOBAL') {
1861 registry.registerJsEmbeddedGlobalCall(node, this);
1862 } else if (selector.name == 'JS_BUILTIN') {
1863 registry.registerJsBuiltinCall(node, this);
1864 } else if (selector.name == 'JS_INTERCEPTOR_CONSTANT') {
1865 if (!node.argumentsNode.isEmpty) {
1866 Node argument = node.argumentsNode.nodes.head;
1867 if (argumentsToJsInterceptorConstant == null) {
1868 argumentsToJsInterceptorConstant = new Set<Node>();
1869 }
1870 argumentsToJsInterceptorConstant.add(argument);
1871 }
1872 }
1873 }
1874 }
1875
1876 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. 1541 /// Callback for native enqueuer to parse a type. Returns [:null:] on error.
1877 DartType resolveTypeFromString(Node node, String typeName) { 1542 DartType resolveTypeFromString(Node node, String typeName) {
1878 Element element = lookupInScope(compiler, node, scope, typeName); 1543 Element element = lookupInScope(compiler, node, scope, typeName);
1879 if (element == null) return null; 1544 if (element == null) return null;
1880 if (element is! ClassElement) return null; 1545 if (element is! ClassElement) return null;
1881 ClassElement cls = element; 1546 ClassElement cls = element;
1882 cls.ensureResolved(compiler); 1547 cls.ensureResolved(compiler);
1883 return cls.computeType(compiler); 1548 return cls.computeType(compiler);
1884 } 1549 }
1885 1550
(...skipping 1091 matching lines...) Expand 10 before | Expand all | Expand 10 after
2977 visitTypedef(Typedef node) { 2642 visitTypedef(Typedef node) {
2978 internalError(node, 'typedef'); 2643 internalError(node, 'typedef');
2979 } 2644 }
2980 } 2645 }
2981 2646
2982 /// Looks up [name] in [scope] and unwraps the result. 2647 /// Looks up [name] in [scope] and unwraps the result.
2983 Element lookupInScope(Compiler compiler, Node node, 2648 Element lookupInScope(Compiler compiler, Node node,
2984 Scope scope, String name) { 2649 Scope scope, String name) {
2985 return Elements.unwrap(scope.lookup(name), compiler, node); 2650 return Elements.unwrap(scope.lookup(name), compiler, node);
2986 } 2651 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart ('k') | pkg/compiler/lib/src/resolution/resolution_common.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698