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 ClosureClassMap; | 7 import '../closure.dart' show ClosureClassMap; |
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; |
11 import '../constants/values.dart' show ConstantValue, IntConstantValue; | 11 import '../constants/values.dart' show ConstantValue, IntConstantValue; |
12 import '../core_types.dart' show CoreClasses, CoreTypes; | 12 import '../core_types.dart' show CoreClasses, CoreTypes; |
13 import '../dart_types.dart' show DartType; | 13 import '../dart_types.dart' show DartType; |
14 import '../elements/elements.dart'; | 14 import '../elements/elements.dart'; |
15 import '../js_backend/backend_helpers.dart'; | 15 import '../js_backend/backend_helpers.dart'; |
16 import '../js_backend/js_backend.dart' as js; | 16 import '../js_backend/js_backend.dart' as js; |
17 import '../native/native.dart' as native; | 17 import '../native/native.dart' as native; |
18 import '../resolution/operators.dart' as op; | 18 import '../resolution/operators.dart' as op; |
19 import '../resolution/tree_elements.dart' show TreeElements; | 19 import '../resolution/tree_elements.dart' show TreeElements; |
20 import '../tree/tree.dart' as ast; | 20 import '../tree/tree.dart' as ast; |
21 import '../types/types.dart' show TypeMask; | 21 import '../types/types.dart' show TypeMask, GlobalTypeInferenceElementData; |
22 import '../universe/call_structure.dart' show CallStructure; | 22 import '../universe/call_structure.dart' show CallStructure; |
23 import '../universe/selector.dart' show Selector; | 23 import '../universe/selector.dart' show Selector; |
24 import '../universe/side_effects.dart' show SideEffects; | 24 import '../universe/side_effects.dart' show SideEffects; |
25 import '../util/util.dart' show Link, Setlet; | 25 import '../util/util.dart' show Link, Setlet; |
26 import '../world.dart' show ClosedWorld; | 26 import '../world.dart' show ClosedWorld; |
27 import 'inferrer_visitor.dart'; | 27 import 'inferrer_visitor.dart'; |
28 | 28 |
29 /** | 29 /** |
30 * Common super class used by [SimpleTypeInferrerVisitor] to propagate | 30 * Common super class used by [SimpleTypeInferrerVisitor] to propagate |
31 * type information about visited nodes, as well as to request type | 31 * type information about visited nodes, as well as to request type |
32 * information of elements. | 32 * information of elements. |
33 */ | 33 */ |
34 abstract class InferrerEngine<T, V extends TypeSystem> | 34 abstract class InferrerEngine<T, V extends TypeSystem> |
35 implements MinimalInferrerEngine<T> { | 35 implements MinimalInferrerEngine<T> { |
36 final Compiler compiler; | 36 final Compiler compiler; |
37 final ClosedWorld closedWorld; | 37 final ClosedWorld closedWorld; |
38 final V types; | 38 final V types; |
39 final Map<ast.Node, T> concreteTypes = new Map<ast.Node, T>(); | 39 final Map<ast.Node, T> concreteTypes = new Map<ast.Node, T>(); |
40 final Set<Element> generativeConstructorsExposingThis = new Set<Element>(); | 40 final Set<Element> generativeConstructorsExposingThis = new Set<Element>(); |
41 | 41 |
| 42 /// Data computed internally within elements, like the type-mask of a send a |
| 43 /// list allocation, or a for-in loop. |
| 44 final Map<Element, GlobalTypeInferenceElementData> inTreeData = |
| 45 new Map<Element, GlobalTypeInferenceElementData>(); |
| 46 |
42 InferrerEngine(Compiler compiler, this.types) | 47 InferrerEngine(Compiler compiler, this.types) |
43 : this.compiler = compiler, | 48 : this.compiler = compiler, |
44 this.closedWorld = compiler.closedWorld; | 49 this.closedWorld = compiler.closedWorld; |
45 | 50 |
46 CoreClasses get coreClasses => compiler.coreClasses; | 51 CoreClasses get coreClasses => compiler.coreClasses; |
47 | 52 |
48 CoreTypes get coreTypes => compiler.coreTypes; | 53 CoreTypes get coreTypes => compiler.coreTypes; |
49 | 54 |
50 /** | 55 /** |
51 * Records the default type of parameter [parameter]. | 56 * Records the default type of parameter [parameter]. |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
174 */ | 179 */ |
175 void forEachElementMatching( | 180 void forEachElementMatching( |
176 Selector selector, TypeMask mask, bool f(Element element)) { | 181 Selector selector, TypeMask mask, bool f(Element element)) { |
177 Iterable<Element> elements = | 182 Iterable<Element> elements = |
178 compiler.closedWorld.allFunctions.filter(selector, mask); | 183 compiler.closedWorld.allFunctions.filter(selector, mask); |
179 for (Element e in elements) { | 184 for (Element e in elements) { |
180 if (!f(e.implementation)) return; | 185 if (!f(e.implementation)) return; |
181 } | 186 } |
182 } | 187 } |
183 | 188 |
| 189 GlobalTypeInferenceElementData _dataOf(AstElement element) => inTreeData |
| 190 .putIfAbsent(element, () => new GlobalTypeInferenceElementData()); |
| 191 |
184 /** | 192 /** |
185 * Update [sideEffects] with the side effects of [callee] being | 193 * Update [sideEffects] with the side effects of [callee] being |
186 * called with [selector]. | 194 * called with [selector]. |
187 */ | 195 */ |
188 void updateSideEffects( | 196 void updateSideEffects( |
189 SideEffects sideEffects, Selector selector, Element callee) { | 197 SideEffects sideEffects, Selector selector, Element callee) { |
190 if (callee.isField) { | 198 if (callee.isField) { |
191 if (callee.isInstanceMember) { | 199 if (callee.isInstanceMember) { |
192 if (selector.isSetter) { | 200 if (selector.isSetter) { |
193 sideEffects.setChangesInstanceProperty(); | 201 sideEffects.setChangesInstanceProperty(); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 break; | 262 break; |
255 } | 263 } |
256 } | 264 } |
257 return returnType; | 265 return returnType; |
258 } | 266 } |
259 | 267 |
260 // TODO(johnniwinther): Pass the [ResolvedAst] instead of [owner]. | 268 // TODO(johnniwinther): Pass the [ResolvedAst] instead of [owner]. |
261 void updateSelectorInTree( | 269 void updateSelectorInTree( |
262 AstElement owner, Spannable node, Selector selector, TypeMask mask) { | 270 AstElement owner, Spannable node, Selector selector, TypeMask mask) { |
263 ast.Node astNode = node; | 271 ast.Node astNode = node; |
264 TreeElements elements = owner.resolvedAst.elements; | 272 GlobalTypeInferenceElementData data = _dataOf(owner); |
265 if (astNode.asSendSet() != null) { | 273 if (astNode.asSendSet() != null) { |
266 if (selector.isSetter || selector.isIndexSet) { | 274 if (selector.isSetter || selector.isIndexSet) { |
267 elements.setTypeMask(node, mask); | 275 data.setTypeMask(node, mask); |
268 } else if (selector.isGetter || selector.isIndex) { | 276 } else if (selector.isGetter || selector.isIndex) { |
269 elements.setGetterTypeMaskInComplexSendSet(node, mask); | 277 data.setGetterTypeMaskInComplexSendSet(node, mask); |
270 } else { | 278 } else { |
271 assert(selector.isOperator); | 279 assert(selector.isOperator); |
272 elements.setOperatorTypeMaskInComplexSendSet(node, mask); | 280 data.setOperatorTypeMaskInComplexSendSet(node, mask); |
273 } | 281 } |
274 } else if (astNode.asSend() != null) { | 282 } else if (astNode.asSend() != null) { |
275 elements.setTypeMask(node, mask); | 283 data.setTypeMask(node, mask); |
276 } else { | 284 } else { |
277 assert(astNode.asForIn() != null); | 285 assert(astNode.asForIn() != null); |
278 if (selector == Selectors.iterator) { | 286 if (selector == Selectors.iterator) { |
279 elements.setIteratorTypeMask(node, mask); | 287 data.setIteratorTypeMask(node, mask); |
280 } else if (selector == Selectors.current) { | 288 } else if (selector == Selectors.current) { |
281 elements.setCurrentTypeMask(node, mask); | 289 data.setCurrentTypeMask(node, mask); |
282 } else { | 290 } else { |
283 assert(selector == Selectors.moveNext); | 291 assert(selector == Selectors.moveNext); |
284 elements.setMoveNextTypeMask(node, mask); | 292 data.setMoveNextTypeMask(node, mask); |
285 } | 293 } |
286 } | 294 } |
287 } | 295 } |
288 | 296 |
289 bool isNativeElement(Element element) { | 297 bool isNativeElement(Element element) { |
290 return compiler.backend.isNative(element); | 298 return compiler.backend.isNative(element); |
291 } | 299 } |
292 | 300 |
293 void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments); | 301 void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments); |
294 | 302 |
(...skipping 22 matching lines...) Expand all Loading... |
317 class SimpleTypeInferrerVisitor<T> | 325 class SimpleTypeInferrerVisitor<T> |
318 extends InferrerVisitor<T, InferrerEngine<T, TypeSystem<T>>> { | 326 extends InferrerVisitor<T, InferrerEngine<T, TypeSystem<T>>> { |
319 T returnType; | 327 T returnType; |
320 bool visitingInitializers = false; | 328 bool visitingInitializers = false; |
321 bool isConstructorRedirect = false; | 329 bool isConstructorRedirect = false; |
322 bool seenSuperConstructorCall = false; | 330 bool seenSuperConstructorCall = false; |
323 SideEffects sideEffects = new SideEffects.empty(); | 331 SideEffects sideEffects = new SideEffects.empty(); |
324 final Element outermostElement; | 332 final Element outermostElement; |
325 final InferrerEngine<T, TypeSystem<T>> inferrer; | 333 final InferrerEngine<T, TypeSystem<T>> inferrer; |
326 final Setlet<Entity> capturedVariables = new Setlet<Entity>(); | 334 final Setlet<Entity> capturedVariables = new Setlet<Entity>(); |
| 335 final GlobalTypeInferenceElementData inTreeData; |
327 | 336 |
328 SimpleTypeInferrerVisitor.internal( | 337 SimpleTypeInferrerVisitor.internal( |
329 AstElement analyzedElement, | 338 AstElement analyzedElement, |
330 ResolvedAst resolvedAst, | 339 ResolvedAst resolvedAst, |
331 this.outermostElement, | 340 this.outermostElement, |
332 inferrer, | 341 inferrer, |
333 compiler, | 342 compiler, |
334 locals) | 343 locals) |
335 : super(analyzedElement, resolvedAst, inferrer, inferrer.types, compiler, | 344 : super(analyzedElement, resolvedAst, inferrer, inferrer.types, compiler, |
336 locals), | 345 locals), |
337 this.inferrer = inferrer { | 346 this.inferrer = inferrer, |
| 347 this.inTreeData = inferrer._dataOf(analyzedElement) { |
338 assert(outermostElement != null); | 348 assert(outermostElement != null); |
339 } | 349 } |
340 | 350 |
341 SimpleTypeInferrerVisitor(Element element, ResolvedAst resolvedAst, | 351 SimpleTypeInferrerVisitor(Element element, ResolvedAst resolvedAst, |
342 Compiler compiler, InferrerEngine<T, TypeSystem<T>> inferrer, | 352 Compiler compiler, InferrerEngine<T, TypeSystem<T>> inferrer, |
343 [LocalsHandler<T> handler]) | 353 [LocalsHandler<T> handler]) |
344 : this.internal( | 354 : this.internal( |
345 element, | 355 element, |
346 resolvedAst, | 356 resolvedAst, |
347 element.outermostEnclosingMemberOrTopLevel.implementation, | 357 element.outermostEnclosingMemberOrTopLevel.implementation, |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 | 696 |
687 @override | 697 @override |
688 T handleSendSet(ast.SendSet node) { | 698 T handleSendSet(ast.SendSet node) { |
689 Element element = elements[node]; | 699 Element element = elements[node]; |
690 if (!Elements.isUnresolved(element) && element.impliesType) { | 700 if (!Elements.isUnresolved(element) && element.impliesType) { |
691 node.visitChildren(this); | 701 node.visitChildren(this); |
692 return types.dynamicType; | 702 return types.dynamicType; |
693 } | 703 } |
694 | 704 |
695 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); | 705 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
696 TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node); | 706 TypeMask getterMask = inTreeData.typeOfGetter(node); |
697 TypeMask operatorMask = elements.getOperatorTypeMaskInComplexSendSet(node); | 707 TypeMask operatorMask = inTreeData.typeOfOperator(node); |
698 Selector setterSelector = elements.getSelector(node); | 708 Selector setterSelector = elements.getSelector(node); |
699 TypeMask setterMask = elements.getTypeMask(node); | 709 TypeMask setterMask = inTreeData.typeOfSend(node); |
700 | 710 |
701 String op = node.assignmentOperator.source; | 711 String op = node.assignmentOperator.source; |
702 bool isIncrementOrDecrement = op == '++' || op == '--'; | 712 bool isIncrementOrDecrement = op == '++' || op == '--'; |
703 | 713 |
704 T receiverType; | 714 T receiverType; |
705 bool isCallOnThis = false; | 715 bool isCallOnThis = false; |
706 if (node.receiver == null) { | 716 if (node.receiver == null) { |
707 if (treatAsInstanceMember(element)) { | 717 if (treatAsInstanceMember(element)) { |
708 receiverType = thisType; | 718 receiverType = thisType; |
709 isCallOnThis = true; | 719 isCallOnThis = true; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 } | 809 } |
800 | 810 |
801 return node.isPostfix ? getterType : newType; | 811 return node.isPostfix ? getterType : newType; |
802 } | 812 } |
803 } | 813 } |
804 | 814 |
805 /// Handle compound index set, like `foo[0] += 42` or `foo[0]++`. | 815 /// Handle compound index set, like `foo[0] += 42` or `foo[0]++`. |
806 T handleCompoundIndexSet( | 816 T handleCompoundIndexSet( |
807 ast.SendSet node, T receiverType, T indexType, T rhsType) { | 817 ast.SendSet node, T receiverType, T indexType, T rhsType) { |
808 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); | 818 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
809 TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node); | 819 |
| 820 TypeMask getterMask = inTreeData.typeOfGetter(node); |
810 Selector operatorSelector = | 821 Selector operatorSelector = |
811 elements.getOperatorSelectorInComplexSendSet(node); | 822 elements.getOperatorSelectorInComplexSendSet(node); |
812 TypeMask operatorMask = elements.getOperatorTypeMaskInComplexSendSet(node); | 823 TypeMask operatorMask = inTreeData.typeOfOperator(node); |
813 Selector setterSelector = elements.getSelector(node); | 824 Selector setterSelector = elements.getSelector(node); |
814 TypeMask setterMask = elements.getTypeMask(node); | 825 TypeMask setterMask = inTreeData.typeOfSend(node); |
815 | 826 |
816 T getterType = handleDynamicSend(node, getterSelector, getterMask, | 827 T getterType = handleDynamicSend(node, getterSelector, getterMask, |
817 receiverType, new ArgumentsTypes<T>([indexType], null)); | 828 receiverType, new ArgumentsTypes<T>([indexType], null)); |
818 | 829 |
819 T returnType; | 830 T returnType; |
820 if (node.isIfNullAssignment) { | 831 if (node.isIfNullAssignment) { |
821 returnType = types.allocateDiamondPhi(getterType, rhsType); | 832 returnType = types.allocateDiamondPhi(getterType, rhsType); |
822 } else { | 833 } else { |
823 returnType = handleDynamicSend(node, operatorSelector, operatorMask, | 834 returnType = handleDynamicSend(node, operatorSelector, operatorMask, |
824 getterType, new ArgumentsTypes<T>([rhsType], null)); | 835 getterType, new ArgumentsTypes<T>([rhsType], null)); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 Element setter, ast.Node index, ast.Node rhs) { | 910 Element setter, ast.Node index, ast.Node rhs) { |
900 T indexType = visit(index); | 911 T indexType = visit(index); |
901 T rhsType = visit(rhs); | 912 T rhsType = visit(rhs); |
902 return _handleSuperCompoundIndexSet( | 913 return _handleSuperCompoundIndexSet( |
903 node, getter, setter, indexType, rhsType); | 914 node, getter, setter, indexType, rhsType); |
904 } | 915 } |
905 | 916 |
906 T _handleSuperCompoundIndexSet(ast.SendSet node, Element getter, | 917 T _handleSuperCompoundIndexSet(ast.SendSet node, Element getter, |
907 Element setter, T indexType, T rhsType) { | 918 Element setter, T indexType, T rhsType) { |
908 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); | 919 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
909 TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node); | 920 |
| 921 TypeMask getterMask = inTreeData.typeOfGetter(node); |
910 Selector setterSelector = elements.getSelector(node); | 922 Selector setterSelector = elements.getSelector(node); |
911 TypeMask setterMask = elements.getTypeMask(node); | 923 TypeMask setterMask = inTreeData.typeOfSend(node); |
912 | 924 |
913 T getterType = handleSuperSend(node, getterSelector, getterMask, getter, | 925 T getterType = handleSuperSend(node, getterSelector, getterMask, getter, |
914 new ArgumentsTypes<T>([indexType], null)); | 926 new ArgumentsTypes<T>([indexType], null)); |
915 | 927 |
916 T returnType; | 928 T returnType; |
917 if (node.isIfNullAssignment) { | 929 if (node.isIfNullAssignment) { |
918 returnType = types.allocateDiamondPhi(getterType, rhsType); | 930 returnType = types.allocateDiamondPhi(getterType, rhsType); |
919 } else { | 931 } else { |
920 Selector operatorSelector = | 932 Selector operatorSelector = |
921 elements.getOperatorSelectorInComplexSendSet(node); | 933 elements.getOperatorSelectorInComplexSendSet(node); |
922 TypeMask operatorMask = | 934 TypeMask operatorMask = inTreeData.typeOfOperator(node); |
923 elements.getOperatorTypeMaskInComplexSendSet(node); | |
924 returnType = handleDynamicSend(node, operatorSelector, operatorMask, | 935 returnType = handleDynamicSend(node, operatorSelector, operatorMask, |
925 getterType, new ArgumentsTypes<T>([rhsType], null)); | 936 getterType, new ArgumentsTypes<T>([rhsType], null)); |
926 } | 937 } |
927 handleSuperSend(node, setterSelector, setterMask, setter, | 938 handleSuperSend(node, setterSelector, setterMask, setter, |
928 new ArgumentsTypes<T>([indexType, returnType], null)); | 939 new ArgumentsTypes<T>([indexType, returnType], null)); |
929 | 940 |
930 return node.isPostfix ? getterType : returnType; | 941 return node.isPostfix ? getterType : returnType; |
931 } | 942 } |
932 | 943 |
933 T handleSuperSend(ast.Node node, Selector selector, TypeMask mask, | 944 T handleSuperSend(ast.Node node, Selector selector, TypeMask mask, |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 return handleSuperPrefixPostfix(node, getter, setter); | 1272 return handleSuperPrefixPostfix(node, getter, setter); |
1262 } | 1273 } |
1263 | 1274 |
1264 T handleSuperPrefixPostfix(ast.SendSet node, Element getter, Element setter) { | 1275 T handleSuperPrefixPostfix(ast.SendSet node, Element getter, Element setter) { |
1265 return _handleSuperCompound(node, getter, setter, types.uint31Type); | 1276 return _handleSuperCompound(node, getter, setter, types.uint31Type); |
1266 } | 1277 } |
1267 | 1278 |
1268 T _handleSuperCompound( | 1279 T _handleSuperCompound( |
1269 ast.SendSet node, Element getter, Element setter, T rhsType) { | 1280 ast.SendSet node, Element getter, Element setter, T rhsType) { |
1270 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); | 1281 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node); |
1271 TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node); | 1282 TypeMask getterMask = inTreeData.typeOfGetter(node); |
1272 Selector setterSelector = elements.getSelector(node); | 1283 Selector setterSelector = elements.getSelector(node); |
1273 TypeMask setterMask = elements.getTypeMask(node); | 1284 TypeMask setterMask = inTreeData.typeOfSend(node); |
1274 | 1285 |
1275 T getterType = | 1286 T getterType = |
1276 handleSuperSend(node, getterSelector, getterMask, getter, null); | 1287 handleSuperSend(node, getterSelector, getterMask, getter, null); |
1277 | 1288 |
1278 T returnType; | 1289 T returnType; |
1279 if (node.isIfNullAssignment) { | 1290 if (node.isIfNullAssignment) { |
1280 returnType = types.allocateDiamondPhi(getterType, rhsType); | 1291 returnType = types.allocateDiamondPhi(getterType, rhsType); |
1281 } else { | 1292 } else { |
1282 Selector operatorSelector = | 1293 Selector operatorSelector = |
1283 elements.getOperatorSelectorInComplexSendSet(node); | 1294 elements.getOperatorSelectorInComplexSendSet(node); |
1284 TypeMask operatorMask = | 1295 TypeMask operatorMask = inTreeData.typeOfOperator(node); |
1285 elements.getOperatorTypeMaskInComplexSendSet(node); | |
1286 returnType = handleDynamicSend(node, operatorSelector, operatorMask, | 1296 returnType = handleDynamicSend(node, operatorSelector, operatorMask, |
1287 getterType, new ArgumentsTypes<T>([rhsType], null)); | 1297 getterType, new ArgumentsTypes<T>([rhsType], null)); |
1288 } | 1298 } |
1289 handleSuperSend(node, setterSelector, setterMask, setter, | 1299 handleSuperSend(node, setterSelector, setterMask, setter, |
1290 new ArgumentsTypes<T>([returnType], null)); | 1300 new ArgumentsTypes<T>([returnType], null)); |
1291 | 1301 |
1292 return node.isPostfix ? getterType : returnType; | 1302 return node.isPostfix ? getterType : returnType; |
1293 } | 1303 } |
1294 | 1304 |
1295 /// Handle index set, like `foo[0] = 42`. | 1305 /// Handle index set, like `foo[0] = 42`. |
1296 T handleIndexSet(ast.SendSet node, T receiverType, T indexType, T rhsType) { | 1306 T handleIndexSet(ast.SendSet node, T receiverType, T indexType, T rhsType) { |
1297 Selector setterSelector = elements.getSelector(node); | 1307 Selector setterSelector = elements.getSelector(node); |
1298 TypeMask setterMask = elements.getTypeMask(node); | 1308 TypeMask setterMask = inTreeData.typeOfSend(node); |
1299 handleDynamicSend(node, setterSelector, setterMask, receiverType, | 1309 handleDynamicSend(node, setterSelector, setterMask, receiverType, |
1300 new ArgumentsTypes<T>([indexType, rhsType], null)); | 1310 new ArgumentsTypes<T>([indexType, rhsType], null)); |
1301 return rhsType; | 1311 return rhsType; |
1302 } | 1312 } |
1303 | 1313 |
1304 @override | 1314 @override |
1305 T visitIndexSet( | 1315 T visitIndexSet( |
1306 ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) { | 1316 ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) { |
1307 T receiverType = visit(receiver); | 1317 T receiverType = visit(receiver); |
1308 T indexType = visit(index); | 1318 T indexType = visit(index); |
1309 T rhsType = visit(rhs); | 1319 T rhsType = visit(rhs); |
1310 return handleIndexSet(node, receiverType, indexType, rhsType); | 1320 return handleIndexSet(node, receiverType, indexType, rhsType); |
1311 } | 1321 } |
1312 | 1322 |
1313 /// Handle super index set, like `super[42] = true`. | 1323 /// Handle super index set, like `super[42] = true`. |
1314 T handleSuperIndexSet( | 1324 T handleSuperIndexSet( |
1315 ast.SendSet node, Element element, ast.Node index, ast.Node rhs) { | 1325 ast.SendSet node, Element element, ast.Node index, ast.Node rhs) { |
1316 T indexType = visit(index); | 1326 T indexType = visit(index); |
1317 T rhsType = visit(rhs); | 1327 T rhsType = visit(rhs); |
1318 Selector setterSelector = elements.getSelector(node); | 1328 Selector setterSelector = elements.getSelector(node); |
1319 TypeMask setterMask = elements.getTypeMask(node); | 1329 TypeMask setterMask = inTreeData.typeOfSend(node); |
1320 handleStaticSend(node, setterSelector, setterMask, element, | 1330 handleStaticSend(node, setterSelector, setterMask, element, |
1321 new ArgumentsTypes<T>([indexType, rhsType], null)); | 1331 new ArgumentsTypes<T>([indexType, rhsType], null)); |
1322 return rhsType; | 1332 return rhsType; |
1323 } | 1333 } |
1324 | 1334 |
1325 @override | 1335 @override |
1326 T visitSuperIndexSet(ast.SendSet node, FunctionElement function, | 1336 T visitSuperIndexSet(ast.SendSet node, FunctionElement function, |
1327 ast.Node index, ast.Node rhs, _) { | 1337 ast.Node index, ast.Node rhs, _) { |
1328 return handleSuperIndexSet(node, function, index, rhs); | 1338 return handleSuperIndexSet(node, function, index, rhs); |
1329 } | 1339 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1385 locals.update(element, rhsType, node); | 1395 locals.update(element, rhsType, node); |
1386 } | 1396 } |
1387 return rhsType; | 1397 return rhsType; |
1388 } | 1398 } |
1389 | 1399 |
1390 /// Handle a super access or invocation that results in a `noSuchMethod` call. | 1400 /// Handle a super access or invocation that results in a `noSuchMethod` call. |
1391 T handleErroneousSuperSend(ast.Send node) { | 1401 T handleErroneousSuperSend(ast.Send node) { |
1392 ArgumentsTypes arguments = | 1402 ArgumentsTypes arguments = |
1393 node.isPropertyAccess ? null : analyzeArguments(node.arguments); | 1403 node.isPropertyAccess ? null : analyzeArguments(node.arguments); |
1394 Selector selector = elements.getSelector(node); | 1404 Selector selector = elements.getSelector(node); |
1395 TypeMask mask = elements.getTypeMask(node); | 1405 TypeMask mask = inTreeData.typeOfSend(node); |
1396 // TODO(herhut): We could do better here if we knew what we | 1406 // TODO(herhut): We could do better here if we knew what we |
1397 // are calling does not expose this. | 1407 // are calling does not expose this. |
1398 // TODO(johnniwinther): Do we still need this when calling directly? | 1408 // TODO(johnniwinther): Do we still need this when calling directly? |
1399 isThisExposed = true; | 1409 isThisExposed = true; |
1400 return handleSuperNoSuchMethod(node, selector, mask, arguments); | 1410 return handleSuperNoSuchMethod(node, selector, mask, arguments); |
1401 } | 1411 } |
1402 | 1412 |
1403 T handleSuperNoSuchMethod(ast.Send node, Selector selector, TypeMask mask, | 1413 T handleSuperNoSuchMethod(ast.Send node, Selector selector, TypeMask mask, |
1404 ArgumentsTypes arguments) { | 1414 ArgumentsTypes arguments) { |
1405 // Ensure we create a node, to make explicit the call to the | 1415 // Ensure we create a node, to make explicit the call to the |
1406 // `noSuchMethod` handler. | 1416 // `noSuchMethod` handler. |
1407 ClassElement cls = outermostElement.enclosingClass.declaration; | 1417 ClassElement cls = outermostElement.enclosingClass.declaration; |
1408 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); | 1418 MethodElement element = cls.lookupSuperMember(Identifiers.noSuchMethod_); |
1409 if (!Selectors.noSuchMethod_.signatureApplies(element)) { | 1419 if (!Selectors.noSuchMethod_.signatureApplies(element)) { |
1410 element = compiler.coreClasses.objectClass | 1420 element = compiler.coreClasses.objectClass |
1411 .lookupMember(Identifiers.noSuchMethod_); | 1421 .lookupMember(Identifiers.noSuchMethod_); |
1412 } | 1422 } |
1413 return handleStaticSend(node, selector, mask, element, arguments); | 1423 return handleStaticSend(node, selector, mask, element, arguments); |
1414 } | 1424 } |
1415 | 1425 |
1416 /// Handle a .call invocation on the values retrieved from the super | 1426 /// Handle a .call invocation on the values retrieved from the super |
1417 /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter. | 1427 /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter. |
1418 T handleSuperClosureCall( | 1428 T handleSuperClosureCall( |
1419 ast.Send node, Element element, ast.NodeList arguments) { | 1429 ast.Send node, Element element, ast.NodeList arguments) { |
1420 ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes); | 1430 ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes); |
1421 Selector selector = elements.getSelector(node); | 1431 Selector selector = elements.getSelector(node); |
1422 TypeMask mask = elements.getTypeMask(node); | 1432 TypeMask mask = inTreeData.typeOfSend(node); |
1423 // TODO(herhut): We could do better here if we knew what we | 1433 // TODO(herhut): We could do better here if we knew what we |
1424 // are calling does not expose this. | 1434 // are calling does not expose this. |
1425 isThisExposed = true; | 1435 isThisExposed = true; |
1426 return inferrer.registerCalledClosure( | 1436 return inferrer.registerCalledClosure( |
1427 node, | 1437 node, |
1428 selector, | 1438 selector, |
1429 mask, | 1439 mask, |
1430 inferrer.typeOfElement(element), | 1440 inferrer.typeOfElement(element), |
1431 outermostElement, | 1441 outermostElement, |
1432 argumentTypes, | 1442 argumentTypes, |
1433 sideEffects, | 1443 sideEffects, |
1434 inLoop); | 1444 inLoop); |
1435 } | 1445 } |
1436 | 1446 |
1437 /// Handle an invocation of super [method]. | 1447 /// Handle an invocation of super [method]. |
1438 T handleSuperMethodInvoke( | 1448 T handleSuperMethodInvoke( |
1439 ast.Send node, MethodElement method, ArgumentsTypes arguments) { | 1449 ast.Send node, MethodElement method, ArgumentsTypes arguments) { |
1440 // TODO(herhut): We could do better here if we knew what we | 1450 // TODO(herhut): We could do better here if we knew what we |
1441 // are calling does not expose this. | 1451 // are calling does not expose this. |
1442 isThisExposed = true; | 1452 isThisExposed = true; |
1443 Selector selector = elements.getSelector(node); | 1453 Selector selector = elements.getSelector(node); |
1444 TypeMask mask = elements.getTypeMask(node); | 1454 TypeMask mask = inTreeData.typeOfSend(node); |
1445 return handleStaticSend(node, selector, mask, method, arguments); | 1455 return handleStaticSend(node, selector, mask, method, arguments); |
1446 } | 1456 } |
1447 | 1457 |
1448 /// Handle access to a super field or getter [element]. | 1458 /// Handle access to a super field or getter [element]. |
1449 T handleSuperGet(ast.Send node, Element element) { | 1459 T handleSuperGet(ast.Send node, Element element) { |
1450 // TODO(herhut): We could do better here if we knew what we | 1460 // TODO(herhut): We could do better here if we knew what we |
1451 // are calling does not expose this. | 1461 // are calling does not expose this. |
1452 isThisExposed = true; | 1462 isThisExposed = true; |
1453 Selector selector = elements.getSelector(node); | 1463 Selector selector = elements.getSelector(node); |
1454 TypeMask mask = elements.getTypeMask(node); | 1464 TypeMask mask = inTreeData.typeOfSend(node); |
1455 return handleStaticSend(node, selector, mask, element, null); | 1465 return handleStaticSend(node, selector, mask, element, null); |
1456 } | 1466 } |
1457 | 1467 |
1458 /// Handle update to a super field or setter [element]. | 1468 /// Handle update to a super field or setter [element]. |
1459 T handleSuperSet(ast.Send node, Element element, ast.Node rhs) { | 1469 T handleSuperSet(ast.Send node, Element element, ast.Node rhs) { |
1460 T rhsType = visit(rhs); | 1470 T rhsType = visit(rhs); |
1461 // TODO(herhut): We could do better here if we knew what we | 1471 // TODO(herhut): We could do better here if we knew what we |
1462 // are calling does not expose this. | 1472 // are calling does not expose this. |
1463 isThisExposed = true; | 1473 isThisExposed = true; |
1464 Selector selector = elements.getSelector(node); | 1474 Selector selector = elements.getSelector(node); |
1465 TypeMask mask = elements.getTypeMask(node); | 1475 TypeMask mask = inTreeData.typeOfSend(node); |
1466 return handleStaticSend( | 1476 return handleStaticSend( |
1467 node, selector, mask, element, new ArgumentsTypes<T>([rhsType], null)); | 1477 node, selector, mask, element, new ArgumentsTypes<T>([rhsType], null)); |
1468 } | 1478 } |
1469 | 1479 |
1470 @override | 1480 @override |
1471 T visitSuperFieldSet(ast.Send node, FieldElement method, ast.Node rhs, _) { | 1481 T visitSuperFieldSet(ast.Send node, FieldElement method, ast.Node rhs, _) { |
1472 return handleSuperSet(node, method, rhs); | 1482 return handleSuperSet(node, method, rhs); |
1473 } | 1483 } |
1474 | 1484 |
1475 @override | 1485 @override |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1667 // forward the call to the effective target of the factory. | 1677 // forward the call to the effective target of the factory. |
1668 // TODO(herhut): Remove the loop once effectiveTarget forwards to patches. | 1678 // TODO(herhut): Remove the loop once effectiveTarget forwards to patches. |
1669 while (target.isFactoryConstructor) { | 1679 while (target.isFactoryConstructor) { |
1670 if (!target.isRedirectingFactory) break; | 1680 if (!target.isRedirectingFactory) break; |
1671 target = target.effectiveTarget.implementation; | 1681 target = target.effectiveTarget.implementation; |
1672 } | 1682 } |
1673 if (compiler.backend.isForeign(target)) { | 1683 if (compiler.backend.isForeign(target)) { |
1674 return handleForeignSend(node, target); | 1684 return handleForeignSend(node, target); |
1675 } | 1685 } |
1676 Selector selector = elements.getSelector(node); | 1686 Selector selector = elements.getSelector(node); |
1677 TypeMask mask = elements.getTypeMask(node); | 1687 TypeMask mask = inTreeData.typeOfSend(node); |
1678 // In erroneous code the number of arguments in the selector might not | 1688 // In erroneous code the number of arguments in the selector might not |
1679 // match the function element. | 1689 // match the function element. |
1680 // TODO(polux): return nonNullEmpty and check it doesn't break anything | 1690 // TODO(polux): return nonNullEmpty and check it doesn't break anything |
1681 if (!selector.applies(target) || | 1691 if (!selector.applies(target) || |
1682 (mask != null && | 1692 (mask != null && |
1683 !mask.canHit(target, selector, compiler.closedWorld))) { | 1693 !mask.canHit(target, selector, compiler.closedWorld))) { |
1684 return types.dynamicType; | 1694 return types.dynamicType; |
1685 } | 1695 } |
1686 | 1696 |
1687 T returnType = handleStaticSend(node, selector, mask, target, arguments); | 1697 T returnType = handleStaticSend(node, selector, mask, target, arguments); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1726 @override | 1736 @override |
1727 T errorNonConstantConstructorInvoke(ast.NewExpression node, Element element, | 1737 T errorNonConstantConstructorInvoke(ast.NewExpression node, Element element, |
1728 DartType type, ast.NodeList arguments, CallStructure callStructure, _) { | 1738 DartType type, ast.NodeList arguments, CallStructure callStructure, _) { |
1729 return bulkHandleNew(node, _); | 1739 return bulkHandleNew(node, _); |
1730 } | 1740 } |
1731 | 1741 |
1732 /// Handle invocation of a top level or static field or getter [element]. | 1742 /// Handle invocation of a top level or static field or getter [element]. |
1733 T handleStaticFieldOrGetterInvoke(ast.Send node, Element element) { | 1743 T handleStaticFieldOrGetterInvoke(ast.Send node, Element element) { |
1734 ArgumentsTypes arguments = analyzeArguments(node.arguments); | 1744 ArgumentsTypes arguments = analyzeArguments(node.arguments); |
1735 Selector selector = elements.getSelector(node); | 1745 Selector selector = elements.getSelector(node); |
1736 TypeMask mask = elements.getTypeMask(node); | 1746 TypeMask mask = inTreeData.typeOfSend(node); |
1737 handleStaticSend(node, selector, mask, element, arguments); | 1747 handleStaticSend(node, selector, mask, element, arguments); |
1738 return inferrer.registerCalledClosure( | 1748 return inferrer.registerCalledClosure( |
1739 node, | 1749 node, |
1740 selector, | 1750 selector, |
1741 mask, | 1751 mask, |
1742 inferrer.typeOfElement(element), | 1752 inferrer.typeOfElement(element), |
1743 outermostElement, | 1753 outermostElement, |
1744 arguments, | 1754 arguments, |
1745 sideEffects, | 1755 sideEffects, |
1746 inLoop); | 1756 inLoop); |
1747 } | 1757 } |
1748 | 1758 |
1749 /// Handle invocation of a top level or static [function]. | 1759 /// Handle invocation of a top level or static [function]. |
1750 T handleStaticFunctionInvoke(ast.Send node, MethodElement function) { | 1760 T handleStaticFunctionInvoke(ast.Send node, MethodElement function) { |
1751 if (compiler.backend.isForeign(function)) { | 1761 if (compiler.backend.isForeign(function)) { |
1752 return handleForeignSend(node, function); | 1762 return handleForeignSend(node, function); |
1753 } | 1763 } |
1754 ArgumentsTypes arguments = analyzeArguments(node.arguments); | 1764 ArgumentsTypes arguments = analyzeArguments(node.arguments); |
1755 Selector selector = elements.getSelector(node); | 1765 Selector selector = elements.getSelector(node); |
1756 TypeMask mask = elements.getTypeMask(node); | 1766 TypeMask mask = inTreeData.typeOfSend(node); |
1757 return handleStaticSend(node, selector, mask, function, arguments); | 1767 return handleStaticSend(node, selector, mask, function, arguments); |
1758 } | 1768 } |
1759 | 1769 |
1760 /// Handle an static invocation of an unresolved target or with incompatible | 1770 /// Handle an static invocation of an unresolved target or with incompatible |
1761 /// arguments to a resolved target. | 1771 /// arguments to a resolved target. |
1762 T handleInvalidStaticInvoke(ast.Send node) { | 1772 T handleInvalidStaticInvoke(ast.Send node) { |
1763 analyzeArguments(node.arguments); | 1773 analyzeArguments(node.arguments); |
1764 return types.dynamicType; | 1774 return types.dynamicType; |
1765 } | 1775 } |
1766 | 1776 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1830 | 1840 |
1831 @override | 1841 @override |
1832 T visitUnresolvedInvoke(ast.Send node, Element element, | 1842 T visitUnresolvedInvoke(ast.Send node, Element element, |
1833 ast.NodeList arguments, Selector selector, _) { | 1843 ast.NodeList arguments, Selector selector, _) { |
1834 return handleInvalidStaticInvoke(node); | 1844 return handleInvalidStaticInvoke(node); |
1835 } | 1845 } |
1836 | 1846 |
1837 T handleForeignSend(ast.Send node, Element element) { | 1847 T handleForeignSend(ast.Send node, Element element) { |
1838 ArgumentsTypes arguments = analyzeArguments(node.arguments); | 1848 ArgumentsTypes arguments = analyzeArguments(node.arguments); |
1839 Selector selector = elements.getSelector(node); | 1849 Selector selector = elements.getSelector(node); |
1840 TypeMask mask = elements.getTypeMask(node); | 1850 TypeMask mask = inTreeData.typeOfSend(node); |
1841 String name = element.name; | 1851 String name = element.name; |
1842 handleStaticSend(node, selector, mask, element, arguments); | 1852 handleStaticSend(node, selector, mask, element, arguments); |
1843 if (name == BackendHelpers.JS || | 1853 if (name == BackendHelpers.JS || |
1844 name == BackendHelpers.JS_EMBEDDED_GLOBAL || | 1854 name == BackendHelpers.JS_EMBEDDED_GLOBAL || |
1845 name == BackendHelpers.JS_BUILTIN) { | 1855 name == BackendHelpers.JS_BUILTIN) { |
1846 native.NativeBehavior nativeBehavior = elements.getNativeData(node); | 1856 native.NativeBehavior nativeBehavior = elements.getNativeData(node); |
1847 sideEffects.add(nativeBehavior.sideEffects); | 1857 sideEffects.add(nativeBehavior.sideEffects); |
1848 return inferrer.typeOfNativeBehavior(nativeBehavior); | 1858 return inferrer.typeOfNativeBehavior(nativeBehavior); |
1849 } else if (name == 'JS_OPERATOR_AS_PREFIX' || name == 'JS_STRING_CONCAT') { | 1859 } else if (name == 'JS_OPERATOR_AS_PREFIX' || name == 'JS_STRING_CONCAT') { |
1850 return types.stringType; | 1860 return types.stringType; |
(...skipping 24 matching lines...) Expand all Loading... |
1875 | 1885 |
1876 /// Read a local variable, function or parameter. | 1886 /// Read a local variable, function or parameter. |
1877 T handleLocalGet(ast.Send node, LocalElement local) { | 1887 T handleLocalGet(ast.Send node, LocalElement local) { |
1878 assert(locals.use(local) != null); | 1888 assert(locals.use(local) != null); |
1879 return locals.use(local); | 1889 return locals.use(local); |
1880 } | 1890 } |
1881 | 1891 |
1882 /// Read a static or top level field. | 1892 /// Read a static or top level field. |
1883 T handleStaticFieldGet(ast.Send node, FieldElement field) { | 1893 T handleStaticFieldGet(ast.Send node, FieldElement field) { |
1884 Selector selector = elements.getSelector(node); | 1894 Selector selector = elements.getSelector(node); |
1885 TypeMask mask = elements.getTypeMask(node); | 1895 TypeMask mask = inTreeData.typeOfSend(node); |
1886 return handleStaticSend(node, selector, mask, field, null); | 1896 return handleStaticSend(node, selector, mask, field, null); |
1887 } | 1897 } |
1888 | 1898 |
1889 /// Invoke a static or top level getter. | 1899 /// Invoke a static or top level getter. |
1890 T handleStaticGetterGet(ast.Send node, MethodElement getter) { | 1900 T handleStaticGetterGet(ast.Send node, MethodElement getter) { |
1891 Selector selector = elements.getSelector(node); | 1901 Selector selector = elements.getSelector(node); |
1892 TypeMask mask = elements.getTypeMask(node); | 1902 TypeMask mask = inTreeData.typeOfSend(node); |
1893 return handleStaticSend(node, selector, mask, getter, null); | 1903 return handleStaticSend(node, selector, mask, getter, null); |
1894 } | 1904 } |
1895 | 1905 |
1896 /// Closurize a static or top level function. | 1906 /// Closurize a static or top level function. |
1897 T handleStaticFunctionGet(ast.Send node, MethodElement function) { | 1907 T handleStaticFunctionGet(ast.Send node, MethodElement function) { |
1898 Selector selector = elements.getSelector(node); | 1908 Selector selector = elements.getSelector(node); |
1899 TypeMask mask = elements.getTypeMask(node); | 1909 TypeMask mask = inTreeData.typeOfSend(node); |
1900 return handleStaticSend(node, selector, mask, function, null); | 1910 return handleStaticSend(node, selector, mask, function, null); |
1901 } | 1911 } |
1902 | 1912 |
1903 @override | 1913 @override |
1904 T visitDynamicPropertyGet(ast.Send node, ast.Node receiver, Name name, _) { | 1914 T visitDynamicPropertyGet(ast.Send node, ast.Node receiver, Name name, _) { |
1905 return handleDynamicGet(node); | 1915 return handleDynamicGet(node); |
1906 } | 1916 } |
1907 | 1917 |
1908 @override | 1918 @override |
1909 T visitIfNotNullDynamicPropertyGet( | 1919 T visitIfNotNullDynamicPropertyGet( |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1973 | 1983 |
1974 @override | 1984 @override |
1975 T visitUnresolvedGet(ast.Send node, Element element, _) { | 1985 T visitUnresolvedGet(ast.Send node, Element element, _) { |
1976 return types.dynamicType; | 1986 return types.dynamicType; |
1977 } | 1987 } |
1978 | 1988 |
1979 /// Handle .call invocation on [closure]. | 1989 /// Handle .call invocation on [closure]. |
1980 T handleCallInvoke(ast.Send node, T closure) { | 1990 T handleCallInvoke(ast.Send node, T closure) { |
1981 ArgumentsTypes arguments = analyzeArguments(node.arguments); | 1991 ArgumentsTypes arguments = analyzeArguments(node.arguments); |
1982 Selector selector = elements.getSelector(node); | 1992 Selector selector = elements.getSelector(node); |
1983 TypeMask mask = elements.getTypeMask(node); | 1993 TypeMask mask = inTreeData.typeOfSend(node); |
1984 return inferrer.registerCalledClosure(node, selector, mask, closure, | 1994 return inferrer.registerCalledClosure(node, selector, mask, closure, |
1985 outermostElement, arguments, sideEffects, inLoop); | 1995 outermostElement, arguments, sideEffects, inLoop); |
1986 } | 1996 } |
1987 | 1997 |
1988 @override | 1998 @override |
1989 T visitExpressionInvoke(ast.Send node, ast.Node expression, | 1999 T visitExpressionInvoke(ast.Send node, ast.Node expression, |
1990 ast.NodeList arguments, CallStructure callStructure, _) { | 2000 ast.NodeList arguments, CallStructure callStructure, _) { |
1991 return handleCallInvoke(node, expression.accept(this)); | 2001 return handleCallInvoke(node, expression.accept(this)); |
1992 } | 2002 } |
1993 | 2003 |
(...skipping 13 matching lines...) Expand all Loading... |
2007 T visitLocalVariableInvoke(ast.Send node, LocalVariableElement variable, | 2017 T visitLocalVariableInvoke(ast.Send node, LocalVariableElement variable, |
2008 ast.NodeList arguments, CallStructure callStructure, _) { | 2018 ast.NodeList arguments, CallStructure callStructure, _) { |
2009 return handleCallInvoke(node, locals.use(variable)); | 2019 return handleCallInvoke(node, locals.use(variable)); |
2010 } | 2020 } |
2011 | 2021 |
2012 @override | 2022 @override |
2013 T visitLocalFunctionInvoke(ast.Send node, LocalFunctionElement function, | 2023 T visitLocalFunctionInvoke(ast.Send node, LocalFunctionElement function, |
2014 ast.NodeList arguments, CallStructure callStructure, _) { | 2024 ast.NodeList arguments, CallStructure callStructure, _) { |
2015 ArgumentsTypes argumentTypes = analyzeArguments(node.arguments); | 2025 ArgumentsTypes argumentTypes = analyzeArguments(node.arguments); |
2016 Selector selector = elements.getSelector(node); | 2026 Selector selector = elements.getSelector(node); |
2017 TypeMask mask = elements.getTypeMask(node); | 2027 TypeMask mask = inTreeData.typeOfSend(node); |
2018 // This only works for function statements. We need a | 2028 // This only works for function statements. We need a |
2019 // more sophisticated type system with function types to support | 2029 // more sophisticated type system with function types to support |
2020 // more. | 2030 // more. |
2021 return inferrer.registerCalledElement(node, selector, mask, | 2031 return inferrer.registerCalledElement(node, selector, mask, |
2022 outermostElement, function, argumentTypes, sideEffects, inLoop); | 2032 outermostElement, function, argumentTypes, sideEffects, inLoop); |
2023 } | 2033 } |
2024 | 2034 |
2025 @override | 2035 @override |
2026 T visitLocalFunctionIncompatibleInvoke( | 2036 T visitLocalFunctionIncompatibleInvoke( |
2027 ast.Send node, | 2037 ast.Send node, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2093 isCallOnThis = true; | 2103 isCallOnThis = true; |
2094 receiverType = thisType; | 2104 receiverType = thisType; |
2095 } | 2105 } |
2096 } else { | 2106 } else { |
2097 ast.Node receiver = node.receiver; | 2107 ast.Node receiver = node.receiver; |
2098 isCallOnThis = isThisOrSuper(receiver); | 2108 isCallOnThis = isThisOrSuper(receiver); |
2099 receiverType = visit(receiver); | 2109 receiverType = visit(receiver); |
2100 } | 2110 } |
2101 | 2111 |
2102 Selector selector = elements.getSelector(node); | 2112 Selector selector = elements.getSelector(node); |
2103 TypeMask mask = elements.getTypeMask(node); | 2113 TypeMask mask = inTreeData.typeOfSend(node); |
2104 if (!isThisExposed && isCallOnThis) { | 2114 if (!isThisExposed && isCallOnThis) { |
2105 checkIfExposesThis(selector, types.newTypedSelector(receiverType, mask)); | 2115 checkIfExposesThis(selector, types.newTypedSelector(receiverType, mask)); |
2106 } | 2116 } |
2107 | 2117 |
2108 ArgumentsTypes arguments = | 2118 ArgumentsTypes arguments = |
2109 node.isPropertyAccess ? null : analyzeArguments(node.arguments); | 2119 node.isPropertyAccess ? null : analyzeArguments(node.arguments); |
2110 if (selector.name == '==' || selector.name == '!=') { | 2120 if (selector.name == '==' || selector.name == '!=') { |
2111 if (types.isNull(receiverType)) { | 2121 if (types.isNull(receiverType)) { |
2112 potentiallyAddNullCheck(node, node.arguments.head); | 2122 potentiallyAddNullCheck(node, node.arguments.head); |
2113 return types.boolType; | 2123 return types.boolType; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2188 | 2198 |
2189 if (node.expression.isThis()) { | 2199 if (node.expression.isThis()) { |
2190 // Any reasonable implementation of an iterator would expose | 2200 // Any reasonable implementation of an iterator would expose |
2191 // this, so we play it safe and assume it will. | 2201 // this, so we play it safe and assume it will. |
2192 isThisExposed = true; | 2202 isThisExposed = true; |
2193 } | 2203 } |
2194 | 2204 |
2195 ast.Node identifier = node.declaredIdentifier; | 2205 ast.Node identifier = node.declaredIdentifier; |
2196 Element element = elements.getForInVariable(node); | 2206 Element element = elements.getForInVariable(node); |
2197 Selector selector = elements.getSelector(identifier); | 2207 Selector selector = elements.getSelector(identifier); |
2198 TypeMask mask = elements.getTypeMask(identifier); | 2208 TypeMask mask = inTreeData.typeOfSend(identifier); |
2199 | 2209 |
2200 T receiverType; | 2210 T receiverType; |
2201 if (element != null && element.isInstanceMember) { | 2211 if (element != null && element.isInstanceMember) { |
2202 receiverType = thisType; | 2212 receiverType = thisType; |
2203 } else { | 2213 } else { |
2204 receiverType = types.dynamicType; | 2214 receiverType = types.dynamicType; |
2205 } | 2215 } |
2206 | 2216 |
2207 handlePlainAssignment(identifier, element, selector, mask, receiverType, | 2217 handlePlainAssignment(identifier, element, selector, mask, receiverType, |
2208 currentType, node.expression); | 2218 currentType, node.expression); |
2209 return handleLoop(node, () { | 2219 return handleLoop(node, () { |
2210 visit(node.body); | 2220 visit(node.body); |
2211 }); | 2221 }); |
2212 } | 2222 } |
2213 | 2223 |
2214 T visitAsyncForIn(ast.AsyncForIn node) { | 2224 T visitAsyncForIn(ast.AsyncForIn node) { |
2215 T expressionType = visit(node.expression); | 2225 T expressionType = visit(node.expression); |
2216 | 2226 |
2217 Selector currentSelector = Selectors.current; | 2227 Selector currentSelector = Selectors.current; |
2218 TypeMask currentMask = elements.getCurrentTypeMask(node); | 2228 TypeMask currentMask = inTreeData.typeOfIteratorCurrent(node); |
2219 Selector moveNextSelector = Selectors.moveNext; | 2229 Selector moveNextSelector = Selectors.moveNext; |
2220 TypeMask moveNextMask = elements.getMoveNextTypeMask(node); | 2230 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); |
2221 | 2231 |
2222 js.JavaScriptBackend backend = compiler.backend; | 2232 js.JavaScriptBackend backend = compiler.backend; |
2223 Element ctor = backend.helpers.streamIteratorConstructor; | 2233 Element ctor = backend.helpers.streamIteratorConstructor; |
2224 | 2234 |
2225 /// Synthesize a call to the [StreamIterator] constructor. | 2235 /// Synthesize a call to the [StreamIterator] constructor. |
2226 T iteratorType = handleStaticSend( | 2236 T iteratorType = handleStaticSend( |
2227 node, null, null, ctor, new ArgumentsTypes<T>([expressionType], null)); | 2237 node, null, null, ctor, new ArgumentsTypes<T>([expressionType], null)); |
2228 | 2238 |
2229 return handleForInLoop(node, iteratorType, currentSelector, currentMask, | 2239 return handleForInLoop(node, iteratorType, currentSelector, currentMask, |
2230 moveNextSelector, moveNextMask); | 2240 moveNextSelector, moveNextMask); |
2231 } | 2241 } |
2232 | 2242 |
2233 T visitSyncForIn(ast.SyncForIn node) { | 2243 T visitSyncForIn(ast.SyncForIn node) { |
2234 T expressionType = visit(node.expression); | 2244 T expressionType = visit(node.expression); |
2235 Selector iteratorSelector = Selectors.iterator; | 2245 Selector iteratorSelector = Selectors.iterator; |
2236 TypeMask iteratorMask = elements.getIteratorTypeMask(node); | 2246 TypeMask iteratorMask = inTreeData.typeOfIterator(node); |
2237 Selector currentSelector = Selectors.current; | 2247 Selector currentSelector = Selectors.current; |
2238 TypeMask currentMask = elements.getCurrentTypeMask(node); | 2248 TypeMask currentMask = inTreeData.typeOfIteratorCurrent(node); |
2239 Selector moveNextSelector = Selectors.moveNext; | 2249 Selector moveNextSelector = Selectors.moveNext; |
2240 TypeMask moveNextMask = elements.getMoveNextTypeMask(node); | 2250 TypeMask moveNextMask = inTreeData.typeOfIteratorMoveNext(node); |
2241 | 2251 |
2242 T iteratorType = handleDynamicSend(node, iteratorSelector, iteratorMask, | 2252 T iteratorType = handleDynamicSend(node, iteratorSelector, iteratorMask, |
2243 expressionType, new ArgumentsTypes<T>.empty()); | 2253 expressionType, new ArgumentsTypes<T>.empty()); |
2244 | 2254 |
2245 return handleForInLoop(node, iteratorType, currentSelector, currentMask, | 2255 return handleForInLoop(node, iteratorType, currentSelector, currentMask, |
2246 moveNextSelector, moveNextMask); | 2256 moveNextSelector, moveNextMask); |
2247 } | 2257 } |
2248 } | 2258 } |
OLD | NEW |