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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 SemanticSendResolvedMixin<TypeInformation, dynamic>, | 49 SemanticSendResolvedMixin<TypeInformation, dynamic>, |
50 CompoundBulkMixin<TypeInformation, dynamic>, | 50 CompoundBulkMixin<TypeInformation, dynamic>, |
51 SetIfNullBulkMixin<TypeInformation, dynamic>, | 51 SetIfNullBulkMixin<TypeInformation, dynamic>, |
52 PrefixBulkMixin<TypeInformation, dynamic>, | 52 PrefixBulkMixin<TypeInformation, dynamic>, |
53 PostfixBulkMixin<TypeInformation, dynamic>, | 53 PostfixBulkMixin<TypeInformation, dynamic>, |
54 ErrorBulkMixin<TypeInformation, dynamic>, | 54 ErrorBulkMixin<TypeInformation, dynamic>, |
55 NewBulkMixin<TypeInformation, dynamic>, | 55 NewBulkMixin<TypeInformation, dynamic>, |
56 SetBulkMixin<TypeInformation, dynamic> | 56 SetBulkMixin<TypeInformation, dynamic> |
57 implements SemanticSendVisitor<TypeInformation, dynamic> { | 57 implements SemanticSendVisitor<TypeInformation, dynamic> { |
58 final Compiler compiler; | 58 final Compiler compiler; |
59 final AstElement analyzedElement; | 59 final ExecutableElement analyzedElement; |
60 final ResolvedAst resolvedAst; | 60 final ResolvedAst resolvedAst; |
61 final TypeSystem types; | 61 final TypeSystem types; |
62 final Map<JumpTarget, List<LocalsHandler>> breaksFor = | 62 final Map<JumpTarget, List<LocalsHandler>> breaksFor = |
63 new Map<JumpTarget, List<LocalsHandler>>(); | 63 new Map<JumpTarget, List<LocalsHandler>>(); |
64 final Map<JumpTarget, List<LocalsHandler>> continuesFor = | 64 final Map<JumpTarget, List<LocalsHandler>> continuesFor = |
65 new Map<JumpTarget, List<LocalsHandler>>(); | 65 new Map<JumpTarget, List<LocalsHandler>>(); |
66 LocalsHandler locals; | 66 LocalsHandler locals; |
67 final List<TypeInformation> cascadeReceiverStack = | 67 final List<TypeInformation> cascadeReceiverStack = |
68 new List<TypeInformation>(); | 68 new List<TypeInformation>(); |
69 | 69 |
70 TypeInformation returnType; | 70 TypeInformation returnType; |
71 bool visitingInitializers = false; | 71 bool visitingInitializers = false; |
72 bool isConstructorRedirect = false; | 72 bool isConstructorRedirect = false; |
73 bool seenSuperConstructorCall = false; | 73 bool seenSuperConstructorCall = false; |
74 SideEffects sideEffects = new SideEffects.empty(); | 74 SideEffects sideEffects = new SideEffects.empty(); |
75 final Element outermostElement; | 75 final MemberElement outermostElement; |
76 final InferrerEngine inferrer; | 76 final InferrerEngine inferrer; |
77 final Setlet<Entity> capturedVariables = new Setlet<Entity>(); | 77 final Setlet<Entity> capturedVariables = new Setlet<Entity>(); |
78 final GlobalTypeInferenceElementData inTreeData; | 78 final GlobalTypeInferenceElementData memberData; |
79 | 79 |
80 ElementGraphBuilder.internal( | 80 ElementGraphBuilder.internal( |
81 AstElement analyzedElement, | 81 ExecutableElement analyzedElement, |
82 this.resolvedAst, | 82 this.resolvedAst, |
83 this.outermostElement, | 83 this.outermostElement, |
84 InferrerEngine inferrer, | 84 InferrerEngine inferrer, |
85 this.compiler, | 85 this.compiler, |
86 this.locals) | 86 this.locals) |
87 : this.analyzedElement = analyzedElement, | 87 : this.analyzedElement = analyzedElement, |
88 this.inferrer = inferrer, | 88 this.inferrer = inferrer, |
89 this.types = inferrer.types, | 89 this.types = inferrer.types, |
90 this.inTreeData = analyzedElement.isLocal | 90 this.memberData = inferrer.dataOfMember(analyzedElement.memberContext) { |
91 ? inferrer.dataOfLocalFunction(analyzedElement) | |
92 : inferrer.dataOfMember(analyzedElement) { | |
93 assert(outermostElement != null); | 91 assert(outermostElement != null); |
94 if (locals != null) return; | 92 if (locals != null) return; |
95 ast.Node node; | 93 ast.Node node; |
96 if (resolvedAst.kind == ResolvedAstKind.PARSED) { | 94 if (resolvedAst.kind == ResolvedAstKind.PARSED) { |
97 node = resolvedAst.node; | 95 node = resolvedAst.node; |
98 } | 96 } |
99 FieldInitializationScope fieldScope = | 97 FieldInitializationScope fieldScope = |
100 analyzedElement.isGenerativeConstructor | 98 analyzedElement.isGenerativeConstructor |
101 ? new FieldInitializationScope(types) | 99 ? new FieldInitializationScope(types) |
102 : null; | 100 : null; |
103 locals = | 101 locals = |
104 new LocalsHandler(inferrer, types, compiler.options, node, fieldScope); | 102 new LocalsHandler(inferrer, types, compiler.options, node, fieldScope); |
105 } | 103 } |
106 | 104 |
107 ElementGraphBuilder(AstElement element, ResolvedAst resolvedAst, | 105 ElementGraphBuilder(ExecutableElement element, ResolvedAst resolvedAst, |
108 Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler]) | 106 Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler]) |
109 : this.internal( | 107 : this.internal(element, resolvedAst, element.memberContext, inferrer, |
110 element, | 108 compiler, handler); |
111 resolvedAst, | |
112 element.outermostEnclosingMemberOrTopLevel.implementation, | |
113 inferrer, | |
114 compiler, | |
115 handler); | |
116 | 109 |
117 TreeElements get elements => resolvedAst.elements; | 110 TreeElements get elements => resolvedAst.elements; |
118 | 111 |
119 bool accumulateIsChecks = false; | 112 bool accumulateIsChecks = false; |
120 bool conditionIsSimple = false; | 113 bool conditionIsSimple = false; |
121 List<ast.Send> isChecks; | 114 List<ast.Send> isChecks; |
122 int loopLevel = 0; | 115 int loopLevel = 0; |
123 | 116 |
124 bool get inLoop => loopLevel > 0; | 117 bool get inLoop => loopLevel > 0; |
125 bool get isThisExposed { | 118 bool get isThisExposed { |
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 } | 1224 } |
1232 | 1225 |
1233 TypeInformation handleSendSet(ast.SendSet node) { | 1226 TypeInformation handleSendSet(ast.SendSet node) { |
1234 Element element = elements[node]; | 1227 Element element = elements[node]; |
1235 if (!Elements.isUnresolved(element) && element.impliesType) { | 1228 if (!Elements.isUnresolved(element) && element.impliesType) { |
1236 node.visitChildren(this); | 1229 node.visitChildren(this); |
1237 return types.dynamicType; | 1230 return types.dynamicType; |
1238 } | 1231 } |
1239 | 1232 |
1240 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); | 1233 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
1241 TypeMask getterMask = inTreeData.typeOfGetter(node); | 1234 TypeMask getterMask = memberData.typeOfGetter(node); |
1242 TypeMask operatorMask = inTreeData.typeOfOperator(node); | 1235 TypeMask operatorMask = memberData.typeOfOperator(node); |
1243 Selector setterSelector = elements.getSelector(node); | 1236 Selector setterSelector = elements.getSelector(node); |
1244 TypeMask setterMask = inTreeData.typeOfSend(node); | 1237 TypeMask setterMask = memberData.typeOfSend(node); |
1245 | 1238 |
1246 String op = node.assignmentOperator.source; | 1239 String op = node.assignmentOperator.source; |
1247 bool isIncrementOrDecrement = op == '++' || op == '--'; | 1240 bool isIncrementOrDecrement = op == '++' || op == '--'; |
1248 | 1241 |
1249 TypeInformation receiverType; | 1242 TypeInformation receiverType; |
1250 bool isCallOnThis = false; | 1243 bool isCallOnThis = false; |
1251 if (node.receiver == null) { | 1244 if (node.receiver == null) { |
1252 if (treatAsInstanceMember(element)) { | 1245 if (treatAsInstanceMember(element)) { |
1253 receiverType = thisType; | 1246 receiverType = thisType; |
1254 isCallOnThis = true; | 1247 isCallOnThis = true; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1348 } | 1341 } |
1349 | 1342 |
1350 /// Handle compound index set, like `foo[0] += 42` or `foo[0]++`. | 1343 /// Handle compound index set, like `foo[0] += 42` or `foo[0]++`. |
1351 TypeInformation handleCompoundIndexSet( | 1344 TypeInformation handleCompoundIndexSet( |
1352 ast.SendSet node, | 1345 ast.SendSet node, |
1353 TypeInformation receiverType, | 1346 TypeInformation receiverType, |
1354 TypeInformation indexType, | 1347 TypeInformation indexType, |
1355 TypeInformation rhsType) { | 1348 TypeInformation rhsType) { |
1356 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); | 1349 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
1357 | 1350 |
1358 TypeMask getterMask = inTreeData.typeOfGetter(node); | 1351 TypeMask getterMask = memberData.typeOfGetter(node); |
1359 Selector operatorSelector = | 1352 Selector operatorSelector = |
1360 elements.getOperatorSelectorInComplexSendSet(node); | 1353 elements.getOperatorSelectorInComplexSendSet(node); |
1361 TypeMask operatorMask = inTreeData.typeOfOperator(node); | 1354 TypeMask operatorMask = memberData.typeOfOperator(node); |
1362 Selector setterSelector = elements.getSelector(node); | 1355 Selector setterSelector = elements.getSelector(node); |
1363 TypeMask setterMask = inTreeData.typeOfSend(node); | 1356 TypeMask setterMask = memberData.typeOfSend(node); |
1364 | 1357 |
1365 TypeInformation getterType = handleDynamicSend(node, getterSelector, | 1358 TypeInformation getterType = handleDynamicSend(node, getterSelector, |
1366 getterMask, receiverType, new ArgumentsTypes([indexType], null)); | 1359 getterMask, receiverType, new ArgumentsTypes([indexType], null)); |
1367 | 1360 |
1368 TypeInformation returnType; | 1361 TypeInformation returnType; |
1369 if (node.isIfNullAssignment) { | 1362 if (node.isIfNullAssignment) { |
1370 returnType = types.allocateDiamondPhi(getterType, rhsType); | 1363 returnType = types.allocateDiamondPhi(getterType, rhsType); |
1371 } else { | 1364 } else { |
1372 returnType = handleDynamicSend(node, operatorSelector, operatorMask, | 1365 returnType = handleDynamicSend(node, operatorSelector, operatorMask, |
1373 getterType, new ArgumentsTypes([rhsType], null)); | 1366 getterType, new ArgumentsTypes([rhsType], null)); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1450 TypeInformation indexType = visit(index); | 1443 TypeInformation indexType = visit(index); |
1451 TypeInformation rhsType = visit(rhs); | 1444 TypeInformation rhsType = visit(rhs); |
1452 return _handleSuperCompoundIndexSet( | 1445 return _handleSuperCompoundIndexSet( |
1453 node, getter, setter, indexType, rhsType); | 1446 node, getter, setter, indexType, rhsType); |
1454 } | 1447 } |
1455 | 1448 |
1456 TypeInformation _handleSuperCompoundIndexSet(ast.SendSet node, Element getter, | 1449 TypeInformation _handleSuperCompoundIndexSet(ast.SendSet node, Element getter, |
1457 Element setter, TypeInformation indexType, TypeInformation rhsType) { | 1450 Element setter, TypeInformation indexType, TypeInformation rhsType) { |
1458 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); | 1451 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
1459 | 1452 |
1460 TypeMask getterMask = inTreeData.typeOfGetter(node); | 1453 TypeMask getterMask = memberData.typeOfGetter(node); |
1461 Selector setterSelector = elements.getSelector(node); | 1454 Selector setterSelector = elements.getSelector(node); |
1462 TypeMask setterMask = inTreeData.typeOfSend(node); | 1455 TypeMask setterMask = memberData.typeOfSend(node); |
1463 | 1456 |
1464 TypeInformation getterType = handleSuperSend(node, getterSelector, | 1457 TypeInformation getterType = handleSuperSend(node, getterSelector, |
1465 getterMask, getter, new ArgumentsTypes([indexType], null)); | 1458 getterMask, getter, new ArgumentsTypes([indexType], null)); |
1466 | 1459 |
1467 TypeInformation returnType; | 1460 TypeInformation returnType; |
1468 if (node.isIfNullAssignment) { | 1461 if (node.isIfNullAssignment) { |
1469 returnType = types.allocateDiamondPhi(getterType, rhsType); | 1462 returnType = types.allocateDiamondPhi(getterType, rhsType); |
1470 } else { | 1463 } else { |
1471 Selector operatorSelector = | 1464 Selector operatorSelector = |
1472 elements.getOperatorSelectorInComplexSendSet(node); | 1465 elements.getOperatorSelectorInComplexSendSet(node); |
1473 TypeMask operatorMask = inTreeData.typeOfOperator(node); | 1466 TypeMask operatorMask = memberData.typeOfOperator(node); |
1474 returnType = handleDynamicSend(node, operatorSelector, operatorMask, | 1467 returnType = handleDynamicSend(node, operatorSelector, operatorMask, |
1475 getterType, new ArgumentsTypes([rhsType], null)); | 1468 getterType, new ArgumentsTypes([rhsType], null)); |
1476 } | 1469 } |
1477 handleSuperSend(node, setterSelector, setterMask, setter, | 1470 handleSuperSend(node, setterSelector, setterMask, setter, |
1478 new ArgumentsTypes([indexType, returnType], null)); | 1471 new ArgumentsTypes([indexType, returnType], null)); |
1479 | 1472 |
1480 return node.isPostfix ? getterType : returnType; | 1473 return node.isPostfix ? getterType : returnType; |
1481 } | 1474 } |
1482 | 1475 |
1483 TypeInformation handleSuperSend(ast.Node node, Selector selector, | 1476 TypeInformation handleSuperSend(ast.Node node, Selector selector, |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1886 } | 1879 } |
1887 | 1880 |
1888 TypeInformation handleSuperPrefixPostfix( | 1881 TypeInformation handleSuperPrefixPostfix( |
1889 ast.SendSet node, Element getter, Element setter) { | 1882 ast.SendSet node, Element getter, Element setter) { |
1890 return _handleSuperCompound(node, getter, setter, types.uint31Type); | 1883 return _handleSuperCompound(node, getter, setter, types.uint31Type); |
1891 } | 1884 } |
1892 | 1885 |
1893 TypeInformation _handleSuperCompound(ast.SendSet node, Element getter, | 1886 TypeInformation _handleSuperCompound(ast.SendSet node, Element getter, |
1894 Element setter, TypeInformation rhsType) { | 1887 Element setter, TypeInformation rhsType) { |
1895 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); | 1888 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
1896 TypeMask getterMask = inTreeData.typeOfGetter(node); | 1889 TypeMask getterMask = memberData.typeOfGetter(node); |
1897 Selector setterSelector = elements.getSelector(node); | 1890 Selector setterSelector = elements.getSelector(node); |
1898 TypeMask setterMask = inTreeData.typeOfSend(node); | 1891 TypeMask setterMask = memberData.typeOfSend(node); |
1899 | 1892 |
1900 TypeInformation getterType = | 1893 TypeInformation getterType = |
1901 handleSuperSend(node, getterSelector, getterMask, getter, null); | 1894 handleSuperSend(node, getterSelector, getterMask, getter, null); |
1902 | 1895 |
1903 TypeInformation returnType; | 1896 TypeInformation returnType; |
1904 if (node.isIfNullAssignment) { | 1897 if (node.isIfNullAssignment) { |
1905 returnType = types.allocateDiamondPhi(getterType, rhsType); | 1898 returnType = types.allocateDiamondPhi(getterType, rhsType); |
1906 } else { | 1899 } else { |
1907 Selector operatorSelector = | 1900 Selector operatorSelector = |
1908 elements.getOperatorSelectorInComplexSendSet(node); | 1901 elements.getOperatorSelectorInComplexSendSet(node); |
1909 TypeMask operatorMask = inTreeData.typeOfOperator(node); | 1902 TypeMask operatorMask = memberData.typeOfOperator(node); |
1910 returnType = handleDynamicSend(node, operatorSelector, operatorMask, | 1903 returnType = handleDynamicSend(node, operatorSelector, operatorMask, |
1911 getterType, new ArgumentsTypes([rhsType], null)); | 1904 getterType, new ArgumentsTypes([rhsType], null)); |
1912 } | 1905 } |
1913 handleSuperSend(node, setterSelector, setterMask, setter, | 1906 handleSuperSend(node, setterSelector, setterMask, setter, |
1914 new ArgumentsTypes([returnType], null)); | 1907 new ArgumentsTypes([returnType], null)); |
1915 | 1908 |
1916 return node.isPostfix ? getterType : returnType; | 1909 return node.isPostfix ? getterType : returnType; |
1917 } | 1910 } |
1918 | 1911 |
1919 /// Handle index set, like `foo[0] = 42`. | 1912 /// Handle index set, like `foo[0] = 42`. |
1920 TypeInformation handleIndexSet(ast.SendSet node, TypeInformation receiverType, | 1913 TypeInformation handleIndexSet(ast.SendSet node, TypeInformation receiverType, |
1921 TypeInformation indexType, TypeInformation rhsType) { | 1914 TypeInformation indexType, TypeInformation rhsType) { |
1922 Selector setterSelector = elements.getSelector(node); | 1915 Selector setterSelector = elements.getSelector(node); |
1923 TypeMask setterMask = inTreeData.typeOfSend(node); | 1916 TypeMask setterMask = memberData.typeOfSend(node); |
1924 handleDynamicSend(node, setterSelector, setterMask, receiverType, | 1917 handleDynamicSend(node, setterSelector, setterMask, receiverType, |
1925 new ArgumentsTypes([indexType, rhsType], null)); | 1918 new ArgumentsTypes([indexType, rhsType], null)); |
1926 return rhsType; | 1919 return rhsType; |
1927 } | 1920 } |
1928 | 1921 |
1929 @override | 1922 @override |
1930 TypeInformation visitIndexSet( | 1923 TypeInformation visitIndexSet( |
1931 ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) { | 1924 ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) { |
1932 TypeInformation receiverType = visit(receiver); | 1925 TypeInformation receiverType = visit(receiver); |
1933 TypeInformation indexType = visit(index); | 1926 TypeInformation indexType = visit(index); |
1934 TypeInformation rhsType = visit(rhs); | 1927 TypeInformation rhsType = visit(rhs); |
1935 return handleIndexSet(node, receiverType, indexType, rhsType); | 1928 return handleIndexSet(node, receiverType, indexType, rhsType); |
1936 } | 1929 } |
1937 | 1930 |
1938 /// Handle super index set, like `super[42] = true`. | 1931 /// Handle super index set, like `super[42] = true`. |
1939 TypeInformation handleSuperIndexSet( | 1932 TypeInformation handleSuperIndexSet( |
1940 ast.SendSet node, Element element, ast.Node index, ast.Node rhs) { | 1933 ast.SendSet node, Element element, ast.Node index, ast.Node rhs) { |
1941 TypeInformation indexType = visit(index); | 1934 TypeInformation indexType = visit(index); |
1942 TypeInformation rhsType = visit(rhs); | 1935 TypeInformation rhsType = visit(rhs); |
1943 Selector setterSelector = elements.getSelector(node); | 1936 Selector setterSelector = elements.getSelector(node); |
1944 TypeMask setterMask = inTreeData.typeOfSend(node); | 1937 TypeMask setterMask = memberData.typeOfSend(node); |
1945 handleStaticSend(node, setterSelector, setterMask, element, | 1938 handleStaticSend(node, setterSelector, setterMask, element, |
1946 new ArgumentsTypes([indexType, rhsType], null)); | 1939 new ArgumentsTypes([indexType, rhsType], null)); |
1947 return rhsType; | 1940 return rhsType; |
1948 } | 1941 } |
1949 | 1942 |
1950 @override | 1943 @override |
1951 TypeInformation visitSuperIndexSet(ast.SendSet node, FunctionElement function, | 1944 TypeInformation visitSuperIndexSet(ast.SendSet node, FunctionElement function, |
1952 ast.Node index, ast.Node rhs, _) { | 1945 ast.Node index, ast.Node rhs, _) { |
1953 return handleSuperIndexSet(node, function, index, rhs); | 1946 return handleSuperIndexSet(node, function, index, rhs); |
1954 } | 1947 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2009 locals.update(element, rhsType, node); | 2002 locals.update(element, rhsType, node); |
2010 } | 2003 } |
2011 return rhsType; | 2004 return rhsType; |
2012 } | 2005 } |
2013 | 2006 |
2014 /// Handle a super access or invocation that results in a `noSuchMethod` call. | 2007 /// Handle a super access or invocation that results in a `noSuchMethod` call. |
2015 TypeInformation handleErroneousSuperSend(ast.Send node) { | 2008 TypeInformation handleErroneousSuperSend(ast.Send node) { |
2016 ArgumentsTypes arguments = | 2009 ArgumentsTypes arguments = |
2017 node.isPropertyAccess ? null : analyzeArguments(node.arguments); | 2010 node.isPropertyAccess ? null : analyzeArguments(node.arguments); |
2018 Selector selector = elements.getSelector(node); | 2011 Selector selector = elements.getSelector(node); |
2019 TypeMask mask = inTreeData.typeOfSend(node); | 2012 TypeMask mask = memberData.typeOfSend(node); |
2020 // TODO(herhut): We could do better here if we knew what we | 2013 // TODO(herhut): We could do better here if we knew what we |
2021 // are calling does not expose this. | 2014 // are calling does not expose this. |
2022 // TODO(johnniwinther): Do we still need this when calling directly? | 2015 // TODO(johnniwinther): Do we still need this when calling directly? |
2023 isThisExposed = true; | 2016 isThisExposed = true; |
2024 return handleSuperNoSuchMethod(node, selector, mask, arguments); | 2017 return handleSuperNoSuchMethod(node, selector, mask, arguments); |
2025 } | 2018 } |
2026 | 2019 |
2027 TypeInformation handleSuperNoSuchMethod(ast.Send node, Selector selector, | 2020 TypeInformation handleSuperNoSuchMethod(ast.Send node, Selector selector, |
2028 TypeMask mask, ArgumentsTypes arguments) { | 2021 TypeMask mask, ArgumentsTypes arguments) { |
2029 // Ensure we create a node, to make explicit the call to the | 2022 // Ensure we create a node, to make explicit the call to the |
2030 // `noSuchMethod` handler. | 2023 // `noSuchMethod` handler. |
2031 ClassElement cls = outermostElement.enclosingClass; | 2024 ClassElement cls = outermostElement.enclosingClass; |
2032 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); | 2025 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); |
2033 if (!Selectors.noSuchMethod_.signatureApplies(element)) { | 2026 if (!Selectors.noSuchMethod_.signatureApplies(element)) { |
2034 ClassElement objectClass = closedWorld.commonElements.objectClass; | 2027 ClassElement objectClass = closedWorld.commonElements.objectClass; |
2035 element = objectClass.lookupMember(Identifiers.noSuchMethod_); | 2028 element = objectClass.lookupMember(Identifiers.noSuchMethod_); |
2036 } | 2029 } |
2037 return handleStaticSend(node, selector, mask, element, arguments); | 2030 return handleStaticSend(node, selector, mask, element, arguments); |
2038 } | 2031 } |
2039 | 2032 |
2040 /// Handle a .call invocation on the values retrieved from the super | 2033 /// Handle a .call invocation on the values retrieved from the super |
2041 /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter. | 2034 /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter. |
2042 TypeInformation handleSuperClosureCall( | 2035 TypeInformation handleSuperClosureCall( |
2043 ast.Send node, MemberElement element, ast.NodeList arguments) { | 2036 ast.Send node, MemberElement element, ast.NodeList arguments) { |
2044 ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes); | 2037 ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes); |
2045 Selector selector = elements.getSelector(node); | 2038 Selector selector = elements.getSelector(node); |
2046 TypeMask mask = inTreeData.typeOfSend(node); | 2039 TypeMask mask = memberData.typeOfSend(node); |
2047 // TODO(herhut): We could do better here if we knew what we | 2040 // TODO(herhut): We could do better here if we knew what we |
2048 // are calling does not expose this. | 2041 // are calling does not expose this. |
2049 isThisExposed = true; | 2042 isThisExposed = true; |
2050 return inferrer.registerCalledClosure( | 2043 return inferrer.registerCalledClosure( |
2051 node, | 2044 node, |
2052 selector, | 2045 selector, |
2053 mask, | 2046 mask, |
2054 inferrer.typeOfMember(element), | 2047 inferrer.typeOfMember(element), |
2055 outermostElement, | 2048 outermostElement, |
2056 argumentTypes, | 2049 argumentTypes, |
2057 sideEffects, | 2050 sideEffects, |
2058 inLoop); | 2051 inLoop); |
2059 } | 2052 } |
2060 | 2053 |
2061 /// Handle an invocation of super [method]. | 2054 /// Handle an invocation of super [method]. |
2062 TypeInformation handleSuperMethodInvoke( | 2055 TypeInformation handleSuperMethodInvoke( |
2063 ast.Send node, MethodElement method, ArgumentsTypes arguments) { | 2056 ast.Send node, MethodElement method, ArgumentsTypes arguments) { |
2064 // TODO(herhut): We could do better here if we knew what we | 2057 // TODO(herhut): We could do better here if we knew what we |
2065 // are calling does not expose this. | 2058 // are calling does not expose this. |
2066 isThisExposed = true; | 2059 isThisExposed = true; |
2067 Selector selector = elements.getSelector(node); | 2060 Selector selector = elements.getSelector(node); |
2068 TypeMask mask = inTreeData.typeOfSend(node); | 2061 TypeMask mask = memberData.typeOfSend(node); |
2069 return handleStaticSend(node, selector, mask, method, arguments); | 2062 return handleStaticSend(node, selector, mask, method, arguments); |
2070 } | 2063 } |
2071 | 2064 |
2072 /// Handle access to a super field or getter [element]. | 2065 /// Handle access to a super field or getter [element]. |
2073 TypeInformation handleSuperGet(ast.Send node, Element element) { | 2066 TypeInformation handleSuperGet(ast.Send node, Element element) { |
2074 // TODO(herhut): We could do better here if we knew what we | 2067 // TODO(herhut): We could do better here if we knew what we |
2075 // are calling does not expose this. | 2068 // are calling does not expose this. |
2076 isThisExposed = true; | 2069 isThisExposed = true; |
2077 Selector selector = elements.getSelector(node); | 2070 Selector selector = elements.getSelector(node); |
2078 TypeMask mask = inTreeData.typeOfSend(node); | 2071 TypeMask mask = memberData.typeOfSend(node); |
2079 return handleStaticSend(node, selector, mask, element, null); | 2072 return handleStaticSend(node, selector, mask, element, null); |
2080 } | 2073 } |
2081 | 2074 |
2082 /// Handle update to a super field or setter [element]. | 2075 /// Handle update to a super field or setter [element]. |
2083 TypeInformation handleSuperSet(ast.Send node, Element element, ast.Node rhs) { | 2076 TypeInformation handleSuperSet(ast.Send node, Element element, ast.Node rhs) { |
2084 TypeInformation rhsType = visit(rhs); | 2077 TypeInformation rhsType = visit(rhs); |
2085 // TODO(herhut): We could do better here if we knew what we | 2078 // TODO(herhut): We could do better here if we knew what we |
2086 // are calling does not expose this. | 2079 // are calling does not expose this. |
2087 isThisExposed = true; | 2080 isThisExposed = true; |
2088 Selector selector = elements.getSelector(node); | 2081 Selector selector = elements.getSelector(node); |
2089 TypeMask mask = inTreeData.typeOfSend(node); | 2082 TypeMask mask = memberData.typeOfSend(node); |
2090 handleStaticSend( | 2083 handleStaticSend( |
2091 node, selector, mask, element, new ArgumentsTypes([rhsType], null)); | 2084 node, selector, mask, element, new ArgumentsTypes([rhsType], null)); |
2092 return rhsType; | 2085 return rhsType; |
2093 } | 2086 } |
2094 | 2087 |
2095 @override | 2088 @override |
2096 TypeInformation visitSuperFieldSet( | 2089 TypeInformation visitSuperFieldSet( |
2097 ast.Send node, FieldElement method, ast.Node rhs, _) { | 2090 ast.Send node, FieldElement method, ast.Node rhs, _) { |
2098 return handleSuperSet(node, method, rhs); | 2091 return handleSuperSet(node, method, rhs); |
2099 } | 2092 } |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2309 // TODO(herhut): Remove the loop once effectiveTarget forwards to patches. | 2302 // TODO(herhut): Remove the loop once effectiveTarget forwards to patches. |
2310 while (target.isFactoryConstructor) { | 2303 while (target.isFactoryConstructor) { |
2311 if (!target.isRedirectingFactory) break; | 2304 if (!target.isRedirectingFactory) break; |
2312 target = target.effectiveTarget.implementation; | 2305 target = target.effectiveTarget.implementation; |
2313 } | 2306 } |
2314 if (compiler.backend.isForeign(closedWorld.commonElements, target)) { | 2307 if (compiler.backend.isForeign(closedWorld.commonElements, target)) { |
2315 return handleForeignSend(node, target); | 2308 return handleForeignSend(node, target); |
2316 } | 2309 } |
2317 Selector selector = elements.getSelector(node); | 2310 Selector selector = elements.getSelector(node); |
2318 CallStructure callStructure = selector.callStructure; | 2311 CallStructure callStructure = selector.callStructure; |
2319 TypeMask mask = inTreeData.typeOfSend(node); | 2312 TypeMask mask = memberData.typeOfSend(node); |
2320 // In erroneous code the number of arguments in the selector might not | 2313 // In erroneous code the number of arguments in the selector might not |
2321 // match the function element. | 2314 // match the function element. |
2322 // TODO(polux): return nonNullEmpty and check it doesn'TypeInformation break
anything | 2315 // TODO(polux): return nonNullEmpty and check it doesn'TypeInformation break
anything |
2323 if (target.isMalformed || | 2316 if (target.isMalformed || |
2324 !callStructure.signatureApplies(target.parameterStructure)) { | 2317 !callStructure.signatureApplies(target.parameterStructure)) { |
2325 return types.dynamicType; | 2318 return types.dynamicType; |
2326 } | 2319 } |
2327 | 2320 |
2328 TypeInformation returnType = | 2321 TypeInformation returnType = |
2329 handleStaticSend(node, selector, mask, target, arguments); | 2322 handleStaticSend(node, selector, mask, target, arguments); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2376 CallStructure callStructure, | 2369 CallStructure callStructure, |
2377 _) { | 2370 _) { |
2378 return bulkHandleNew(node, _); | 2371 return bulkHandleNew(node, _); |
2379 } | 2372 } |
2380 | 2373 |
2381 /// Handle invocation of a top level or static field or getter [element]. | 2374 /// Handle invocation of a top level or static field or getter [element]. |
2382 TypeInformation handleStaticFieldOrGetterInvoke( | 2375 TypeInformation handleStaticFieldOrGetterInvoke( |
2383 ast.Send node, MemberElement element) { | 2376 ast.Send node, MemberElement element) { |
2384 ArgumentsTypes arguments = analyzeArguments(node.arguments); | 2377 ArgumentsTypes arguments = analyzeArguments(node.arguments); |
2385 Selector selector = elements.getSelector(node); | 2378 Selector selector = elements.getSelector(node); |
2386 TypeMask mask = inTreeData.typeOfSend(node); | 2379 TypeMask mask = memberData.typeOfSend(node); |
2387 handleStaticSend(node, selector, mask, element, arguments); | 2380 handleStaticSend(node, selector, mask, element, arguments); |
2388 return inferrer.registerCalledClosure( | 2381 return inferrer.registerCalledClosure( |
2389 node, | 2382 node, |
2390 selector, | 2383 selector, |
2391 mask, | 2384 mask, |
2392 inferrer.typeOfMember(element), | 2385 inferrer.typeOfMember(element), |
2393 outermostElement, | 2386 outermostElement, |
2394 arguments, | 2387 arguments, |
2395 sideEffects, | 2388 sideEffects, |
2396 inLoop); | 2389 inLoop); |
2397 } | 2390 } |
2398 | 2391 |
2399 /// Handle invocation of a top level or static [function]. | 2392 /// Handle invocation of a top level or static [function]. |
2400 TypeInformation handleStaticFunctionInvoke( | 2393 TypeInformation handleStaticFunctionInvoke( |
2401 ast.Send node, MethodElement function) { | 2394 ast.Send node, MethodElement function) { |
2402 if (compiler.backend.isForeign(closedWorld.commonElements, function)) { | 2395 if (compiler.backend.isForeign(closedWorld.commonElements, function)) { |
2403 return handleForeignSend(node, function); | 2396 return handleForeignSend(node, function); |
2404 } | 2397 } |
2405 ArgumentsTypes arguments = analyzeArguments(node.arguments); | 2398 ArgumentsTypes arguments = analyzeArguments(node.arguments); |
2406 Selector selector = elements.getSelector(node); | 2399 Selector selector = elements.getSelector(node); |
2407 TypeMask mask = inTreeData.typeOfSend(node); | 2400 TypeMask mask = memberData.typeOfSend(node); |
2408 return handleStaticSend(node, selector, mask, function, arguments); | 2401 return handleStaticSend(node, selector, mask, function, arguments); |
2409 } | 2402 } |
2410 | 2403 |
2411 /// Handle an static invocation of an unresolved target or with incompatible | 2404 /// Handle an static invocation of an unresolved target or with incompatible |
2412 /// arguments to a resolved target. | 2405 /// arguments to a resolved target. |
2413 TypeInformation handleInvalidStaticInvoke(ast.Send node) { | 2406 TypeInformation handleInvalidStaticInvoke(ast.Send node) { |
2414 analyzeArguments(node.arguments); | 2407 analyzeArguments(node.arguments); |
2415 return types.dynamicType; | 2408 return types.dynamicType; |
2416 } | 2409 } |
2417 | 2410 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2493 | 2486 |
2494 @override | 2487 @override |
2495 TypeInformation visitUnresolvedInvoke(ast.Send node, Element element, | 2488 TypeInformation visitUnresolvedInvoke(ast.Send node, Element element, |
2496 ast.NodeList arguments, Selector selector, _) { | 2489 ast.NodeList arguments, Selector selector, _) { |
2497 return handleInvalidStaticInvoke(node); | 2490 return handleInvalidStaticInvoke(node); |
2498 } | 2491 } |
2499 | 2492 |
2500 TypeInformation handleForeignSend(ast.Send node, Element element) { | 2493 TypeInformation handleForeignSend(ast.Send node, Element element) { |
2501 ArgumentsTypes arguments = analyzeArguments(node.arguments); | 2494 ArgumentsTypes arguments = analyzeArguments(node.arguments); |
2502 Selector selector = elements.getSelector(node); | 2495 Selector selector = elements.getSelector(node); |
2503 TypeMask mask = inTreeData.typeOfSend(node); | 2496 TypeMask mask = memberData.typeOfSend(node); |
2504 String name = element.name; | 2497 String name = element.name; |
2505 handleStaticSend(node, selector, mask, element, arguments); | 2498 handleStaticSend(node, selector, mask, element, arguments); |
2506 if (name == JavaScriptBackend.JS || | 2499 if (name == JavaScriptBackend.JS || |
2507 name == JavaScriptBackend.JS_EMBEDDED_GLOBAL || | 2500 name == JavaScriptBackend.JS_EMBEDDED_GLOBAL || |
2508 name == JavaScriptBackend.JS_BUILTIN) { | 2501 name == JavaScriptBackend.JS_BUILTIN) { |
2509 native.NativeBehavior nativeBehavior = elements.getNativeData(node); | 2502 native.NativeBehavior nativeBehavior = elements.getNativeData(node); |
2510 sideEffects.add(nativeBehavior.sideEffects); | 2503 sideEffects.add(nativeBehavior.sideEffects); |
2511 return inferrer.typeOfNativeBehavior(nativeBehavior); | 2504 return inferrer.typeOfNativeBehavior(nativeBehavior); |
2512 } else if (name == 'JS_OPERATOR_AS_PREFIX' || name == 'JS_STRING_CONCAT') { | 2505 } else if (name == 'JS_OPERATOR_AS_PREFIX' || name == 'JS_STRING_CONCAT') { |
2513 return types.stringType; | 2506 return types.stringType; |
(...skipping 24 matching lines...) Expand all Loading... |
2538 | 2531 |
2539 /// Read a local variable, function or parameter. | 2532 /// Read a local variable, function or parameter. |
2540 TypeInformation handleLocalGet(ast.Send node, LocalElement local) { | 2533 TypeInformation handleLocalGet(ast.Send node, LocalElement local) { |
2541 assert(locals.use(local) != null); | 2534 assert(locals.use(local) != null); |
2542 return locals.use(local); | 2535 return locals.use(local); |
2543 } | 2536 } |
2544 | 2537 |
2545 /// Read a static or top level field. | 2538 /// Read a static or top level field. |
2546 TypeInformation handleStaticFieldGet(ast.Send node, FieldElement field) { | 2539 TypeInformation handleStaticFieldGet(ast.Send node, FieldElement field) { |
2547 Selector selector = elements.getSelector(node); | 2540 Selector selector = elements.getSelector(node); |
2548 TypeMask mask = inTreeData.typeOfSend(node); | 2541 TypeMask mask = memberData.typeOfSend(node); |
2549 return handleStaticSend(node, selector, mask, field, null); | 2542 return handleStaticSend(node, selector, mask, field, null); |
2550 } | 2543 } |
2551 | 2544 |
2552 /// Invoke a static or top level getter. | 2545 /// Invoke a static or top level getter. |
2553 TypeInformation handleStaticGetterGet(ast.Send node, GetterElement getter) { | 2546 TypeInformation handleStaticGetterGet(ast.Send node, GetterElement getter) { |
2554 Selector selector = elements.getSelector(node); | 2547 Selector selector = elements.getSelector(node); |
2555 TypeMask mask = inTreeData.typeOfSend(node); | 2548 TypeMask mask = memberData.typeOfSend(node); |
2556 return handleStaticSend(node, selector, mask, getter, null); | 2549 return handleStaticSend(node, selector, mask, getter, null); |
2557 } | 2550 } |
2558 | 2551 |
2559 /// Closurize a static or top level function. | 2552 /// Closurize a static or top level function. |
2560 TypeInformation handleStaticFunctionGet( | 2553 TypeInformation handleStaticFunctionGet( |
2561 ast.Send node, MethodElement function) { | 2554 ast.Send node, MethodElement function) { |
2562 Selector selector = elements.getSelector(node); | 2555 Selector selector = elements.getSelector(node); |
2563 TypeMask mask = inTreeData.typeOfSend(node); | 2556 TypeMask mask = memberData.typeOfSend(node); |
2564 return handleStaticSend(node, selector, mask, function, null); | 2557 return handleStaticSend(node, selector, mask, function, null); |
2565 } | 2558 } |
2566 | 2559 |
2567 @override | 2560 @override |
2568 TypeInformation visitDynamicPropertyGet( | 2561 TypeInformation visitDynamicPropertyGet( |
2569 ast.Send node, ast.Node receiver, Name name, _) { | 2562 ast.Send node, ast.Node receiver, Name name, _) { |
2570 return handleDynamicGet(node); | 2563 return handleDynamicGet(node); |
2571 } | 2564 } |
2572 | 2565 |
2573 @override | 2566 @override |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2645 | 2638 |
2646 @override | 2639 @override |
2647 TypeInformation visitUnresolvedGet(ast.Send node, Element element, _) { | 2640 TypeInformation visitUnresolvedGet(ast.Send node, Element element, _) { |
2648 return types.dynamicType; | 2641 return types.dynamicType; |
2649 } | 2642 } |
2650 | 2643 |
2651 /// Handle .call invocation on [closure]. | 2644 /// Handle .call invocation on [closure]. |
2652 TypeInformation handleCallInvoke(ast.Send node, TypeInformation closure) { | 2645 TypeInformation handleCallInvoke(ast.Send node, TypeInformation closure) { |
2653 ArgumentsTypes arguments = analyzeArguments(node.arguments); | 2646 ArgumentsTypes arguments = analyzeArguments(node.arguments); |
2654 Selector selector = elements.getSelector(node); | 2647 Selector selector = elements.getSelector(node); |
2655 TypeMask mask = inTreeData.typeOfSend(node); | 2648 TypeMask mask = memberData.typeOfSend(node); |
2656 return inferrer.registerCalledClosure(node, selector, mask, closure, | 2649 return inferrer.registerCalledClosure(node, selector, mask, closure, |
2657 outermostElement, arguments, sideEffects, inLoop); | 2650 outermostElement, arguments, sideEffects, inLoop); |
2658 } | 2651 } |
2659 | 2652 |
2660 @override | 2653 @override |
2661 TypeInformation visitExpressionInvoke(ast.Send node, ast.Node expression, | 2654 TypeInformation visitExpressionInvoke(ast.Send node, ast.Node expression, |
2662 ast.NodeList arguments, CallStructure callStructure, _) { | 2655 ast.NodeList arguments, CallStructure callStructure, _) { |
2663 return handleCallInvoke(node, expression.accept(this)); | 2656 return handleCallInvoke(node, expression.accept(this)); |
2664 } | 2657 } |
2665 | 2658 |
(...skipping 25 matching lines...) Expand all Loading... |
2691 | 2684 |
2692 @override | 2685 @override |
2693 TypeInformation visitLocalFunctionInvoke( | 2686 TypeInformation visitLocalFunctionInvoke( |
2694 ast.Send node, | 2687 ast.Send node, |
2695 LocalFunctionElement function, | 2688 LocalFunctionElement function, |
2696 ast.NodeList arguments, | 2689 ast.NodeList arguments, |
2697 CallStructure callStructure, | 2690 CallStructure callStructure, |
2698 _) { | 2691 _) { |
2699 ArgumentsTypes argumentTypes = analyzeArguments(node.arguments); | 2692 ArgumentsTypes argumentTypes = analyzeArguments(node.arguments); |
2700 Selector selector = elements.getSelector(node); | 2693 Selector selector = elements.getSelector(node); |
2701 TypeMask mask = inTreeData.typeOfSend(node); | 2694 TypeMask mask = memberData.typeOfSend(node); |
2702 // This only works for function statements. We need a | 2695 // This only works for function statements. We need a |
2703 // more sophisticated type system with function types to support | 2696 // more sophisticated type system with function types to support |
2704 // more. | 2697 // more. |
2705 return inferrer.registerCalledLocalFunction(node, selector, mask, | 2698 return inferrer.registerCalledLocalFunction(node, selector, mask, |
2706 outermostElement, function, argumentTypes, sideEffects, inLoop); | 2699 outermostElement, function, argumentTypes, sideEffects, inLoop); |
2707 } | 2700 } |
2708 | 2701 |
2709 @override | 2702 @override |
2710 TypeInformation visitLocalFunctionIncompatibleInvoke( | 2703 TypeInformation visitLocalFunctionIncompatibleInvoke( |
2711 ast.Send node, | 2704 ast.Send node, |
(...skipping 18 matching lines...) Expand all Loading... |
2730 element, arguments, sideEffects, inLoop); | 2723 element, arguments, sideEffects, inLoop); |
2731 } | 2724 } |
2732 | 2725 |
2733 TypeInformation handleDynamicSend(ast.Node node, Selector selector, | 2726 TypeInformation handleDynamicSend(ast.Node node, Selector selector, |
2734 TypeMask mask, TypeInformation receiverType, ArgumentsTypes arguments) { | 2727 TypeMask mask, TypeInformation receiverType, ArgumentsTypes arguments) { |
2735 assert(receiverType != null); | 2728 assert(receiverType != null); |
2736 if (types.selectorNeedsUpdate(receiverType, mask)) { | 2729 if (types.selectorNeedsUpdate(receiverType, mask)) { |
2737 mask = receiverType == types.dynamicType | 2730 mask = receiverType == types.dynamicType |
2738 ? null | 2731 ? null |
2739 : types.newTypedSelector(receiverType, mask); | 2732 : types.newTypedSelector(receiverType, mask); |
2740 if (analyzedElement.isLocal) { | 2733 inferrer.updateSelectorInMember(outermostElement, node, selector, mask); |
2741 inferrer.updateSelectorInLocalFunction( | |
2742 analyzedElement, node, selector, mask); | |
2743 } else { | |
2744 inferrer.updateSelectorInMember(analyzedElement, node, selector, mask); | |
2745 } | |
2746 } | 2734 } |
2747 | 2735 |
2748 // If the receiver of the call is a local, we may know more about | 2736 // If the receiver of the call is a local, we may know more about |
2749 // its type by refining it with the potential targets of the | 2737 // its type by refining it with the potential targets of the |
2750 // calls. | 2738 // calls. |
2751 ast.Send send = node.asSend(); | 2739 ast.Send send = node.asSend(); |
2752 if (send != null) { | 2740 if (send != null) { |
2753 ast.Node receiver = send.receiver; | 2741 ast.Node receiver = send.receiver; |
2754 if (receiver != null) { | 2742 if (receiver != null) { |
2755 Element element = elements[receiver]; | 2743 Element element = elements[receiver]; |
(...skipping 26 matching lines...) Expand all Loading... |
2782 isCallOnThis = true; | 2770 isCallOnThis = true; |
2783 receiverType = thisType; | 2771 receiverType = thisType; |
2784 } | 2772 } |
2785 } else { | 2773 } else { |
2786 ast.Node receiver = node.receiver; | 2774 ast.Node receiver = node.receiver; |
2787 isCallOnThis = isThisOrSuper(receiver); | 2775 isCallOnThis = isThisOrSuper(receiver); |
2788 receiverType = visit(receiver); | 2776 receiverType = visit(receiver); |
2789 } | 2777 } |
2790 | 2778 |
2791 Selector selector = elements.getSelector(node); | 2779 Selector selector = elements.getSelector(node); |
2792 TypeMask mask = inTreeData.typeOfSend(node); | 2780 TypeMask mask = memberData.typeOfSend(node); |
2793 if (!isThisExposed && isCallOnThis) { | 2781 if (!isThisExposed && isCallOnThis) { |
2794 checkIfExposesThis(selector, types.newTypedSelector(receiverType, mask)); | 2782 checkIfExposesThis(selector, types.newTypedSelector(receiverType, mask)); |
2795 } | 2783 } |
2796 | 2784 |
2797 ArgumentsTypes arguments = | 2785 ArgumentsTypes arguments = |
2798 node.isPropertyAccess ? null : analyzeArguments(node.arguments); | 2786 node.isPropertyAccess ? null : analyzeArguments(node.arguments); |
2799 if (selector.name == '==' || selector.name == '!=') { | 2787 if (selector.name == '==' || selector.name == '!=') { |
2800 if (types.isNull(receiverType)) { | 2788 if (types.isNull(receiverType)) { |
2801 potentiallyAddNullCheck(node, node.arguments.head); | 2789 potentiallyAddNullCheck(node, node.arguments.head); |
2802 return types.boolType; | 2790 return types.boolType; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2894 | 2882 |
2895 if (node.expression.isThis()) { | 2883 if (node.expression.isThis()) { |
2896 // Any reasonable implementation of an iterator would expose | 2884 // Any reasonable implementation of an iterator would expose |
2897 // this, so we play it safe and assume it will. | 2885 // this, so we play it safe and assume it will. |
2898 isThisExposed = true; | 2886 isThisExposed = true; |
2899 } | 2887 } |
2900 | 2888 |
2901 ast.Node identifier = node.declaredIdentifier; | 2889 ast.Node identifier = node.declaredIdentifier; |
2902 Element element = elements.getForInVariable(node); | 2890 Element element = elements.getForInVariable(node); |
2903 Selector selector = elements.getSelector(identifier); | 2891 Selector selector = elements.getSelector(identifier); |
2904 TypeMask mask = inTreeData.typeOfSend(identifier.asSend()); | 2892 TypeMask mask = memberData.typeOfSend(identifier.asSend()); |
2905 | 2893 |
2906 TypeInformation receiverType; | 2894 TypeInformation receiverType; |
2907 if (element != null && element.isInstanceMember) { | 2895 if (element != null && element.isInstanceMember) { |
2908 receiverType = thisType; | 2896 receiverType = thisType; |
2909 } else { | 2897 } else { |
2910 receiverType = types.dynamicType; | 2898 receiverType = types.dynamicType; |
2911 } | 2899 } |
2912 | 2900 |
2913 handlePlainAssignment(identifier, element, selector, mask, receiverType, | 2901 handlePlainAssignment(identifier, element, selector, mask, receiverType, |
2914 currentType, node.expression); | 2902 currentType, node.expression); |
2915 return handleLoop(node, () { | 2903 return handleLoop(node, () { |
2916 visit(node.body); | 2904 visit(node.body); |
2917 }); | 2905 }); |
2918 } | 2906 } |
2919 | 2907 |
2920 TypeInformation visitAsyncForIn(ast.AsyncForIn node) { | 2908 TypeInformation visitAsyncForIn(ast.AsyncForIn node) { |
2921 TypeInformation expressionType = visit(node.expression); | 2909 TypeInformation expressionType = visit(node.expression); |
2922 | 2910 |
2923 Selector currentSelector = Selectors.current; | 2911 Selector currentSelector = Selectors.current; |
2924 TypeMask currentMask = inTreeData.typeOfIteratorCurrent(node); | 2912 TypeMask currentMask = memberData.typeOfIteratorCurrent(node); |
2925 Selector moveNextSelector = Selectors.moveNext; | 2913 Selector moveNextSelector = Selectors.moveNext; |
2926 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); | 2914 TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node); |
2927 | 2915 |
2928 ConstructorElement ctor = | 2916 ConstructorElement ctor = |
2929 closedWorld.commonElements.streamIteratorConstructor; | 2917 closedWorld.commonElements.streamIteratorConstructor; |
2930 | 2918 |
2931 /// Synthesize a call to the [StreamIterator] constructor. | 2919 /// Synthesize a call to the [StreamIterator] constructor. |
2932 TypeInformation iteratorType = handleStaticSend( | 2920 TypeInformation iteratorType = handleStaticSend( |
2933 node, null, null, ctor, new ArgumentsTypes([expressionType], null)); | 2921 node, null, null, ctor, new ArgumentsTypes([expressionType], null)); |
2934 | 2922 |
2935 return handleForInLoop(node, iteratorType, currentSelector, currentMask, | 2923 return handleForInLoop(node, iteratorType, currentSelector, currentMask, |
2936 moveNextSelector, moveNextMask); | 2924 moveNextSelector, moveNextMask); |
2937 } | 2925 } |
2938 | 2926 |
2939 TypeInformation visitSyncForIn(ast.SyncForIn node) { | 2927 TypeInformation visitSyncForIn(ast.SyncForIn node) { |
2940 TypeInformation expressionType = visit(node.expression); | 2928 TypeInformation expressionType = visit(node.expression); |
2941 Selector iteratorSelector = Selectors.iterator; | 2929 Selector iteratorSelector = Selectors.iterator; |
2942 TypeMask iteratorMask = inTreeData.typeOfIterator(node); | 2930 TypeMask iteratorMask = memberData.typeOfIterator(node); |
2943 Selector currentSelector = Selectors.current; | 2931 Selector currentSelector = Selectors.current; |
2944 TypeMask currentMask = inTreeData.typeOfIteratorCurrent(node); | 2932 TypeMask currentMask = memberData.typeOfIteratorCurrent(node); |
2945 Selector moveNextSelector = Selectors.moveNext; | 2933 Selector moveNextSelector = Selectors.moveNext; |
2946 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); | 2934 TypeMask moveNextMask = memberData.typeOfIteratorMoveNext(node); |
2947 | 2935 |
2948 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, | 2936 TypeInformation iteratorType = handleDynamicSend(node, iteratorSelector, |
2949 iteratorMask, expressionType, new ArgumentsTypes.empty()); | 2937 iteratorMask, expressionType, new ArgumentsTypes.empty()); |
2950 | 2938 |
2951 return handleForInLoop(node, iteratorType, currentSelector, currentMask, | 2939 return handleForInLoop(node, iteratorType, currentSelector, currentMask, |
2952 moveNextSelector, moveNextMask); | 2940 moveNextSelector, moveNextMask); |
2953 } | 2941 } |
2954 } | 2942 } |
OLD | NEW |