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

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

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

Powered by Google App Engine
This is Rietveld 408576698