| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library simple_types_inferrer; | 5 library simple_types_inferrer; |
| 6 | 6 |
| 7 import '../closure.dart' show ClosureRepresentationInfo; | 7 import '../closure.dart' show ClosureRepresentationInfo; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/names.dart' show Identifiers, Selectors; | 9 import '../common/names.dart' show Identifiers, Selectors; |
| 10 import '../compiler.dart' show Compiler; | 10 import '../compiler.dart' show Compiler; |
| (...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 | 1317 |
| 1318 if (Elements.isMalformed(element)) return types.dynamicType; | 1318 if (Elements.isMalformed(element)) return types.dynamicType; |
| 1319 | 1319 |
| 1320 if (Elements.isStaticOrTopLevelField(element)) { | 1320 if (Elements.isStaticOrTopLevelField(element)) { |
| 1321 Element getterElement = elements[node.selector]; | 1321 Element getterElement = elements[node.selector]; |
| 1322 getterType = handleStaticSend( | 1322 getterType = handleStaticSend( |
| 1323 node, getterSelector, getterMask, getterElement, null); | 1323 node, getterSelector, getterMask, getterElement, null); |
| 1324 } else if (Elements.isUnresolved(element) || | 1324 } else if (Elements.isUnresolved(element) || |
| 1325 element.isSetter || | 1325 element.isSetter || |
| 1326 element.isField) { | 1326 element.isField) { |
| 1327 getterType = handleDynamicSend( | 1327 getterType = handleDynamicSend(CallType.complex, node, getterSelector, |
| 1328 node, getterSelector, getterMask, receiverType, null); | 1328 getterMask, receiverType, null); |
| 1329 } else if (element.isLocal) { | 1329 } else if (element.isLocal) { |
| 1330 LocalElement local = element; | 1330 LocalElement local = element; |
| 1331 getterType = locals.use(local); | 1331 getterType = locals.use(local); |
| 1332 } else { | 1332 } else { |
| 1333 // Bogus SendSet, for example [: myMethod += 42 :]. | 1333 // Bogus SendSet, for example [: myMethod += 42 :]. |
| 1334 getterType = types.dynamicType; | 1334 getterType = types.dynamicType; |
| 1335 } | 1335 } |
| 1336 | 1336 |
| 1337 if (op == '??=') { | 1337 if (op == '??=') { |
| 1338 newType = types.allocateDiamondPhi(getterType, rhsType); | 1338 newType = types.allocateDiamondPhi(getterType, rhsType); |
| 1339 } else { | 1339 } else { |
| 1340 Selector operatorSelector = | 1340 Selector operatorSelector = |
| 1341 elements.getOperatorSelectorInComplexSendSet(node); | 1341 elements.getOperatorSelectorInComplexSendSet(node); |
| 1342 newType = handleDynamicSend(node, operatorSelector, operatorMask, | 1342 newType = handleDynamicSend(CallType.complex, node, operatorSelector, |
| 1343 getterType, new ArgumentsTypes([rhsType], null)); | 1343 operatorMask, getterType, new ArgumentsTypes([rhsType], null)); |
| 1344 } | 1344 } |
| 1345 | 1345 |
| 1346 if (Elements.isStaticOrTopLevelField(element)) { | 1346 if (Elements.isStaticOrTopLevelField(element)) { |
| 1347 handleStaticSend(node, setterSelector, setterMask, element, | 1347 handleStaticSend(node, setterSelector, setterMask, element, |
| 1348 new ArgumentsTypes([newType], null)); | 1348 new ArgumentsTypes([newType], null)); |
| 1349 } else if (Elements.isUnresolved(element) || | 1349 } else if (Elements.isUnresolved(element) || |
| 1350 element.isSetter || | 1350 element.isSetter || |
| 1351 element.isField) { | 1351 element.isField) { |
| 1352 handleDynamicSend(node, setterSelector, setterMask, receiverType, | 1352 handleDynamicSend(CallType.complex, node, setterSelector, setterMask, |
| 1353 new ArgumentsTypes([newType], null)); | 1353 receiverType, new ArgumentsTypes([newType], null)); |
| 1354 } else if (element.isLocal) { | 1354 } else if (element.isLocal) { |
| 1355 locals.update(element, newType, node); | 1355 locals.update(element, newType, node); |
| 1356 } | 1356 } |
| 1357 | 1357 |
| 1358 return node.isPostfix ? getterType : newType; | 1358 return node.isPostfix ? getterType : newType; |
| 1359 } | 1359 } |
| 1360 } | 1360 } |
| 1361 | 1361 |
| 1362 /// Handle compound index set, like `foo[0] += 42` or `foo[0]++`. | 1362 /// Handle compound index set, like `foo[0] += 42` or `foo[0]++`. |
| 1363 TypeInformation handleCompoundIndexSet( | 1363 TypeInformation handleCompoundIndexSet( |
| 1364 ast.SendSet node, | 1364 ast.SendSet node, |
| 1365 TypeInformation receiverType, | 1365 TypeInformation receiverType, |
| 1366 TypeInformation indexType, | 1366 TypeInformation indexType, |
| 1367 TypeInformation rhsType) { | 1367 TypeInformation rhsType) { |
| 1368 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); | 1368 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
| 1369 | 1369 |
| 1370 TypeMask getterMask = memberData.typeOfGetter(node); | 1370 TypeMask getterMask = memberData.typeOfGetter(node); |
| 1371 Selector operatorSelector = | 1371 Selector operatorSelector = |
| 1372 elements.getOperatorSelectorInComplexSendSet(node); | 1372 elements.getOperatorSelectorInComplexSendSet(node); |
| 1373 TypeMask operatorMask = memberData.typeOfOperator(node); | 1373 TypeMask operatorMask = memberData.typeOfOperator(node); |
| 1374 Selector setterSelector = elements.getSelector(node); | 1374 Selector setterSelector = elements.getSelector(node); |
| 1375 TypeMask setterMask = memberData.typeOfSend(node); | 1375 TypeMask setterMask = memberData.typeOfSend(node); |
| 1376 | 1376 |
| 1377 TypeInformation getterType = handleDynamicSend(node, getterSelector, | 1377 TypeInformation getterType = handleDynamicSend( |
| 1378 getterMask, receiverType, new ArgumentsTypes([indexType], null)); | 1378 CallType.complex, |
| 1379 node, |
| 1380 getterSelector, |
| 1381 getterMask, |
| 1382 receiverType, |
| 1383 new ArgumentsTypes([indexType], null)); |
| 1379 | 1384 |
| 1380 TypeInformation returnType; | 1385 TypeInformation returnType; |
| 1381 if (node.isIfNullAssignment) { | 1386 if (node.isIfNullAssignment) { |
| 1382 returnType = types.allocateDiamondPhi(getterType, rhsType); | 1387 returnType = types.allocateDiamondPhi(getterType, rhsType); |
| 1383 } else { | 1388 } else { |
| 1384 returnType = handleDynamicSend(node, operatorSelector, operatorMask, | 1389 returnType = handleDynamicSend(CallType.complex, node, operatorSelector, |
| 1385 getterType, new ArgumentsTypes([rhsType], null)); | 1390 operatorMask, getterType, new ArgumentsTypes([rhsType], null)); |
| 1386 } | 1391 } |
| 1387 handleDynamicSend(node, setterSelector, setterMask, receiverType, | 1392 handleDynamicSend(CallType.complex, node, setterSelector, setterMask, |
| 1388 new ArgumentsTypes([indexType, returnType], null)); | 1393 receiverType, new ArgumentsTypes([indexType, returnType], null)); |
| 1389 | 1394 |
| 1390 if (node.isPostfix) { | 1395 if (node.isPostfix) { |
| 1391 return getterType; | 1396 return getterType; |
| 1392 } else { | 1397 } else { |
| 1393 return returnType; | 1398 return returnType; |
| 1394 } | 1399 } |
| 1395 } | 1400 } |
| 1396 | 1401 |
| 1397 /// Handle compound prefix/postfix operations, like `a[0]++`. | 1402 /// Handle compound prefix/postfix operations, like `a[0]++`. |
| 1398 TypeInformation handleCompoundPrefixPostfix( | 1403 TypeInformation handleCompoundPrefixPostfix( |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 TypeInformation getterType = handleSuperSend(node, getterSelector, | 1481 TypeInformation getterType = handleSuperSend(node, getterSelector, |
| 1477 getterMask, getter, new ArgumentsTypes([indexType], null)); | 1482 getterMask, getter, new ArgumentsTypes([indexType], null)); |
| 1478 | 1483 |
| 1479 TypeInformation returnType; | 1484 TypeInformation returnType; |
| 1480 if (node.isIfNullAssignment) { | 1485 if (node.isIfNullAssignment) { |
| 1481 returnType = types.allocateDiamondPhi(getterType, rhsType); | 1486 returnType = types.allocateDiamondPhi(getterType, rhsType); |
| 1482 } else { | 1487 } else { |
| 1483 Selector operatorSelector = | 1488 Selector operatorSelector = |
| 1484 elements.getOperatorSelectorInComplexSendSet(node); | 1489 elements.getOperatorSelectorInComplexSendSet(node); |
| 1485 TypeMask operatorMask = memberData.typeOfOperator(node); | 1490 TypeMask operatorMask = memberData.typeOfOperator(node); |
| 1486 returnType = handleDynamicSend(node, operatorSelector, operatorMask, | 1491 returnType = handleDynamicSend(CallType.complex, node, operatorSelector, |
| 1487 getterType, new ArgumentsTypes([rhsType], null)); | 1492 operatorMask, getterType, new ArgumentsTypes([rhsType], null)); |
| 1488 } | 1493 } |
| 1489 handleSuperSend(node, setterSelector, setterMask, setter, | 1494 handleSuperSend(node, setterSelector, setterMask, setter, |
| 1490 new ArgumentsTypes([indexType, returnType], null)); | 1495 new ArgumentsTypes([indexType, returnType], null)); |
| 1491 | 1496 |
| 1492 return node.isPostfix ? getterType : returnType; | 1497 return node.isPostfix ? getterType : returnType; |
| 1493 } | 1498 } |
| 1494 | 1499 |
| 1495 TypeInformation handleSuperSend(ast.Node node, Selector selector, | 1500 TypeInformation handleSuperSend(ast.Node node, Selector selector, |
| 1496 TypeMask mask, Element element, ArgumentsTypes arguments) { | 1501 TypeMask mask, Element element, ArgumentsTypes arguments) { |
| 1497 if (element.isMalformed) { | 1502 if (element.isMalformed) { |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1912 TypeInformation getterType = | 1917 TypeInformation getterType = |
| 1913 handleSuperSend(node, getterSelector, getterMask, getter, null); | 1918 handleSuperSend(node, getterSelector, getterMask, getter, null); |
| 1914 | 1919 |
| 1915 TypeInformation returnType; | 1920 TypeInformation returnType; |
| 1916 if (node.isIfNullAssignment) { | 1921 if (node.isIfNullAssignment) { |
| 1917 returnType = types.allocateDiamondPhi(getterType, rhsType); | 1922 returnType = types.allocateDiamondPhi(getterType, rhsType); |
| 1918 } else { | 1923 } else { |
| 1919 Selector operatorSelector = | 1924 Selector operatorSelector = |
| 1920 elements.getOperatorSelectorInComplexSendSet(node); | 1925 elements.getOperatorSelectorInComplexSendSet(node); |
| 1921 TypeMask operatorMask = memberData.typeOfOperator(node); | 1926 TypeMask operatorMask = memberData.typeOfOperator(node); |
| 1922 returnType = handleDynamicSend(node, operatorSelector, operatorMask, | 1927 returnType = handleDynamicSend(CallType.complex, node, operatorSelector, |
| 1923 getterType, new ArgumentsTypes([rhsType], null)); | 1928 operatorMask, getterType, new ArgumentsTypes([rhsType], null)); |
| 1924 } | 1929 } |
| 1925 handleSuperSend(node, setterSelector, setterMask, setter, | 1930 handleSuperSend(node, setterSelector, setterMask, setter, |
| 1926 new ArgumentsTypes([returnType], null)); | 1931 new ArgumentsTypes([returnType], null)); |
| 1927 | 1932 |
| 1928 return node.isPostfix ? getterType : returnType; | 1933 return node.isPostfix ? getterType : returnType; |
| 1929 } | 1934 } |
| 1930 | 1935 |
| 1931 /// Handle index set, like `foo[0] = 42`. | 1936 /// Handle index set, like `foo[0] = 42`. |
| 1932 TypeInformation handleIndexSet(ast.SendSet node, TypeInformation receiverType, | 1937 TypeInformation handleIndexSet(ast.SendSet node, TypeInformation receiverType, |
| 1933 TypeInformation indexType, TypeInformation rhsType) { | 1938 TypeInformation indexType, TypeInformation rhsType) { |
| 1934 Selector setterSelector = elements.getSelector(node); | 1939 Selector setterSelector = elements.getSelector(node); |
| 1935 TypeMask setterMask = memberData.typeOfSend(node); | 1940 TypeMask setterMask = memberData.typeOfSend(node); |
| 1936 handleDynamicSend(node, setterSelector, setterMask, receiverType, | 1941 handleDynamicSend(CallType.complex, node, setterSelector, setterMask, |
| 1937 new ArgumentsTypes([indexType, rhsType], null)); | 1942 receiverType, new ArgumentsTypes([indexType, rhsType], null)); |
| 1938 return rhsType; | 1943 return rhsType; |
| 1939 } | 1944 } |
| 1940 | 1945 |
| 1941 @override | 1946 @override |
| 1942 TypeInformation visitIndexSet( | 1947 TypeInformation visitIndexSet( |
| 1943 ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) { | 1948 ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) { |
| 1944 TypeInformation receiverType = visit(receiver); | 1949 TypeInformation receiverType = visit(receiver); |
| 1945 TypeInformation indexType = visit(index); | 1950 TypeInformation indexType = visit(index); |
| 1946 TypeInformation rhsType = visit(rhs); | 1951 TypeInformation rhsType = visit(rhs); |
| 1947 return handleIndexSet(node, receiverType, indexType, rhsType); | 1952 return handleIndexSet(node, receiverType, indexType, rhsType); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1994 // We just recognized a field initialization of the form: | 1999 // We just recognized a field initialization of the form: |
| 1995 // `this.foo = 42`. If there is only one target, we can update | 2000 // `this.foo = 42`. If there is only one target, we can update |
| 1996 // its type. | 2001 // its type. |
| 1997 if (targets.length == 1) { | 2002 if (targets.length == 1) { |
| 1998 MemberElement single = targets.first; | 2003 MemberElement single = targets.first; |
| 1999 if (single.isField) { | 2004 if (single.isField) { |
| 2000 locals.updateField(single, rhsType); | 2005 locals.updateField(single, rhsType); |
| 2001 } | 2006 } |
| 2002 } | 2007 } |
| 2003 } | 2008 } |
| 2004 handleDynamicSend( | 2009 handleDynamicSend(CallType.access, node, setterSelector, setterMask, |
| 2005 node, setterSelector, setterMask, receiverType, arguments); | 2010 receiverType, arguments); |
| 2006 } else if (element.isField) { | 2011 } else if (element.isField) { |
| 2007 FieldElement field = element; | 2012 FieldElement field = element; |
| 2008 if (field.isFinal) { | 2013 if (field.isFinal) { |
| 2009 inferrer.recordTypeOfField(field, rhsType); | 2014 inferrer.recordTypeOfField(field, rhsType); |
| 2010 } else { | 2015 } else { |
| 2011 if (analyzedElement.isGenerativeConstructor) { | 2016 if (analyzedElement.isGenerativeConstructor) { |
| 2012 locals.updateField(field, rhsType); | 2017 locals.updateField(field, rhsType); |
| 2013 } | 2018 } |
| 2014 if (visitingInitializers) { | 2019 if (visitingInitializers) { |
| 2015 inferrer.recordTypeOfField(field, rhsType); | 2020 inferrer.recordTypeOfField(field, rhsType); |
| 2016 } else { | 2021 } else { |
| 2017 handleDynamicSend( | 2022 handleDynamicSend(CallType.complex, node, setterSelector, setterMask, |
| 2018 node, setterSelector, setterMask, receiverType, arguments); | 2023 receiverType, arguments); |
| 2019 } | 2024 } |
| 2020 } | 2025 } |
| 2021 } else if (element.isLocal) { | 2026 } else if (element.isLocal) { |
| 2022 locals.update(element, rhsType, node); | 2027 locals.update(element, rhsType, node); |
| 2023 } | 2028 } |
| 2024 return rhsType; | 2029 return rhsType; |
| 2025 } | 2030 } |
| 2026 | 2031 |
| 2027 /// Handle a super access or invocation that results in a `noSuchMethod` call. | 2032 /// Handle a super access or invocation that results in a `noSuchMethod` call. |
| 2028 TypeInformation handleErroneousSuperSend(ast.Send node) { | 2033 TypeInformation handleErroneousSuperSend(ast.Send node) { |
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2737 !(element as ConstructorElement).isRedirectingFactory); | 2742 !(element as ConstructorElement).isRedirectingFactory); |
| 2738 // Erroneous elements may be unresolved, for example missing getters. | 2743 // Erroneous elements may be unresolved, for example missing getters. |
| 2739 if (Elements.isUnresolved(element)) return types.dynamicType; | 2744 if (Elements.isUnresolved(element)) return types.dynamicType; |
| 2740 // TODO(herhut): should we follow redirecting constructors here? We would | 2745 // TODO(herhut): should we follow redirecting constructors here? We would |
| 2741 // need to pay attention if the constructor is pointing to an erroneous | 2746 // need to pay attention if the constructor is pointing to an erroneous |
| 2742 // element. | 2747 // element. |
| 2743 return inferrer.registerCalledMember(node, selector, mask, outermostElement, | 2748 return inferrer.registerCalledMember(node, selector, mask, outermostElement, |
| 2744 element, arguments, sideEffects, inLoop); | 2749 element, arguments, sideEffects, inLoop); |
| 2745 } | 2750 } |
| 2746 | 2751 |
| 2747 TypeInformation handleDynamicSend(ast.Node node, Selector selector, | 2752 TypeInformation handleDynamicSend( |
| 2748 TypeMask mask, TypeInformation receiverType, ArgumentsTypes arguments) { | 2753 CallType callType, |
| 2754 ast.Node node, |
| 2755 Selector selector, |
| 2756 TypeMask mask, |
| 2757 TypeInformation receiverType, |
| 2758 ArgumentsTypes arguments) { |
| 2749 assert(receiverType != null); | 2759 assert(receiverType != null); |
| 2750 if (types.selectorNeedsUpdate(receiverType, mask)) { | 2760 if (types.selectorNeedsUpdate(receiverType, mask)) { |
| 2751 mask = receiverType == types.dynamicType | 2761 mask = receiverType == types.dynamicType |
| 2752 ? null | 2762 ? null |
| 2753 : types.newTypedSelector(receiverType, mask); | 2763 : types.newTypedSelector(receiverType, mask); |
| 2754 inferrer.updateSelectorInMember(outermostElement, node, selector, mask); | 2764 inferrer.updateSelectorInMember( |
| 2765 outermostElement, callType, node, selector, mask); |
| 2755 } | 2766 } |
| 2756 | 2767 |
| 2757 // If the receiver of the call is a local, we may know more about | 2768 // If the receiver of the call is a local, we may know more about |
| 2758 // its type by refining it with the potential targets of the | 2769 // its type by refining it with the potential targets of the |
| 2759 // calls. | 2770 // calls. |
| 2760 ast.Send send = node.asSend(); | 2771 ast.Send send = node.asSend(); |
| 2761 bool isConditional = false; | 2772 bool isConditional = false; |
| 2762 if (send != null) { | 2773 if (send != null) { |
| 2763 isConditional = send.isConditional; | 2774 isConditional = send.isConditional; |
| 2764 ast.Node receiver = send.receiver; | 2775 ast.Node receiver = send.receiver; |
| 2765 if (receiver != null) { | 2776 if (receiver != null) { |
| 2766 Element element = elements[receiver]; | 2777 Element element = elements[receiver]; |
| 2767 if (Elements.isLocal(element) && !capturedVariables.contains(element)) { | 2778 if (Elements.isLocal(element) && !capturedVariables.contains(element)) { |
| 2768 TypeInformation refinedType = types.refineReceiver( | 2779 TypeInformation refinedType = types.refineReceiver( |
| 2769 selector, mask, receiverType, send.isConditional); | 2780 selector, mask, receiverType, send.isConditional); |
| 2770 locals.update(element, refinedType, node); | 2781 locals.update(element, refinedType, node); |
| 2771 } | 2782 } |
| 2772 } | 2783 } |
| 2773 } | 2784 } |
| 2774 | 2785 |
| 2775 return inferrer.registerCalledSelector(node, selector, mask, receiverType, | 2786 return inferrer.registerCalledSelector( |
| 2776 outermostElement, arguments, sideEffects, inLoop, isConditional); | 2787 callType, |
| 2788 node, |
| 2789 selector, |
| 2790 mask, |
| 2791 receiverType, |
| 2792 outermostElement, |
| 2793 arguments, |
| 2794 sideEffects, |
| 2795 inLoop, |
| 2796 isConditional); |
| 2777 } | 2797 } |
| 2778 | 2798 |
| 2779 TypeInformation handleDynamicInvoke(ast.Send node) { | 2799 TypeInformation handleDynamicInvoke(ast.Send node) { |
| 2780 return _handleDynamicSend(node); | 2800 return _handleDynamicSend(node); |
| 2781 } | 2801 } |
| 2782 | 2802 |
| 2783 TypeInformation handleDynamicGet(ast.Send node) { | 2803 TypeInformation handleDynamicGet(ast.Send node) { |
| 2784 return _handleDynamicSend(node); | 2804 return _handleDynamicSend(node); |
| 2785 } | 2805 } |
| 2786 | 2806 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2809 node.isPropertyAccess ? null : analyzeArguments(node.arguments); | 2829 node.isPropertyAccess ? null : analyzeArguments(node.arguments); |
| 2810 if (selector.name == '==' || selector.name == '!=') { | 2830 if (selector.name == '==' || selector.name == '!=') { |
| 2811 if (types.isNull(receiverType)) { | 2831 if (types.isNull(receiverType)) { |
| 2812 potentiallyAddNullCheck(node, node.arguments.head); | 2832 potentiallyAddNullCheck(node, node.arguments.head); |
| 2813 return types.boolType; | 2833 return types.boolType; |
| 2814 } else if (types.isNull(arguments.positional[0])) { | 2834 } else if (types.isNull(arguments.positional[0])) { |
| 2815 potentiallyAddNullCheck(node, node.receiver); | 2835 potentiallyAddNullCheck(node, node.receiver); |
| 2816 return types.boolType; | 2836 return types.boolType; |
| 2817 } | 2837 } |
| 2818 } | 2838 } |
| 2819 return handleDynamicSend(node, selector, mask, receiverType, arguments); | 2839 return handleDynamicSend( |
| 2840 CallType.access, node, selector, mask, receiverType, arguments); |
| 2820 } | 2841 } |
| 2821 | 2842 |
| 2822 void recordReturnType(TypeInformation type) { | 2843 void recordReturnType(TypeInformation type) { |
| 2823 MethodElement analyzedMethod = analyzedElement; | 2844 MethodElement analyzedMethod = analyzedElement; |
| 2824 returnType = | 2845 returnType = |
| 2825 inferrer.addReturnTypeForMethod(analyzedMethod, returnType, type); | 2846 inferrer.addReturnTypeForMethod(analyzedMethod, returnType, type); |
| 2826 } | 2847 } |
| 2827 | 2848 |
| 2828 TypeInformation synthesizeForwardingCall( | 2849 TypeInformation synthesizeForwardingCall( |
| 2829 Spannable node, ConstructorElement element) { | 2850 Spannable node, ConstructorElement element) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2887 return null; | 2908 return null; |
| 2888 } | 2909 } |
| 2889 | 2910 |
| 2890 TypeInformation handleForInLoop( | 2911 TypeInformation handleForInLoop( |
| 2891 ast.ForIn node, | 2912 ast.ForIn node, |
| 2892 TypeInformation iteratorType, | 2913 TypeInformation iteratorType, |
| 2893 Selector currentSelector, | 2914 Selector currentSelector, |
| 2894 TypeMask currentMask, | 2915 TypeMask currentMask, |
| 2895 Selector moveNextSelector, | 2916 Selector moveNextSelector, |
| 2896 TypeMask moveNextMask) { | 2917 TypeMask moveNextMask) { |
| 2897 handleDynamicSend(node, moveNextSelector, moveNextMask, iteratorType, | 2918 handleDynamicSend(CallType.forIn, node, moveNextSelector, moveNextMask, |
| 2898 new ArgumentsTypes.empty()); | 2919 iteratorType, new ArgumentsTypes.empty()); |
| 2899 TypeInformation currentType = handleDynamicSend(node, currentSelector, | 2920 TypeInformation currentType = handleDynamicSend(CallType.forIn, node, |
| 2900 currentMask, iteratorType, new ArgumentsTypes.empty()); | 2921 currentSelector, currentMask, iteratorType, new ArgumentsTypes.empty()); |
| 2901 | 2922 |
| 2902 if (node.expression.isThis()) { | 2923 if (node.expression.isThis()) { |
| 2903 // Any reasonable implementation of an iterator would expose | 2924 // Any reasonable implementation of an iterator would expose |
| 2904 // this, so we play it safe and assume it will. | 2925 // this, so we play it safe and assume it will. |
| 2905 isThisExposed = true; | 2926 isThisExposed = true; |
| 2906 } | 2927 } |
| 2907 | 2928 |
| 2908 ast.Node identifier = node.declaredIdentifier; | 2929 ast.Node identifier = node.declaredIdentifier; |
| 2909 Element element = elements.getForInVariable(node); | 2930 Element element = elements.getForInVariable(node); |
| 2910 Selector selector = elements.getSelector(identifier); | 2931 Selector selector = elements.getSelector(identifier); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2945 | 2966 |
| 2946 TypeInformation visitSyncForIn(ast.SyncForIn node) { | 2967 TypeInformation visitSyncForIn(ast.SyncForIn node) { |
| 2947 TypeInformation expressionType = visit(node.expression); | 2968 TypeInformation expressionType = visit(node.expression); |
| 2948 Selector iteratorSelector = Selectors.iterator; | 2969 Selector iteratorSelector = Selectors.iterator; |
| 2949 TypeMask iteratorMask = memberData.typeOfIterator(node); | 2970 TypeMask iteratorMask = memberData.typeOfIterator(node); |
| 2950 Selector currentSelector = Selectors.current; | 2971 Selector currentSelector = Selectors.current; |
| 2951 TypeMask currentMask = memberData.typeOfIteratorCurrent(node); | 2972 TypeMask currentMask = memberData.typeOfIteratorCurrent(node); |
| 2952 Selector moveNextSelector = Selectors.moveNext; | 2973 Selector moveNextSelector = Selectors.moveNext; |
| 2953 TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node); | 2974 TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node); |
| 2954 | 2975 |
| 2955 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, | 2976 TypeInformation iteratorType = handleDynamicSend( |
| 2956 iteratorMask, expressionType, new ArgumentsTypes.empty()); | 2977 CallType.forIn, |
| 2978 node, |
| 2979 iteratorSelector, |
| 2980 iteratorMask, |
| 2981 expressionType, |
| 2982 new ArgumentsTypes.empty()); |
| 2957 | 2983 |
| 2958 return handleForInLoop(node, iteratorType, currentSelector, currentMask, | 2984 return handleForInLoop(node, iteratorType, currentSelector, currentMask, |
| 2959 moveNextSelector, moveNextMask); | 2985 moveNextSelector, moveNextMask); |
| 2960 } | 2986 } |
| 2961 } | 2987 } |
| OLD | NEW |