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

Side by Side Diff: pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 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 7 import '../closure.dart' show ClosureClassMap, ClosureScope;
8 ClosureClassMap,
9 ClosureScope;
10 import '../common.dart'; 8 import '../common.dart';
11 import '../common/names.dart' show 9 import '../common/names.dart' show Selectors;
12 Selectors; 10 import '../compiler.dart' show Compiler;
13 import '../compiler.dart' show 11 import '../constants/values.dart' show ConstantValue, IntConstantValue;
14 Compiler; 12 import '../core_types.dart' show CoreClasses, CoreTypes;
15 import '../constants/values.dart' show 13 import '../cps_ir/cps_ir_nodes.dart' as cps_ir show Node;
16 ConstantValue, 14 import '../dart_types.dart'
17 IntConstantValue; 15 show DartType, FunctionType, InterfaceType, TypeKind;
18 import '../core_types.dart' show
19 CoreClasses,
20 CoreTypes;
21 import '../cps_ir/cps_ir_nodes.dart' as cps_ir show
22 Node;
23 import '../dart_types.dart' show
24 DartType,
25 FunctionType,
26 InterfaceType,
27 TypeKind;
28 import '../elements/elements.dart'; 16 import '../elements/elements.dart';
29 import '../js_backend/js_backend.dart' as js; 17 import '../js_backend/js_backend.dart' as js;
30 import '../native/native.dart' as native; 18 import '../native/native.dart' as native;
31 import '../resolution/tree_elements.dart' show 19 import '../resolution/tree_elements.dart' show TreeElements;
32 TreeElements;
33 import '../resolution/operators.dart' as op; 20 import '../resolution/operators.dart' as op;
34 import '../tree/tree.dart' as ast; 21 import '../tree/tree.dart' as ast;
35 import '../types/types.dart' show 22 import '../types/types.dart'
36 TypesInferrer, 23 show
37 FlatTypeMask, 24 TypesInferrer,
38 TypeMask, 25 FlatTypeMask,
39 ContainerTypeMask, 26 TypeMask,
40 ValueTypeMask; 27 ContainerTypeMask,
41 import '../util/util.dart' show 28 ValueTypeMask;
42 Link, 29 import '../util/util.dart' show Link, Setlet;
43 Setlet; 30 import '../universe/call_structure.dart' show CallStructure;
44 import '../universe/call_structure.dart' show 31 import '../universe/selector.dart' show Selector;
45 CallStructure; 32 import '../universe/side_effects.dart' show SideEffects;
46 import '../universe/selector.dart' show
47 Selector;
48 import '../universe/side_effects.dart' show
49 SideEffects;
50 import '../world.dart' show ClassWorld; 33 import '../world.dart' show ClassWorld;
51 34
52 import 'inferrer_visitor.dart'; 35 import 'inferrer_visitor.dart';
53 36
54 /** 37 /**
55 * Common super class used by [SimpleTypeInferrerVisitor] to propagate 38 * Common super class used by [SimpleTypeInferrerVisitor] to propagate
56 * type information about visited nodes, as well as to request type 39 * type information about visited nodes, as well as to request type
57 * information of elements. 40 * information of elements.
58 */ 41 */
59 abstract class InferrerEngine<T, V extends TypeSystem> 42 abstract class InferrerEngine<T, V extends TypeSystem>
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 /** 78 /**
96 * Returns the return type of [element]. 79 * Returns the return type of [element].
97 */ 80 */
98 T returnTypeOfElement(Element element); 81 T returnTypeOfElement(Element element);
99 82
100 /** 83 /**
101 * Records that [node] sets final field [element] to be of type [type]. 84 * Records that [node] sets final field [element] to be of type [type].
102 * 85 *
103 * [nodeHolder] is the element holder of [node]. 86 * [nodeHolder] is the element holder of [node].
104 */ 87 */
105 void recordTypeOfFinalField(ast.Node node, 88 void recordTypeOfFinalField(
106 Element nodeHolder, 89 ast.Node node, Element nodeHolder, Element field, T type);
107 Element field,
108 T type);
109 90
110 /** 91 /**
111 * Records that [node] sets non-final field [element] to be of type 92 * Records that [node] sets non-final field [element] to be of type
112 * [type]. 93 * [type].
113 */ 94 */
114 void recordTypeOfNonFinalField(Spannable node, Element field, T type); 95 void recordTypeOfNonFinalField(Spannable node, Element field, T type);
115 96
116 /** 97 /**
117 * Records that [element] is of type [type]. 98 * Records that [element] is of type [type].
118 */ 99 */
119 void recordType(Element element, T type); 100 void recordType(Element element, T type);
120 101
121 /** 102 /**
122 * Records that the return type [element] is of type [type]. 103 * Records that the return type [element] is of type [type].
123 */ 104 */
124 void recordReturnType(Element element, T type); 105 void recordReturnType(Element element, T type);
125 106
126 /** 107 /**
127 * Registers that [caller] calls [callee] at location [node], with 108 * Registers that [caller] calls [callee] at location [node], with
128 * [selector], and [arguments]. Note that [selector] is null for 109 * [selector], and [arguments]. Note that [selector] is null for
129 * forwarding constructors. 110 * forwarding constructors.
130 * 111 *
131 * [sideEffects] will be updated to incorporate [callee]'s side 112 * [sideEffects] will be updated to incorporate [callee]'s side
132 * effects. 113 * effects.
133 * 114 *
134 * [inLoop] tells whether the call happens in a loop. 115 * [inLoop] tells whether the call happens in a loop.
135 */ 116 */
136 T registerCalledElement(Spannable node, 117 T registerCalledElement(
137 Selector selector, 118 Spannable node,
138 TypeMask mask, 119 Selector selector,
139 Element caller, 120 TypeMask mask,
140 Element callee, 121 Element caller,
141 ArgumentsTypes<T> arguments, 122 Element callee,
142 SideEffects sideEffects, 123 ArgumentsTypes<T> arguments,
143 bool inLoop); 124 SideEffects sideEffects,
125 bool inLoop);
144 126
145 /** 127 /**
146 * Registers that [caller] calls [selector] with [receiverType] as 128 * Registers that [caller] calls [selector] with [receiverType] as
147 * receiver, and [arguments]. 129 * receiver, and [arguments].
148 * 130 *
149 * [sideEffects] will be updated to incorporate the potential 131 * [sideEffects] will be updated to incorporate the potential
150 * callees' side effects. 132 * callees' side effects.
151 * 133 *
152 * [inLoop] tells whether the call happens in a loop. 134 * [inLoop] tells whether the call happens in a loop.
153 */ 135 */
154 T registerCalledSelector(ast.Node node, 136 T registerCalledSelector(
155 Selector selector, 137 ast.Node node,
156 TypeMask mask, 138 Selector selector,
157 T receiverType, 139 TypeMask mask,
158 Element caller, 140 T receiverType,
159 ArgumentsTypes<T> arguments, 141 Element caller,
160 SideEffects sideEffects, 142 ArgumentsTypes<T> arguments,
161 bool inLoop); 143 SideEffects sideEffects,
144 bool inLoop);
162 145
163 /** 146 /**
164 * Registers that [caller] calls [closure] with [arguments]. 147 * Registers that [caller] calls [closure] with [arguments].
165 * 148 *
166 * [sideEffects] will be updated to incorporate the potential 149 * [sideEffects] will be updated to incorporate the potential
167 * callees' side effects. 150 * callees' side effects.
168 * 151 *
169 * [inLoop] tells whether the call happens in a loop. 152 * [inLoop] tells whether the call happens in a loop.
170 */ 153 */
171 T registerCalledClosure(ast.Node node, 154 T registerCalledClosure(
172 Selector selector, 155 ast.Node node,
173 TypeMask mask, 156 Selector selector,
174 T closure, 157 TypeMask mask,
175 Element caller, 158 T closure,
176 ArgumentsTypes<T> arguments, 159 Element caller,
177 SideEffects sideEffects, 160 ArgumentsTypes<T> arguments,
178 bool inLoop); 161 SideEffects sideEffects,
162 bool inLoop);
179 163
180 /** 164 /**
181 * Registers a call to await with an expression of type [argumentType] as 165 * Registers a call to await with an expression of type [argumentType] as
182 * argument. 166 * argument.
183 */ 167 */
184 T registerAwait(ast.Node node, T argumentType); 168 T registerAwait(ast.Node node, T argumentType);
185 169
186 /** 170 /**
187 * Notifies to the inferrer that [analyzedElement] can have return 171 * Notifies to the inferrer that [analyzedElement] can have return
188 * type [newType]. [currentType] is the type the [InferrerVisitor] 172 * type [newType]. [currentType] is the type the [InferrerVisitor]
189 * currently found. 173 * currently found.
190 * 174 *
191 * Returns the new type for [analyzedElement]. 175 * Returns the new type for [analyzedElement].
192 */ 176 */
193 T addReturnTypeFor(Element analyzedElement, T currentType, T newType); 177 T addReturnTypeFor(Element analyzedElement, T currentType, T newType);
194 178
195 /** 179 /**
196 * Applies [f] to all elements in the universe that match 180 * Applies [f] to all elements in the universe that match
197 * [selector] and [mask]. If [f] returns false, aborts the iteration. 181 * [selector] and [mask]. If [f] returns false, aborts the iteration.
198 */ 182 */
199 void forEachElementMatching(Selector selector, 183 void forEachElementMatching(
200 TypeMask mask, 184 Selector selector, TypeMask mask, bool f(Element element)) {
201 bool f(Element element)) {
202 Iterable<Element> elements = 185 Iterable<Element> elements =
203 compiler.world.allFunctions.filter(selector, mask); 186 compiler.world.allFunctions.filter(selector, mask);
204 for (Element e in elements) { 187 for (Element e in elements) {
205 if (!f(e.implementation)) return; 188 if (!f(e.implementation)) return;
206 } 189 }
207 } 190 }
208 191
209 /** 192 /**
210 * Update [sideEffects] with the side effects of [callee] being 193 * Update [sideEffects] with the side effects of [callee] being
211 * called with [selector]. 194 * called with [selector].
212 */ 195 */
213 void updateSideEffects(SideEffects sideEffects, 196 void updateSideEffects(
214 Selector selector, 197 SideEffects sideEffects, Selector selector, Element callee) {
215 Element callee) {
216 if (callee.isField) { 198 if (callee.isField) {
217 if (callee.isInstanceMember) { 199 if (callee.isInstanceMember) {
218 if (selector.isSetter) { 200 if (selector.isSetter) {
219 sideEffects.setChangesInstanceProperty(); 201 sideEffects.setChangesInstanceProperty();
220 } else if (selector.isGetter) { 202 } else if (selector.isGetter) {
221 sideEffects.setDependsOnInstancePropertyStore(); 203 sideEffects.setDependsOnInstancePropertyStore();
222 } else { 204 } else {
223 sideEffects.setAllSideEffects(); 205 sideEffects.setAllSideEffects();
224 sideEffects.setDependsOnSomething(); 206 sideEffects.setDependsOnSomething();
225 } 207 }
(...skipping 25 matching lines...) Expand all
251 if (typesReturned.isEmpty) return types.dynamicType; 233 if (typesReturned.isEmpty) return types.dynamicType;
252 T returnType; 234 T returnType;
253 for (var type in typesReturned) { 235 for (var type in typesReturned) {
254 T mappedType; 236 T mappedType;
255 if (type == native.SpecialType.JsObject) { 237 if (type == native.SpecialType.JsObject) {
256 mappedType = types.nonNullExact(coreClasses.objectClass); 238 mappedType = types.nonNullExact(coreClasses.objectClass);
257 } else if (type == coreTypes.stringType) { 239 } else if (type == coreTypes.stringType) {
258 mappedType = types.stringType; 240 mappedType = types.stringType;
259 } else if (type == coreTypes.intType) { 241 } else if (type == coreTypes.intType) {
260 mappedType = types.intType; 242 mappedType = types.intType;
261 } else if (type == coreTypes.numType || 243 } else if (type == coreTypes.numType || type == coreTypes.doubleType) {
262 type == coreTypes.doubleType) {
263 // Note: the backend double class is specifically for non-integer 244 // Note: the backend double class is specifically for non-integer
264 // doubles, and a native behavior returning 'double' does not guarantee 245 // doubles, and a native behavior returning 'double' does not guarantee
265 // a non-integer return type, so we return the number type for those. 246 // a non-integer return type, so we return the number type for those.
266 mappedType = types.numType; 247 mappedType = types.numType;
267 } else if (type == coreTypes.boolType) { 248 } else if (type == coreTypes.boolType) {
268 mappedType = types.boolType; 249 mappedType = types.boolType;
269 } else if (type == coreTypes.nullType) { 250 } else if (type == coreTypes.nullType) {
270 mappedType = types.nullType; 251 mappedType = types.nullType;
271 } else if (type.isVoid) { 252 } else if (type.isVoid) {
272 mappedType = types.nullType; 253 mappedType = types.nullType;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 elements.setCurrentTypeMask(node, mask); 291 elements.setCurrentTypeMask(node, mask);
311 } else { 292 } else {
312 assert(selector == Selectors.moveNext); 293 assert(selector == Selectors.moveNext);
313 elements.setMoveNextTypeMask(node, mask); 294 elements.setMoveNextTypeMask(node, mask);
314 } 295 }
315 } 296 }
316 } 297 }
317 298
318 bool isNativeElement(Element element) { 299 bool isNativeElement(Element element) {
319 if (compiler.backend.isNative(element)) return true; 300 if (compiler.backend.isNative(element)) return true;
320 return element.isClassMember 301 return element.isClassMember &&
321 && compiler.backend.isNative(element.enclosingClass) 302 compiler.backend.isNative(element.enclosingClass) &&
322 && element.isField; 303 element.isField;
323 } 304 }
324 305
325 void analyze(Element element, ArgumentsTypes arguments); 306 void analyze(Element element, ArgumentsTypes arguments);
326 307
327 bool checkIfExposesThis(Element element) { 308 bool checkIfExposesThis(Element element) {
328 element = element.implementation; 309 element = element.implementation;
329 return generativeConstructorsExposingThis.contains(element); 310 return generativeConstructorsExposingThis.contains(element);
330 } 311 }
331 312
332 void recordExposesThis(Element element, bool exposesThis) { 313 void recordExposesThis(Element element, bool exposesThis) {
(...skipping 17 matching lines...) Expand all
350 extends InferrerVisitor<T, InferrerEngine<T, TypeSystem<T>>> { 331 extends InferrerVisitor<T, InferrerEngine<T, TypeSystem<T>>> {
351 T returnType; 332 T returnType;
352 bool visitingInitializers = false; 333 bool visitingInitializers = false;
353 bool isConstructorRedirect = false; 334 bool isConstructorRedirect = false;
354 bool seenSuperConstructorCall = false; 335 bool seenSuperConstructorCall = false;
355 SideEffects sideEffects = new SideEffects.empty(); 336 SideEffects sideEffects = new SideEffects.empty();
356 final Element outermostElement; 337 final Element outermostElement;
357 final InferrerEngine<T, TypeSystem<T>> inferrer; 338 final InferrerEngine<T, TypeSystem<T>> inferrer;
358 final Setlet<Entity> capturedVariables = new Setlet<Entity>(); 339 final Setlet<Entity> capturedVariables = new Setlet<Entity>();
359 340
360 SimpleTypeInferrerVisitor.internal(analyzedElement, 341 SimpleTypeInferrerVisitor.internal(
361 this.outermostElement, 342 analyzedElement, this.outermostElement, inferrer, compiler, locals)
362 inferrer, 343 : super(analyzedElement, inferrer, inferrer.types, compiler, locals),
363 compiler, 344 this.inferrer = inferrer {
364 locals)
365 : super(analyzedElement, inferrer, inferrer.types, compiler, locals),
366 this.inferrer = inferrer {
367 assert(outermostElement != null); 345 assert(outermostElement != null);
368 } 346 }
369 347
370 SimpleTypeInferrerVisitor(Element element, 348 SimpleTypeInferrerVisitor(Element element, Compiler compiler,
371 Compiler compiler, 349 InferrerEngine<T, TypeSystem<T>> inferrer, [LocalsHandler<T> handler])
372 InferrerEngine<T, TypeSystem<T>> inferrer, 350 : this.internal(
373 [LocalsHandler<T> handler]) 351 element,
374 : this.internal(element, 352 element.outermostEnclosingMemberOrTopLevel.implementation,
375 element.outermostEnclosingMemberOrTopLevel.implementation, 353 inferrer,
376 inferrer, compiler, handler); 354 compiler,
355 handler);
377 356
378 void analyzeSuperConstructorCall(Element target, ArgumentsTypes arguments) { 357 void analyzeSuperConstructorCall(Element target, ArgumentsTypes arguments) {
379 inferrer.analyze(target, arguments); 358 inferrer.analyze(target, arguments);
380 isThisExposed = isThisExposed || inferrer.checkIfExposesThis(target); 359 isThisExposed = isThisExposed || inferrer.checkIfExposesThis(target);
381 } 360 }
382 361
383 T run() { 362 T run() {
384 var node = analyzedElement.node; 363 var node = analyzedElement.node;
385 ast.Expression initializer; 364 ast.Expression initializer;
386 if (analyzedElement.isField) { 365 if (analyzedElement.isField) {
387 VariableElement fieldElement = analyzedElement; 366 VariableElement fieldElement = analyzedElement;
388 initializer = fieldElement.initializer; 367 initializer = fieldElement.initializer;
389 if (initializer == null) { 368 if (initializer == null) {
390 // Eagerly bailout, because computing the closure data only 369 // Eagerly bailout, because computing the closure data only
391 // works for functions and field assignments. 370 // works for functions and field assignments.
392 return types.nullType; 371 return types.nullType;
393 } 372 }
394 } 373 }
395 // Update the locals that are boxed in [locals]. These locals will 374 // Update the locals that are boxed in [locals]. These locals will
396 // be handled specially, in that we are computing their LUB at 375 // be handled specially, in that we are computing their LUB at
397 // each update, and reading them yields the type that was found in a 376 // each update, and reading them yields the type that was found in a
398 // previous analysis of [outermostElement]. 377 // previous analysis of [outermostElement].
399 ClosureClassMap closureData = 378 ClosureClassMap closureData = compiler.closureToClassMapper
400 compiler.closureToClassMapper.computeClosureToClassMapping( 379 .computeClosureToClassMapping(analyzedElement, node, elements);
401 analyzedElement, node, elements);
402 closureData.forEachCapturedVariable((variable, field) { 380 closureData.forEachCapturedVariable((variable, field) {
403 locals.setCaptured(variable, field); 381 locals.setCaptured(variable, field);
404 }); 382 });
405 closureData.forEachBoxedVariable((variable, field) { 383 closureData.forEachBoxedVariable((variable, field) {
406 locals.setCapturedAndBoxed(variable, field); 384 locals.setCapturedAndBoxed(variable, field);
407 }); 385 });
408 if (analyzedElement.isField) { 386 if (analyzedElement.isField) {
409 return visit(initializer); 387 return visit(initializer);
410 } 388 }
411 389
(...skipping 26 matching lines...) Expand all
438 return types.dynamicType; 416 return types.dynamicType;
439 } 417 }
440 418
441 if (analyzedElement.isGenerativeConstructor) { 419 if (analyzedElement.isGenerativeConstructor) {
442 isThisExposed = false; 420 isThisExposed = false;
443 signature.forEachParameter((ParameterElement element) { 421 signature.forEachParameter((ParameterElement element) {
444 T parameterType = inferrer.typeOfElement(element); 422 T parameterType = inferrer.typeOfElement(element);
445 if (element.isInitializingFormal) { 423 if (element.isInitializingFormal) {
446 InitializingFormalElement initializingFormal = element; 424 InitializingFormalElement initializingFormal = element;
447 if (initializingFormal.fieldElement.isFinal) { 425 if (initializingFormal.fieldElement.isFinal) {
448 inferrer.recordTypeOfFinalField( 426 inferrer.recordTypeOfFinalField(node, analyzedElement,
449 node, 427 initializingFormal.fieldElement, parameterType);
450 analyzedElement,
451 initializingFormal.fieldElement,
452 parameterType);
453 } else { 428 } else {
454 locals.updateField(initializingFormal.fieldElement, parameterType); 429 locals.updateField(initializingFormal.fieldElement, parameterType);
455 inferrer.recordTypeOfNonFinalField( 430 inferrer.recordTypeOfNonFinalField(initializingFormal.node,
456 initializingFormal.node, 431 initializingFormal.fieldElement, parameterType);
457 initializingFormal.fieldElement,
458 parameterType);
459 } 432 }
460 } 433 }
461 locals.update(element, parameterType, node); 434 locals.update(element, parameterType, node);
462 }); 435 });
463 ClassElement cls = analyzedElement.enclosingClass; 436 ClassElement cls = analyzedElement.enclosingClass;
464 Spannable spannable = node; 437 Spannable spannable = node;
465 if (analyzedElement.isSynthesized) { 438 if (analyzedElement.isSynthesized) {
466 spannable = analyzedElement; 439 spannable = analyzedElement;
467 ConstructorElement constructor = analyzedElement; 440 ConstructorElement constructor = analyzedElement;
468 synthesizeForwardingCall(spannable, constructor.definingConstructor); 441 synthesizeForwardingCall(spannable, constructor.definingConstructor);
469 } else { 442 } else {
470 visitingInitializers = true; 443 visitingInitializers = true;
471 if (node.initializers != null) { 444 if (node.initializers != null) {
472 for (ast.Node initializer in node.initializers) { 445 for (ast.Node initializer in node.initializers) {
473 ast.SendSet fieldInitializer = initializer.asSendSet(); 446 ast.SendSet fieldInitializer = initializer.asSendSet();
474 if (fieldInitializer != null) { 447 if (fieldInitializer != null) {
475 handleSendSet(fieldInitializer); 448 handleSendSet(fieldInitializer);
476 } else { 449 } else {
477 Element element = elements[initializer]; 450 Element element = elements[initializer];
478 handleConstructorSend(initializer, element); 451 handleConstructorSend(initializer, element);
479 } 452 }
480 } 453 }
481 } 454 }
482 visitingInitializers = false; 455 visitingInitializers = false;
483 // For a generative constructor like: `Foo();`, we synthesize 456 // For a generative constructor like: `Foo();`, we synthesize
484 // a call to the default super constructor (the one that takes 457 // a call to the default super constructor (the one that takes
485 // no argument). Resolution ensures that such a constructor 458 // no argument). Resolution ensures that such a constructor
486 // exists. 459 // exists.
487 if (!isConstructorRedirect 460 if (!isConstructorRedirect &&
488 && !seenSuperConstructorCall 461 !seenSuperConstructorCall &&
489 && !cls.isObject) { 462 !cls.isObject) {
490 FunctionElement target = cls.superclass.lookupDefaultConstructor(); 463 FunctionElement target = cls.superclass.lookupDefaultConstructor();
491 ArgumentsTypes arguments = new ArgumentsTypes([], {}); 464 ArgumentsTypes arguments = new ArgumentsTypes([], {});
492 analyzeSuperConstructorCall(target, arguments); 465 analyzeSuperConstructorCall(target, arguments);
493 inferrer.registerCalledElement(node, 466 inferrer.registerCalledElement(node, null, null, outermostElement,
494 null, 467 target.implementation, arguments, sideEffects, inLoop);
495 null,
496 outermostElement,
497 target.implementation,
498 arguments,
499 sideEffects,
500 inLoop);
501 } 468 }
502 visit(node.body); 469 visit(node.body);
503 inferrer.recordExposesThis(analyzedElement, isThisExposed); 470 inferrer.recordExposesThis(analyzedElement, isThisExposed);
504 } 471 }
505 if (!isConstructorRedirect) { 472 if (!isConstructorRedirect) {
506 // Iterate over all instance fields, and give a null type to 473 // Iterate over all instance fields, and give a null type to
507 // fields that we haven't initialized for sure. 474 // fields that we haven't initialized for sure.
508 cls.forEachInstanceField((_, FieldElement field) { 475 cls.forEachInstanceField((_, FieldElement field) {
509 if (field.isFinal) return; 476 if (field.isFinal) return;
510 T type = locals.fieldScope.readField(field); 477 T type = locals.fieldScope.readField(field);
511 if (type == null && field.initializer == null) { 478 if (type == null && field.initializer == null) {
512 inferrer.recordTypeOfNonFinalField( 479 inferrer.recordTypeOfNonFinalField(
513 spannable, field, types.nullType); 480 spannable, field, types.nullType);
514 } 481 }
515 }); 482 });
516 } 483 }
517 if (analyzedElement.isGenerativeConstructor && cls.isAbstract) { 484 if (analyzedElement.isGenerativeConstructor && cls.isAbstract) {
518 if (compiler.world.isDirectlyInstantiated(cls)) { 485 if (compiler.world.isDirectlyInstantiated(cls)) {
519 returnType = types.nonNullExact(cls); 486 returnType = types.nonNullExact(cls);
520 } else if (compiler.world.isIndirectlyInstantiated(cls)) { 487 } else if (compiler.world.isIndirectlyInstantiated(cls)) {
521 returnType = types.nonNullSubclass(cls); 488 returnType = types.nonNullSubclass(cls);
522 } else { 489 } else {
523 // TODO(johnniwinther): Avoid analyzing [analyzedElement] in this 490 // TODO(johnniwinther): Avoid analyzing [analyzedElement] in this
524 // case; it's never called. 491 // case; it's never called.
525 returnType = types.nonNullEmpty(); 492 returnType = types.nonNullEmpty();
526 } 493 }
527 } else { 494 } else {
528 returnType = types.nonNullExact(cls); 495 returnType = types.nonNullExact(cls);
529 } 496 }
530 } else { 497 } else {
531 signature.forEachParameter((LocalParameterElement element) { 498 signature.forEachParameter((LocalParameterElement element) {
532 locals.update(element, inferrer.typeOfElement(element), node); 499 locals.update(element, inferrer.typeOfElement(element), node);
533 }); 500 });
534 visit(node.body); 501 visit(node.body);
535 switch (function.asyncMarker) { 502 switch (function.asyncMarker) {
536 case AsyncMarker.SYNC: 503 case AsyncMarker.SYNC:
537 if (returnType == null) { 504 if (returnType == null) {
538 // No return in the body. 505 // No return in the body.
539 returnType = locals.seenReturnOrThrow 506 returnType = locals.seenReturnOrThrow
540 ? types.nonNullEmpty() // Body always throws. 507 ? types.nonNullEmpty() // Body always throws.
541 : types.nullType; 508 : types.nullType;
542 } else if (!locals.seenReturnOrThrow) { 509 } else if (!locals.seenReturnOrThrow) {
543 // We haven't seen returns on all branches. So the method may 510 // We haven't seen returns on all branches. So the method may
544 // also return null. 511 // also return null.
545 returnType = inferrer.addReturnTypeFor( 512 returnType = inferrer.addReturnTypeFor(
546 analyzedElement, returnType, types.nullType); 513 analyzedElement, returnType, types.nullType);
547 } 514 }
548 break; 515 break;
549 516
550 case AsyncMarker.SYNC_STAR: 517 case AsyncMarker.SYNC_STAR:
551 // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type 518 // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type
552 // contained is the method body's return type. 519 // contained is the method body's return type.
553 returnType = inferrer.addReturnTypeFor( 520 returnType = inferrer.addReturnTypeFor(
554 analyzedElement, returnType, types.syncStarIterableType); 521 analyzedElement, returnType, types.syncStarIterableType);
555 break; 522 break;
556 523
557 case AsyncMarker.ASYNC: 524 case AsyncMarker.ASYNC:
558 returnType = inferrer.addReturnTypeFor( 525 returnType = inferrer.addReturnTypeFor(
559 analyzedElement, returnType, types.asyncFutureType); 526 analyzedElement, returnType, types.asyncFutureType);
560 break; 527 break;
561 528
562 case AsyncMarker.ASYNC_STAR: 529 case AsyncMarker.ASYNC_STAR:
563 returnType = inferrer.addReturnTypeFor( 530 returnType = inferrer.addReturnTypeFor(
564 analyzedElement, returnType, types.asyncStarStreamType); 531 analyzedElement, returnType, types.asyncStarStreamType);
565 break; 532 break;
566 } 533 }
567 } 534 }
568 535
569 compiler.world.registerSideEffects(analyzedElement, sideEffects); 536 compiler.world.registerSideEffects(analyzedElement, sideEffects);
570 assert(breaksFor.isEmpty); 537 assert(breaksFor.isEmpty);
571 assert(continuesFor.isEmpty); 538 assert(continuesFor.isEmpty);
572 return returnType; 539 return returnType;
573 } 540 }
574 541
575 T visitFunctionExpression(ast.FunctionExpression node) { 542 T visitFunctionExpression(ast.FunctionExpression node) {
576 // We loose track of [this] in closures (see issue 20840). To be on 543 // We loose track of [this] in closures (see issue 20840). To be on
577 // the safe side, we mark [this] as exposed here. We could do better by 544 // the safe side, we mark [this] as exposed here. We could do better by
578 // analyzing the closure. 545 // analyzing the closure.
579 // TODO(herhut): Analyze whether closure exposes this. 546 // TODO(herhut): Analyze whether closure exposes this.
580 isThisExposed = true; 547 isThisExposed = true;
581 LocalFunctionElement element = elements.getFunctionDefinition(node); 548 LocalFunctionElement element = elements.getFunctionDefinition(node);
582 // We don't put the closure in the work queue of the 549 // We don't put the closure in the work queue of the
583 // inferrer, because it will share information with its enclosing 550 // inferrer, because it will share information with its enclosing
584 // method, like for example the types of local variables. 551 // method, like for example the types of local variables.
585 LocalsHandler closureLocals = new LocalsHandler<T>.from( 552 LocalsHandler closureLocals =
586 locals, node, useOtherTryBlock: false); 553 new LocalsHandler<T>.from(locals, node, useOtherTryBlock: false);
587 SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor<T>( 554 SimpleTypeInferrerVisitor visitor = new SimpleTypeInferrerVisitor<T>(
588 element, compiler, inferrer, closureLocals); 555 element, compiler, inferrer, closureLocals);
589 visitor.run(); 556 visitor.run();
590 inferrer.recordReturnType(element, visitor.returnType); 557 inferrer.recordReturnType(element, visitor.returnType);
591 558
592 // Record the types of captured non-boxed variables. Types of 559 // Record the types of captured non-boxed variables. Types of
593 // these variables may already be there, because of an analysis of 560 // these variables may already be there, because of an analysis of
594 // a previous closure. 561 // a previous closure.
595 ClosureClassMap nestedClosureData = 562 ClosureClassMap nestedClosureData =
596 compiler.closureToClassMapper.getMappingForNestedFunction(node); 563 compiler.closureToClassMapper.getMappingForNestedFunction(node);
597 nestedClosureData.forEachCapturedVariable((variable, field) { 564 nestedClosureData.forEachCapturedVariable((variable, field) {
598 if (!nestedClosureData.isVariableBoxed(variable)) { 565 if (!nestedClosureData.isVariableBoxed(variable)) {
599 if (variable == nestedClosureData.thisLocal) { 566 if (variable == nestedClosureData.thisLocal) {
600 inferrer.recordType(field, thisType); 567 inferrer.recordType(field, thisType);
601 } 568 }
602 // The type is null for type parameters. 569 // The type is null for type parameters.
603 if (locals.locals[variable] == null) return; 570 if (locals.locals[variable] == null) return;
604 inferrer.recordType(field, locals.locals[variable]); 571 inferrer.recordType(field, locals.locals[variable]);
605 } 572 }
606 capturedVariables.add(variable); 573 capturedVariables.add(variable);
607 }); 574 });
608 575
609 return inferrer.concreteTypes.putIfAbsent(node, () { 576 return inferrer.concreteTypes.putIfAbsent(node, () {
610 return types.allocateClosure(node, element); 577 return types.allocateClosure(node, element);
611 }); 578 });
612 } 579 }
613 580
614 T visitFunctionDeclaration(ast.FunctionDeclaration node) { 581 T visitFunctionDeclaration(ast.FunctionDeclaration node) {
615 LocalFunctionElement element = elements.getFunctionDefinition(node.function) ; 582 LocalFunctionElement element =
583 elements.getFunctionDefinition(node.function);
616 T type = inferrer.concreteTypes.putIfAbsent(node.function, () { 584 T type = inferrer.concreteTypes.putIfAbsent(node.function, () {
617 return types.allocateClosure(node.function, element); 585 return types.allocateClosure(node.function, element);
618 }); 586 });
619 locals.update(element, type, node); 587 locals.update(element, type, node);
620 visit(node.function); 588 visit(node.function);
621 return type; 589 return type;
622 } 590 }
623 591
624 T visitStringInterpolation(ast.StringInterpolation node) { 592 T visitStringInterpolation(ast.StringInterpolation node) {
625 // Interpolation could have any effects since it could call any toString() 593 // Interpolation could have any effects since it could call any toString()
(...skipping 17 matching lines...) Expand all
643 for (ast.Node element in node.elements.nodes) { 611 for (ast.Node element in node.elements.nodes) {
644 T type = visit(element); 612 T type = visit(element);
645 elementType = elementType == null 613 elementType = elementType == null
646 ? types.allocatePhi(null, null, type) 614 ? types.allocatePhi(null, null, type)
647 : types.addPhiInput(null, elementType, type); 615 : types.addPhiInput(null, elementType, type);
648 length++; 616 length++;
649 } 617 }
650 elementType = elementType == null 618 elementType = elementType == null
651 ? types.nonNullEmpty() 619 ? types.nonNullEmpty()
652 : types.simplifyPhi(null, null, elementType); 620 : types.simplifyPhi(null, null, elementType);
653 T containerType = node.isConst 621 T containerType =
654 ? types.constListType 622 node.isConst ? types.constListType : types.growableListType;
655 : types.growableListType;
656 return types.allocateList( 623 return types.allocateList(
657 containerType, 624 containerType, node, outermostElement, elementType, length);
658 node,
659 outermostElement,
660 elementType,
661 length);
662 }); 625 });
663 } 626 }
664 627
665 T visitLiteralMap(ast.LiteralMap node) { 628 T visitLiteralMap(ast.LiteralMap node) {
666 return inferrer.concreteTypes.putIfAbsent(node, () { 629 return inferrer.concreteTypes.putIfAbsent(node, () {
667 ast.NodeList entries = node.entries; 630 ast.NodeList entries = node.entries;
668 List<T> keyTypes = []; 631 List<T> keyTypes = [];
669 List<T> valueTypes = []; 632 List<T> valueTypes = [];
670 633
671 for (ast.LiteralMapEntry entry in entries) { 634 for (ast.LiteralMapEntry entry in entries) {
672 keyTypes.add(visit(entry.key)); 635 keyTypes.add(visit(entry.key));
673 valueTypes.add(visit(entry.value)); 636 valueTypes.add(visit(entry.value));
674 } 637 }
675 638
676 T type = node.isConst ? types.constMapType : types.mapType; 639 T type = node.isConst ? types.constMapType : types.mapType;
677 return types.allocateMap(type, 640 return types.allocateMap(
678 node, 641 type, node, outermostElement, keyTypes, valueTypes);
679 outermostElement,
680 keyTypes,
681 valueTypes);
682 }); 642 });
683 } 643 }
684 644
685 bool isThisOrSuper(ast.Node node) => node.isThis() || node.isSuper(); 645 bool isThisOrSuper(ast.Node node) => node.isThis() || node.isSuper();
686 646
687 bool isInClassOrSubclass(Element element) { 647 bool isInClassOrSubclass(Element element) {
688 ClassElement cls = outermostElement.enclosingClass.declaration; 648 ClassElement cls = outermostElement.enclosingClass.declaration;
689 ClassElement enclosing = element.enclosingClass.declaration; 649 ClassElement enclosing = element.enclosingClass.declaration;
690 return compiler.world.isSubclassOf(enclosing, cls); 650 return compiler.world.isSubclassOf(enclosing, cls);
691 } 651 }
692 652
693 void checkIfExposesThis(Selector selector, TypeMask mask) { 653 void checkIfExposesThis(Selector selector, TypeMask mask) {
694 if (isThisExposed) return; 654 if (isThisExposed) return;
695 inferrer.forEachElementMatching(selector, mask, (element) { 655 inferrer.forEachElementMatching(selector, mask, (element) {
696 if (element.isField) { 656 if (element.isField) {
697 if (!selector.isSetter 657 if (!selector.isSetter &&
698 && isInClassOrSubclass(element) 658 isInClassOrSubclass(element) &&
699 && !element.modifiers.isFinal 659 !element.modifiers.isFinal &&
700 && locals.fieldScope.readField(element) == null 660 locals.fieldScope.readField(element) == null &&
701 && element.initializer == null) { 661 element.initializer == null) {
702 // If the field is being used before this constructor 662 // If the field is being used before this constructor
703 // actually had a chance to initialize it, say it can be 663 // actually had a chance to initialize it, say it can be
704 // null. 664 // null.
705 inferrer.recordTypeOfNonFinalField( 665 inferrer.recordTypeOfNonFinalField(
706 analyzedElement.node, element, 666 analyzedElement.node, element, types.nullType);
707 types.nullType);
708 } 667 }
709 // Accessing a field does not expose [:this:]. 668 // Accessing a field does not expose [:this:].
710 return true; 669 return true;
711 } 670 }
712 // TODO(ngeoffray): We could do better here if we knew what we 671 // TODO(ngeoffray): We could do better here if we knew what we
713 // are calling does not expose this. 672 // are calling does not expose this.
714 isThisExposed = true; 673 isThisExposed = true;
715 return false; 674 return false;
716 }); 675 });
717 } 676 }
718 677
719 bool get inInstanceContext { 678 bool get inInstanceContext {
720 return (outermostElement.isInstanceMember && !outermostElement.isField) 679 return (outermostElement.isInstanceMember && !outermostElement.isField) ||
721 || outermostElement.isGenerativeConstructor; 680 outermostElement.isGenerativeConstructor;
722 } 681 }
723 682
724 bool treatAsInstanceMember(Element element) { 683 bool treatAsInstanceMember(Element element) {
725 return (Elements.isUnresolved(element) && inInstanceContext) 684 return (Elements.isUnresolved(element) && inInstanceContext) ||
726 || (element != null && element.isInstanceMember); 685 (element != null && element.isInstanceMember);
727 } 686 }
728 687
729 @override 688 @override
730 T handleSendSet(ast.SendSet node) { 689 T handleSendSet(ast.SendSet node) {
731 Element element = elements[node]; 690 Element element = elements[node];
732 if (!Elements.isUnresolved(element) && element.impliesType) { 691 if (!Elements.isUnresolved(element) && element.impliesType) {
733 node.visitChildren(this); 692 node.visitChildren(this);
734 return types.dynamicType; 693 return types.dynamicType;
735 } 694 }
736 695
737 Selector getterSelector = 696 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
738 elements.getGetterSelectorInComplexSendSet(node); 697 TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node);
739 TypeMask getterMask = 698 TypeMask operatorMask = elements.getOperatorTypeMaskInComplexSendSet(node);
740 elements.getGetterTypeMaskInComplexSendSet(node);
741 TypeMask operatorMask =
742 elements.getOperatorTypeMaskInComplexSendSet(node);
743 Selector setterSelector = elements.getSelector(node); 699 Selector setterSelector = elements.getSelector(node);
744 TypeMask setterMask = elements.getTypeMask(node); 700 TypeMask setterMask = elements.getTypeMask(node);
745 701
746 String op = node.assignmentOperator.source; 702 String op = node.assignmentOperator.source;
747 bool isIncrementOrDecrement = op == '++' || op == '--'; 703 bool isIncrementOrDecrement = op == '++' || op == '--';
748 704
749 T receiverType; 705 T receiverType;
750 bool isCallOnThis = false; 706 bool isCallOnThis = false;
751 if (node.receiver == null) { 707 if (node.receiver == null) {
752 if (treatAsInstanceMember(element)) { 708 if (treatAsInstanceMember(element)) {
(...skipping 25 matching lines...) Expand all
778 734
779 if (!visitingInitializers && !isThisExposed) { 735 if (!visitingInitializers && !isThisExposed) {
780 for (ast.Node node in node.arguments) { 736 for (ast.Node node in node.arguments) {
781 if (isThisOrSuper(node)) { 737 if (isThisOrSuper(node)) {
782 isThisExposed = true; 738 isThisExposed = true;
783 break; 739 break;
784 } 740 }
785 } 741 }
786 if (!isThisExposed && isCallOnThis) { 742 if (!isThisExposed && isCallOnThis) {
787 checkIfExposesThis( 743 checkIfExposesThis(
788 setterSelector, 744 setterSelector, types.newTypedSelector(receiverType, setterMask));
789 types.newTypedSelector(receiverType, setterMask));
790 if (getterSelector != null) { 745 if (getterSelector != null) {
791 checkIfExposesThis( 746 checkIfExposesThis(
792 getterSelector, 747 getterSelector, types.newTypedSelector(receiverType, getterMask));
793 types.newTypedSelector(receiverType, getterMask));
794 } 748 }
795 } 749 }
796 } 750 }
797 751
798 if (node.isIndex) { 752 if (node.isIndex) {
799 return internalError(node, "Unexpected index operation"); 753 return internalError(node, "Unexpected index operation");
800 } else if (op == '=') { 754 } else if (op == '=') {
801 return handlePlainAssignment( 755 return handlePlainAssignment(node, element, setterSelector, setterMask,
802 node, element, setterSelector, setterMask, receiverType, rhsType, 756 receiverType, rhsType, node.arguments.head);
803 node.arguments.head);
804 } else { 757 } else {
805 // [foo ??= bar], [: foo++ :] or [: foo += 1 :]. 758 // [foo ??= bar], [: foo++ :] or [: foo += 1 :].
806 T getterType; 759 T getterType;
807 T newType; 760 T newType;
808 761
809 if (Elements.isMalformed(element)) return types.dynamicType; 762 if (Elements.isMalformed(element)) return types.dynamicType;
810 763
811 if (Elements.isStaticOrTopLevelField(element)) { 764 if (Elements.isStaticOrTopLevelField(element)) {
812 Element getterElement = elements[node.selector]; 765 Element getterElement = elements[node.selector];
813 getterType = handleStaticSend( 766 getterType = handleStaticSend(
814 node, getterSelector, getterMask, getterElement, null); 767 node, getterSelector, getterMask, getterElement, null);
815 } else if (Elements.isUnresolved(element) 768 } else if (Elements.isUnresolved(element) ||
816 || element.isSetter 769 element.isSetter ||
817 || element.isField) { 770 element.isField) {
818 getterType = handleDynamicSend( 771 getterType = handleDynamicSend(
819 node, getterSelector, getterMask, receiverType, null); 772 node, getterSelector, getterMask, receiverType, null);
820 } else if (element.isLocal) { 773 } else if (element.isLocal) {
821 LocalElement local = element; 774 LocalElement local = element;
822 getterType = locals.use(local); 775 getterType = locals.use(local);
823 } else { 776 } else {
824 // Bogus SendSet, for example [: myMethod += 42 :]. 777 // Bogus SendSet, for example [: myMethod += 42 :].
825 getterType = types.dynamicType; 778 getterType = types.dynamicType;
826 } 779 }
827 780
828 if (op == '??=') { 781 if (op == '??=') {
829 newType = types.allocateDiamondPhi(getterType, rhsType); 782 newType = types.allocateDiamondPhi(getterType, rhsType);
830 } else { 783 } else {
831 Selector operatorSelector = 784 Selector operatorSelector =
832 elements.getOperatorSelectorInComplexSendSet(node); 785 elements.getOperatorSelectorInComplexSendSet(node);
833 newType = handleDynamicSend( 786 newType = handleDynamicSend(node, operatorSelector, operatorMask,
834 node, operatorSelector, operatorMask,
835 getterType, new ArgumentsTypes<T>([rhsType], null)); 787 getterType, new ArgumentsTypes<T>([rhsType], null));
836 } 788 }
837 789
838 if (Elements.isStaticOrTopLevelField(element)) { 790 if (Elements.isStaticOrTopLevelField(element)) {
839 handleStaticSend( 791 handleStaticSend(node, setterSelector, setterMask, element,
840 node, setterSelector, setterMask, element,
841 new ArgumentsTypes<T>([newType], null)); 792 new ArgumentsTypes<T>([newType], null));
842 } else if (Elements.isUnresolved(element) 793 } else if (Elements.isUnresolved(element) ||
843 || element.isSetter 794 element.isSetter ||
844 || element.isField) { 795 element.isField) {
845 handleDynamicSend(node, setterSelector, setterMask, receiverType, 796 handleDynamicSend(node, setterSelector, setterMask, receiverType,
846 new ArgumentsTypes<T>([newType], null)); 797 new ArgumentsTypes<T>([newType], null));
847 } else if (element.isLocal) { 798 } else if (element.isLocal) {
848 locals.update(element, newType, node); 799 locals.update(element, newType, node);
849 } 800 }
850 801
851 return node.isPostfix ? getterType : newType; 802 return node.isPostfix ? getterType : newType;
852 } 803 }
853 } 804 }
854 805
855 /// Handle compound index set, like `foo[0] += 42` or `foo[0]++`. 806 /// Handle compound index set, like `foo[0] += 42` or `foo[0]++`.
856 T handleCompoundIndexSet( 807 T handleCompoundIndexSet(
857 ast.SendSet node, 808 ast.SendSet node, T receiverType, T indexType, T rhsType) {
858 T receiverType, 809 Selector getterSelector = elements.getGetterSelectorInComplexSendSet(node);
859 T indexType, 810 TypeMask getterMask = elements.getGetterTypeMaskInComplexSendSet(node);
860 T rhsType) {
861 Selector getterSelector =
862 elements.getGetterSelectorInComplexSendSet(node);
863 TypeMask getterMask =
864 elements.getGetterTypeMaskInComplexSendSet(node);
865 Selector operatorSelector = 811 Selector operatorSelector =
866 elements.getOperatorSelectorInComplexSendSet(node); 812 elements.getOperatorSelectorInComplexSendSet(node);
867 TypeMask operatorMask = 813 TypeMask operatorMask = elements.getOperatorTypeMaskInComplexSendSet(node);
868 elements.getOperatorTypeMaskInComplexSendSet(node);
869 Selector setterSelector = elements.getSelector(node); 814 Selector setterSelector = elements.getSelector(node);
870 TypeMask setterMask = elements.getTypeMask(node); 815 TypeMask setterMask = elements.getTypeMask(node);
871 816
872 T getterType = handleDynamicSend( 817 T getterType = handleDynamicSend(node, getterSelector, getterMask,
873 node, 818 receiverType, new ArgumentsTypes<T>([indexType], null));
874 getterSelector,
875 getterMask,
876 receiverType,
877 new ArgumentsTypes<T>([indexType], null));
878 819
879 T returnType; 820 T returnType;
880 if (node.isIfNullAssignment) { 821 if (node.isIfNullAssignment) {
881 returnType = types.allocateDiamondPhi(getterType, rhsType); 822 returnType = types.allocateDiamondPhi(getterType, rhsType);
882 } else { 823 } else {
883 returnType = handleDynamicSend( 824 returnType = handleDynamicSend(node, operatorSelector, operatorMask,
884 node, 825 getterType, new ArgumentsTypes<T>([rhsType], null));
885 operatorSelector,
886 operatorMask,
887 getterType,
888 new ArgumentsTypes<T>([rhsType], null));
889 } 826 }
890 handleDynamicSend( 827 handleDynamicSend(node, setterSelector, setterMask, receiverType,
891 node,
892 setterSelector,
893 setterMask,
894 receiverType,
895 new ArgumentsTypes<T>([indexType, returnType], null)); 828 new ArgumentsTypes<T>([indexType, returnType], null));
896 829
897 if (node.isPostfix) { 830 if (node.isPostfix) {
898 return getterType; 831 return getterType;
899 } else { 832 } else {
900 return returnType; 833 return returnType;
901 } 834 }
902 } 835 }
903 836
904 /// Handle compound prefix/postfix operations, like `a[0]++`. 837 /// Handle compound prefix/postfix operations, like `a[0]++`.
905 T handleCompoundPrefixPostfix( 838 T handleCompoundPrefixPostfix(ast.Send node, T receiverType, T indexType) {
906 ast.Send node,
907 T receiverType,
908 T indexType) {
909 return handleCompoundIndexSet( 839 return handleCompoundIndexSet(
910 node, receiverType, indexType, types.uint31Type); 840 node, receiverType, indexType, types.uint31Type);
911 } 841 }
912 842
913 @override 843 @override
914 T visitIndexPostfix( 844 T visitIndexPostfix(ast.Send node, ast.Node receiver, ast.Node index,
915 ast.Send node, 845 op.IncDecOperator operator, _) {
916 ast.Node receiver,
917 ast.Node index,
918 op.IncDecOperator operator,
919 _) {
920 T receiverType = visit(receiver); 846 T receiverType = visit(receiver);
921 T indexType = visit(index); 847 T indexType = visit(index);
922 return handleCompoundPrefixPostfix(node, receiverType, indexType); 848 return handleCompoundPrefixPostfix(node, receiverType, indexType);
923 } 849 }
924 850
925 @override 851 @override
926 T visitIndexPrefix( 852 T visitIndexPrefix(ast.Send node, ast.Node receiver, ast.Node index,
927 ast.Send node, 853 op.IncDecOperator operator, _) {
928 ast.Node receiver,
929 ast.Node index,
930 op.IncDecOperator operator,
931 _) {
932 T receiverType = visit(receiver); 854 T receiverType = visit(receiver);
933 T indexType = visit(index); 855 T indexType = visit(index);
934 return handleCompoundPrefixPostfix(node, receiverType, indexType); 856 return handleCompoundPrefixPostfix(node, receiverType, indexType);
935 } 857 }
936 858
937 @override 859 @override
938 T visitCompoundIndexSet( 860 T visitCompoundIndexSet(ast.SendSet node, ast.Node receiver, ast.Node index,
939 ast.SendSet node, 861 op.AssignmentOperator operator, ast.Node rhs, _) {
940 ast.Node receiver,
941 ast.Node index,
942 op.AssignmentOperator operator,
943 ast.Node rhs,
944 _) {
945 T receiverType = visit(receiver); 862 T receiverType = visit(receiver);
946 T indexType = visit(index); 863 T indexType = visit(index);
947 T rhsType = visit(rhs); 864 T rhsType = visit(rhs);
948 return handleCompoundIndexSet(node, receiverType, indexType, rhsType); 865 return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
949 } 866 }
950 867
951 @override 868 @override
952 T visitIndexSetIfNull( 869 T visitIndexSetIfNull(
953 ast.SendSet node, 870 ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
954 ast.Node receiver,
955 ast.Node index,
956 ast.Node rhs,
957 _) {
958 T receiverType = visit(receiver); 871 T receiverType = visit(receiver);
959 T indexType = visit(index); 872 T indexType = visit(index);
960 T rhsType = visit(rhs); 873 T rhsType = visit(rhs);
961 return handleCompoundIndexSet(node, receiverType, indexType, rhsType); 874 return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
962 } 875 }
963 876
964 @override 877 @override
965 T visitSuperIndexPrefix( 878 T visitSuperIndexPrefix(ast.Send node, MethodElement getter,
966 ast.Send node, 879 MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
967 MethodElement getter,
968 MethodElement setter,
969 ast.Node index,
970 op.IncDecOperator operator,
971 _) {
972 T indexType = visit(index); 880 T indexType = visit(index);
973 return handleCompoundPrefixPostfix(node, superType, indexType); 881 return handleCompoundPrefixPostfix(node, superType, indexType);
974 } 882 }
975 883
976 @override 884 @override
977 T visitSuperIndexPostfix( 885 T visitSuperIndexPostfix(ast.Send node, MethodElement getter,
978 ast.Send node, 886 MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
979 MethodElement getter,
980 MethodElement setter,
981 ast.Node index,
982 op.IncDecOperator operator,
983 _) {
984 T indexType = visit(index); 887 T indexType = visit(index);
985 return handleCompoundPrefixPostfix(node, superType, indexType); 888 return handleCompoundPrefixPostfix(node, superType, indexType);
986 } 889 }
987 890
988 /// Handle compound super index set, like `super[42] =+ 2`. 891 /// Handle compound super index set, like `super[42] =+ 2`.
989 T handleSuperCompoundIndexSet( 892 T handleSuperCompoundIndexSet(
990 ast.SendSet node, 893 ast.SendSet node, ast.Node index, ast.Node rhs) {
991 ast.Node index,
992 ast.Node rhs) {
993 T receiverType = superType; 894 T receiverType = superType;
994 T indexType = visit(index); 895 T indexType = visit(index);
995 T rhsType = visit(rhs); 896 T rhsType = visit(rhs);
996 return handleCompoundIndexSet(node, receiverType, indexType, rhsType); 897 return handleCompoundIndexSet(node, receiverType, indexType, rhsType);
997 } 898 }
998 899
999 @override 900 @override
1000 T visitSuperCompoundIndexSet( 901 T visitSuperCompoundIndexSet(
1001 ast.SendSet node, 902 ast.SendSet node,
1002 MethodElement getter, 903 MethodElement getter,
1003 MethodElement setter, 904 MethodElement setter,
1004 ast.Node index, 905 ast.Node index,
1005 op.AssignmentOperator operator, 906 op.AssignmentOperator operator,
1006 ast.Node rhs, 907 ast.Node rhs,
1007 _) { 908 _) {
1008 return handleSuperCompoundIndexSet(node, index, rhs); 909 return handleSuperCompoundIndexSet(node, index, rhs);
1009 } 910 }
1010 911
1011 @override 912 @override
1012 T visitSuperIndexSetIfNull( 913 T visitSuperIndexSetIfNull(ast.SendSet node, MethodElement getter,
1013 ast.SendSet node, 914 MethodElement setter, ast.Node index, ast.Node rhs, _) {
1014 MethodElement getter,
1015 MethodElement setter,
1016 ast.Node index,
1017 ast.Node rhs,
1018 _) {
1019 return handleSuperCompoundIndexSet(node, index, rhs); 915 return handleSuperCompoundIndexSet(node, index, rhs);
1020 } 916 }
1021 917
1022 @override 918 @override
1023 T visitUnresolvedSuperCompoundIndexSet( 919 T visitUnresolvedSuperCompoundIndexSet(ast.Send node, Element element,
1024 ast.Send node, 920 ast.Node index, op.AssignmentOperator operator, ast.Node rhs, _) {
1025 Element element,
1026 ast.Node index,
1027 op.AssignmentOperator operator,
1028 ast.Node rhs,
1029 _) {
1030 return handleSuperCompoundIndexSet(node, index, rhs); 921 return handleSuperCompoundIndexSet(node, index, rhs);
1031 } 922 }
1032 923
1033 @override 924 @override
1034 T visitUnresolvedSuperIndexSetIfNull( 925 T visitUnresolvedSuperIndexSetIfNull(
1035 ast.Send node, 926 ast.Send node, Element element, ast.Node index, ast.Node rhs, _) {
1036 Element element,
1037 ast.Node index,
1038 ast.Node rhs,
1039 _) {
1040 return handleSuperCompoundIndexSet(node, index, rhs); 927 return handleSuperCompoundIndexSet(node, index, rhs);
1041 } 928 }
1042 929
1043 @override 930 @override
1044 T visitUnresolvedSuperGetterCompoundIndexSet( 931 T visitUnresolvedSuperGetterCompoundIndexSet(
1045 ast.SendSet node, 932 ast.SendSet node,
1046 Element element, 933 Element element,
1047 MethodElement setter, 934 MethodElement setter,
1048 ast.Node index, 935 ast.Node index,
1049 op.AssignmentOperator operator, 936 op.AssignmentOperator operator,
1050 ast.Node rhs, 937 ast.Node rhs,
1051 _) { 938 _) {
1052 return handleSuperCompoundIndexSet(node, index, rhs); 939 return handleSuperCompoundIndexSet(node, index, rhs);
1053 } 940 }
1054 941
1055 @override 942 @override
1056 T visitUnresolvedSuperGetterIndexSetIfNull( 943 T visitUnresolvedSuperGetterIndexSetIfNull(ast.SendSet node, Element element,
1057 ast.SendSet node, 944 MethodElement setter, ast.Node index, ast.Node rhs, _) {
1058 Element element,
1059 MethodElement setter,
1060 ast.Node index,
1061 ast.Node rhs,
1062 _) {
1063 return handleSuperCompoundIndexSet(node, index, rhs); 945 return handleSuperCompoundIndexSet(node, index, rhs);
1064 } 946 }
1065 947
1066 @override 948 @override
1067 T visitUnresolvedSuperSetterCompoundIndexSet( 949 T visitUnresolvedSuperSetterCompoundIndexSet(
1068 ast.SendSet node, 950 ast.SendSet node,
1069 MethodElement getter, 951 MethodElement getter,
1070 Element element, 952 Element element,
1071 ast.Node index, 953 ast.Node index,
1072 op.AssignmentOperator operator, 954 op.AssignmentOperator operator,
1073 ast.Node rhs, 955 ast.Node rhs,
1074 _) { 956 _) {
1075 return handleSuperCompoundIndexSet(node, index, rhs); 957 return handleSuperCompoundIndexSet(node, index, rhs);
1076 } 958 }
1077 959
1078 @override 960 @override
1079 T visitUnresolvedSuperSetterIndexSetIfNull( 961 T visitUnresolvedSuperSetterIndexSetIfNull(ast.SendSet node,
1080 ast.SendSet node, 962 MethodElement getter, Element element, ast.Node index, ast.Node rhs, _) {
1081 MethodElement getter,
1082 Element element,
1083 ast.Node index,
1084 ast.Node rhs,
1085 _) {
1086 return handleSuperCompoundIndexSet(node, index, rhs); 963 return handleSuperCompoundIndexSet(node, index, rhs);
1087 } 964 }
1088 965
1089 @override 966 @override
1090 T visitUnresolvedSuperIndexPrefix( 967 T visitUnresolvedSuperIndexPrefix(ast.Send node, Element element,
1091 ast.Send node, 968 ast.Node index, op.IncDecOperator operator, _) {
1092 Element element,
1093 ast.Node index,
1094 op.IncDecOperator operator,
1095 _) {
1096 T indexType = visit(index); 969 T indexType = visit(index);
1097 return handleCompoundPrefixPostfix(node, superType, indexType); 970 return handleCompoundPrefixPostfix(node, superType, indexType);
1098 } 971 }
1099 972
1100 @override 973 @override
1101 T visitUnresolvedSuperGetterIndexPrefix( 974 T visitUnresolvedSuperGetterIndexPrefix(ast.SendSet node, Element element,
1102 ast.SendSet node, 975 MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
1103 Element element,
1104 MethodElement setter,
1105 ast.Node index,
1106 op.IncDecOperator operator,
1107 _) {
1108 T indexType = visit(index); 976 T indexType = visit(index);
1109 return handleCompoundPrefixPostfix(node, superType, indexType); 977 return handleCompoundPrefixPostfix(node, superType, indexType);
1110 } 978 }
1111 979
1112 @override 980 @override
1113 T visitUnresolvedSuperSetterIndexPrefix( 981 T visitUnresolvedSuperSetterIndexPrefix(
1114 ast.SendSet node, 982 ast.SendSet node,
1115 MethodElement getter, 983 MethodElement getter,
1116 Element element, 984 Element element,
1117 ast.Node index, 985 ast.Node index,
1118 op.IncDecOperator operator, 986 op.IncDecOperator operator,
1119 _) { 987 _) {
1120 T indexType = visit(index); 988 T indexType = visit(index);
1121 return handleCompoundPrefixPostfix(node, superType, indexType); 989 return handleCompoundPrefixPostfix(node, superType, indexType);
1122 } 990 }
1123 991
1124 @override 992 @override
1125 T visitUnresolvedSuperIndexPostfix( 993 T visitUnresolvedSuperIndexPostfix(ast.Send node, Element element,
1126 ast.Send node, 994 ast.Node index, op.IncDecOperator operator, _) {
1127 Element element,
1128 ast.Node index,
1129 op.IncDecOperator operator,
1130 _) {
1131 T indexType = visit(index); 995 T indexType = visit(index);
1132 return handleCompoundPrefixPostfix(node, superType, indexType); 996 return handleCompoundPrefixPostfix(node, superType, indexType);
1133 } 997 }
1134 998
1135 @override 999 @override
1136 T visitUnresolvedSuperGetterIndexPostfix( 1000 T visitUnresolvedSuperGetterIndexPostfix(ast.SendSet node, Element element,
1137 ast.SendSet node, 1001 MethodElement setter, ast.Node index, op.IncDecOperator operator, _) {
1138 Element element,
1139 MethodElement setter,
1140 ast.Node index,
1141 op.IncDecOperator operator,
1142 _) {
1143 T indexType = visit(index); 1002 T indexType = visit(index);
1144 return handleCompoundPrefixPostfix(node, superType, indexType); 1003 return handleCompoundPrefixPostfix(node, superType, indexType);
1145 } 1004 }
1146 1005
1147 @override 1006 @override
1148 T visitUnresolvedSuperSetterIndexPostfix( 1007 T visitUnresolvedSuperSetterIndexPostfix(
1149 ast.SendSet node, 1008 ast.SendSet node,
1150 MethodElement getter, 1009 MethodElement getter,
1151 Element element, 1010 Element element,
1152 ast.Node index, 1011 ast.Node index,
1153 op.IncDecOperator operator, 1012 op.IncDecOperator operator,
1154 _) { 1013 _) {
1155 T indexType = visit(index); 1014 T indexType = visit(index);
1156 return handleCompoundPrefixPostfix(node, superType, indexType); 1015 return handleCompoundPrefixPostfix(node, superType, indexType);
1157 } 1016 }
1158 1017
1159 /// Handle index set, like `foo[0] = 42`. 1018 /// Handle index set, like `foo[0] = 42`.
1160 T handleIndexSet(ast.SendSet node, T receiverType, T indexType, T rhsType) { 1019 T handleIndexSet(ast.SendSet node, T receiverType, T indexType, T rhsType) {
1161 Selector setterSelector = elements.getSelector(node); 1020 Selector setterSelector = elements.getSelector(node);
1162 TypeMask setterMask = elements.getTypeMask(node); 1021 TypeMask setterMask = elements.getTypeMask(node);
1163 handleDynamicSend( 1022 handleDynamicSend(node, setterSelector, setterMask, receiverType,
1164 node,
1165 setterSelector,
1166 setterMask,
1167 receiverType,
1168 new ArgumentsTypes<T>([indexType, rhsType], null)); 1023 new ArgumentsTypes<T>([indexType, rhsType], null));
1169 return rhsType; 1024 return rhsType;
1170 } 1025 }
1171 1026
1172 @override 1027 @override
1173 T visitIndexSet( 1028 T visitIndexSet(
1174 ast.SendSet node, 1029 ast.SendSet node, ast.Node receiver, ast.Node index, ast.Node rhs, _) {
1175 ast.Node receiver,
1176 ast.Node index,
1177 ast.Node rhs,
1178 _) {
1179 T receiverType = visit(receiver); 1030 T receiverType = visit(receiver);
1180 T indexType = visit(index); 1031 T indexType = visit(index);
1181 T rhsType = visit(rhs); 1032 T rhsType = visit(rhs);
1182 return handleIndexSet(node, receiverType, indexType, rhsType); 1033 return handleIndexSet(node, receiverType, indexType, rhsType);
1183 } 1034 }
1184 1035
1185 /// Handle super index set, like `super[42] = true`. 1036 /// Handle super index set, like `super[42] = true`.
1186 T handleSuperIndexSet( 1037 T handleSuperIndexSet(ast.SendSet node, ast.Node index, ast.Node rhs) {
1187 ast.SendSet node,
1188 ast.Node index,
1189 ast.Node rhs) {
1190 T receiverType = superType; 1038 T receiverType = superType;
1191 T indexType = visit(index); 1039 T indexType = visit(index);
1192 T rhsType = visit(rhs); 1040 T rhsType = visit(rhs);
1193 return handleIndexSet(node, receiverType, indexType, rhsType); 1041 return handleIndexSet(node, receiverType, indexType, rhsType);
1194 } 1042 }
1195 1043
1196 @override 1044 @override
1197 T visitSuperIndexSet( 1045 T visitSuperIndexSet(ast.SendSet node, FunctionElement function,
1198 ast.SendSet node, 1046 ast.Node index, ast.Node rhs, _) {
1199 FunctionElement function,
1200 ast.Node index,
1201 ast.Node rhs,
1202 _) {
1203 return handleSuperIndexSet(node, index, rhs); 1047 return handleSuperIndexSet(node, index, rhs);
1204 } 1048 }
1205 1049
1206 @override 1050 @override
1207 T visitUnresolvedSuperIndexSet( 1051 T visitUnresolvedSuperIndexSet(
1208 ast.SendSet node, 1052 ast.SendSet node, Element element, ast.Node index, ast.Node rhs, _) {
1209 Element element,
1210 ast.Node index,
1211 ast.Node rhs,
1212 _) {
1213 return handleSuperIndexSet(node, index, rhs); 1053 return handleSuperIndexSet(node, index, rhs);
1214 } 1054 }
1215 1055
1216 T handlePlainAssignment(ast.Node node, 1056 T handlePlainAssignment(
1217 Element element, 1057 ast.Node node,
1218 Selector setterSelector, 1058 Element element,
1219 TypeMask setterMask, 1059 Selector setterSelector,
1220 T receiverType, 1060 TypeMask setterMask,
1221 T rhsType, 1061 T receiverType,
1222 ast.Node rhs) { 1062 T rhsType,
1063 ast.Node rhs) {
1223 ArgumentsTypes arguments = new ArgumentsTypes<T>([rhsType], null); 1064 ArgumentsTypes arguments = new ArgumentsTypes<T>([rhsType], null);
1224 if (Elements.isMalformed(element)) { 1065 if (Elements.isMalformed(element)) {
1225 // Code will always throw. 1066 // Code will always throw.
1226 } else if (Elements.isStaticOrTopLevelField(element)) { 1067 } else if (Elements.isStaticOrTopLevelField(element)) {
1227 handleStaticSend(node, setterSelector, setterMask, element, arguments); 1068 handleStaticSend(node, setterSelector, setterMask, element, arguments);
1228 } else if (Elements.isUnresolved(element) || element.isSetter) { 1069 } else if (Elements.isUnresolved(element) || element.isSetter) {
1229 if (analyzedElement.isGenerativeConstructor 1070 if (analyzedElement.isGenerativeConstructor &&
1230 && (node.asSendSet() != null) 1071 (node.asSendSet() != null) &&
1231 && (node.asSendSet().receiver != null) 1072 (node.asSendSet().receiver != null) &&
1232 && node.asSendSet().receiver.isThis()) { 1073 node.asSendSet().receiver.isThis()) {
1233 Iterable<Element> targets = compiler.world.allFunctions.filter( 1074 Iterable<Element> targets = compiler.world.allFunctions.filter(
1234 setterSelector, 1075 setterSelector, types.newTypedSelector(thisType, setterMask));
1235 types.newTypedSelector(thisType, setterMask));
1236 // We just recognized a field initialization of the form: 1076 // We just recognized a field initialization of the form:
1237 // `this.foo = 42`. If there is only one target, we can update 1077 // `this.foo = 42`. If there is only one target, we can update
1238 // its type. 1078 // its type.
1239 if (targets.length == 1) { 1079 if (targets.length == 1) {
1240 Element single = targets.first; 1080 Element single = targets.first;
1241 if (single.isField) { 1081 if (single.isField) {
1242 locals.updateField(single, rhsType); 1082 locals.updateField(single, rhsType);
1243 } 1083 }
1244 } 1084 }
1245 } 1085 }
(...skipping 15 matching lines...) Expand all
1261 } 1101 }
1262 } 1102 }
1263 } else if (element.isLocal) { 1103 } else if (element.isLocal) {
1264 locals.update(element, rhsType, node); 1104 locals.update(element, rhsType, node);
1265 } 1105 }
1266 return rhsType; 1106 return rhsType;
1267 } 1107 }
1268 1108
1269 /// Handle a super access or invocation that results in a `noSuchMethod` call. 1109 /// Handle a super access or invocation that results in a `noSuchMethod` call.
1270 T handleErroneousSuperSend(ast.Send node) { 1110 T handleErroneousSuperSend(ast.Send node) {
1271 ArgumentsTypes arguments = node.isPropertyAccess 1111 ArgumentsTypes arguments =
1272 ? null 1112 node.isPropertyAccess ? null : analyzeArguments(node.arguments);
1273 : analyzeArguments(node.arguments);
1274 Selector selector = elements.getSelector(node); 1113 Selector selector = elements.getSelector(node);
1275 TypeMask mask = elements.getTypeMask(node); 1114 TypeMask mask = elements.getTypeMask(node);
1276 // TODO(herhut): We could do better here if we knew what we 1115 // TODO(herhut): We could do better here if we knew what we
1277 // are calling does not expose this. 1116 // are calling does not expose this.
1278 isThisExposed = true; 1117 isThisExposed = true;
1279 // Ensure we create a node, to make explicit the call to the 1118 // Ensure we create a node, to make explicit the call to the
1280 // `noSuchMethod` handler. 1119 // `noSuchMethod` handler.
1281 return handleDynamicSend(node, selector, mask, superType, arguments); 1120 return handleDynamicSend(node, selector, mask, superType, arguments);
1282 } 1121 }
1283 1122
1284 /// Handle a .call invocation on the values retrieved from the super 1123 /// Handle a .call invocation on the values retrieved from the super
1285 /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter. 1124 /// [element]. For instance `super.foo(bar)` where `foo` is a field or getter.
1286 T handleSuperClosureCall( 1125 T handleSuperClosureCall(
1287 ast.Send node, 1126 ast.Send node, Element element, ast.NodeList arguments) {
1288 Element element,
1289 ast.NodeList arguments) {
1290 ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes); 1127 ArgumentsTypes argumentTypes = analyzeArguments(arguments.nodes);
1291 Selector selector = elements.getSelector(node); 1128 Selector selector = elements.getSelector(node);
1292 TypeMask mask = elements.getTypeMask(node); 1129 TypeMask mask = elements.getTypeMask(node);
1293 // TODO(herhut): We could do better here if we knew what we 1130 // TODO(herhut): We could do better here if we knew what we
1294 // are calling does not expose this. 1131 // are calling does not expose this.
1295 isThisExposed = true; 1132 isThisExposed = true;
1296 return inferrer.registerCalledClosure( 1133 return inferrer.registerCalledClosure(
1297 node, selector, mask, inferrer.typeOfElement(element), 1134 node,
1298 outermostElement, argumentTypes, sideEffects, inLoop); 1135 selector,
1136 mask,
1137 inferrer.typeOfElement(element),
1138 outermostElement,
1139 argumentTypes,
1140 sideEffects,
1141 inLoop);
1299 } 1142 }
1300 1143
1301 /// Handle an invocation of super [method]. 1144 /// Handle an invocation of super [method].
1302 T handleSuperMethodInvoke(ast.Send node, 1145 T handleSuperMethodInvoke(
1303 MethodElement method, 1146 ast.Send node, MethodElement method, ArgumentsTypes arguments) {
1304 ArgumentsTypes arguments) {
1305 // TODO(herhut): We could do better here if we knew what we 1147 // TODO(herhut): We could do better here if we knew what we
1306 // are calling does not expose this. 1148 // are calling does not expose this.
1307 isThisExposed = true; 1149 isThisExposed = true;
1308 Selector selector = elements.getSelector(node); 1150 Selector selector = elements.getSelector(node);
1309 TypeMask mask = elements.getTypeMask(node); 1151 TypeMask mask = elements.getTypeMask(node);
1310 return handleStaticSend( 1152 return handleStaticSend(node, selector, mask, method, arguments);
1311 node, selector, mask, method, arguments);
1312 } 1153 }
1313 1154
1314 /// Handle access to a super field or getter [element]. 1155 /// Handle access to a super field or getter [element].
1315 T handleSuperGet(ast.Send node, 1156 T handleSuperGet(ast.Send node, Element element) {
1316 Element element) {
1317 // TODO(herhut): We could do better here if we knew what we 1157 // TODO(herhut): We could do better here if we knew what we
1318 // are calling does not expose this. 1158 // are calling does not expose this.
1319 isThisExposed = true; 1159 isThisExposed = true;
1320 Selector selector = elements.getSelector(node); 1160 Selector selector = elements.getSelector(node);
1321 TypeMask mask = elements.getTypeMask(node); 1161 TypeMask mask = elements.getTypeMask(node);
1322 return handleStaticSend( 1162 return handleStaticSend(node, selector, mask, element, null);
1323 node, selector, mask, element, null);
1324 } 1163 }
1325 1164
1326 @override 1165 @override
1327 T visitUnresolvedSuperIndex( 1166 T visitUnresolvedSuperIndex(
1328 ast.Send node, 1167 ast.Send node, Element element, ast.Node index, _) {
1329 Element element,
1330 ast.Node index,
1331 _) {
1332 return handleErroneousSuperSend(node); 1168 return handleErroneousSuperSend(node);
1333 } 1169 }
1334 1170
1335 @override 1171 @override
1336 T visitUnresolvedSuperUnary( 1172 T visitUnresolvedSuperUnary(
1337 ast.Send node, 1173 ast.Send node, op.UnaryOperator operator, Element element, _) {
1338 op.UnaryOperator operator,
1339 Element element,
1340 _) {
1341 return handleErroneousSuperSend(node); 1174 return handleErroneousSuperSend(node);
1342 } 1175 }
1343 1176
1344 @override 1177 @override
1345 T visitUnresolvedSuperBinary( 1178 T visitUnresolvedSuperBinary(ast.Send node, Element element,
1346 ast.Send node, 1179 op.BinaryOperator operator, ast.Node argument, _) {
1347 Element element,
1348 op.BinaryOperator operator,
1349 ast.Node argument,
1350 _) {
1351 return handleErroneousSuperSend(node); 1180 return handleErroneousSuperSend(node);
1352 } 1181 }
1353 1182
1354 @override 1183 @override
1355 T visitUnresolvedSuperGet( 1184 T visitUnresolvedSuperGet(ast.Send node, Element element, _) {
1356 ast.Send node,
1357 Element element,
1358 _) {
1359 return handleErroneousSuperSend(node); 1185 return handleErroneousSuperSend(node);
1360 } 1186 }
1361 1187
1362 @override 1188 @override
1363 T visitSuperSetterGet( 1189 T visitSuperSetterGet(ast.Send node, MethodElement setter, _) {
1364 ast.Send node,
1365 MethodElement setter,
1366 _) {
1367 return handleErroneousSuperSend(node); 1190 return handleErroneousSuperSend(node);
1368 } 1191 }
1369 1192
1370 @override 1193 @override
1371 T visitSuperGetterSet( 1194 T visitSuperGetterSet(ast.Send node, MethodElement getter, ast.Node rhs, _) {
1372 ast.Send node,
1373 MethodElement getter,
1374 ast.Node rhs,
1375 _) {
1376 return handleErroneousSuperSend(node); 1195 return handleErroneousSuperSend(node);
1377 } 1196 }
1378 1197
1379 @override 1198 @override
1380 T visitUnresolvedSuperSet( 1199 T visitUnresolvedSuperSet(ast.Send node, Element element, ast.Node rhs, _) {
1381 ast.Send node,
1382 Element element,
1383 ast.Node rhs,
1384 _) {
1385 return handleErroneousSuperSend(node); 1200 return handleErroneousSuperSend(node);
1386 } 1201 }
1387 1202
1388 @override 1203 @override
1389 T visitUnresolvedSuperInvoke( 1204 T visitUnresolvedSuperInvoke(
1390 ast.Send node, 1205 ast.Send node, Element element, ast.Node argument, Selector selector, _) {
1391 Element element,
1392 ast.Node argument,
1393 Selector selector,
1394 _) {
1395 return handleErroneousSuperSend(node); 1206 return handleErroneousSuperSend(node);
1396 } 1207 }
1397 1208
1398 @override 1209 @override
1399 T visitSuperFieldGet( 1210 T visitSuperFieldGet(ast.Send node, FieldElement field, _) {
1400 ast.Send node,
1401 FieldElement field,
1402 _) {
1403 return handleSuperGet(node, field); 1211 return handleSuperGet(node, field);
1404 } 1212 }
1405 1213
1406 @override 1214 @override
1407 T visitSuperGetterGet( 1215 T visitSuperGetterGet(ast.Send node, MethodElement method, _) {
1408 ast.Send node,
1409 MethodElement method,
1410 _) {
1411 return handleSuperGet(node, method); 1216 return handleSuperGet(node, method);
1412 } 1217 }
1413 1218
1414 @override 1219 @override
1415 T visitSuperMethodGet( 1220 T visitSuperMethodGet(ast.Send node, MethodElement method, _) {
1416 ast.Send node,
1417 MethodElement method,
1418 _) {
1419 return handleSuperGet(node, method); 1221 return handleSuperGet(node, method);
1420 } 1222 }
1421 1223
1422 @override 1224 @override
1423 T visitSuperFieldInvoke( 1225 T visitSuperFieldInvoke(ast.Send node, FieldElement field,
1424 ast.Send node, 1226 ast.NodeList arguments, CallStructure callStructure, _) {
1425 FieldElement field,
1426 ast.NodeList arguments,
1427 CallStructure callStructure,
1428 _) {
1429 return handleSuperClosureCall(node, field, arguments); 1227 return handleSuperClosureCall(node, field, arguments);
1430 } 1228 }
1431 1229
1432 @override 1230 @override
1433 T visitSuperGetterInvoke( 1231 T visitSuperGetterInvoke(ast.Send node, MethodElement getter,
1434 ast.Send node, 1232 ast.NodeList arguments, CallStructure callStructure, _) {
1435 MethodElement getter,
1436 ast.NodeList arguments,
1437 CallStructure callStructure,
1438 _) {
1439 return handleSuperClosureCall(node, getter, arguments); 1233 return handleSuperClosureCall(node, getter, arguments);
1440 } 1234 }
1441 1235
1442 @override 1236 @override
1443 T visitSuperMethodInvoke( 1237 T visitSuperMethodInvoke(ast.Send node, MethodElement method,
1444 ast.Send node, 1238 ast.NodeList arguments, CallStructure callStructure, _) {
1445 MethodElement method,
1446 ast.NodeList arguments,
1447 CallStructure callStructure,
1448 _) {
1449 return handleSuperMethodInvoke( 1239 return handleSuperMethodInvoke(
1450 node, method, analyzeArguments(arguments.nodes)); 1240 node, method, analyzeArguments(arguments.nodes));
1451 } 1241 }
1452 1242
1453 @override 1243 @override
1454 T visitSuperSetterInvoke( 1244 T visitSuperSetterInvoke(ast.Send node, FunctionElement setter,
1455 ast.Send node, 1245 ast.NodeList arguments, CallStructure callStructure, _) {
1456 FunctionElement setter,
1457 ast.NodeList arguments,
1458 CallStructure callStructure,
1459 _) {
1460 return handleErroneousSuperSend(node); 1246 return handleErroneousSuperSend(node);
1461 } 1247 }
1462 1248
1463 @override 1249 @override
1464 T visitSuperIndex( 1250 T visitSuperIndex(ast.Send node, MethodElement method, ast.Node index, _) {
1465 ast.Send node,
1466 MethodElement method,
1467 ast.Node index,
1468 _) {
1469 return handleSuperMethodInvoke( 1251 return handleSuperMethodInvoke(
1470 node, method, analyzeArguments(node.arguments)); 1252 node, method, analyzeArguments(node.arguments));
1471 } 1253 }
1472 1254
1473 @override 1255 @override
1474 T visitSuperEquals( 1256 T visitSuperEquals(
1475 ast.Send node, 1257 ast.Send node, MethodElement method, ast.Node argument, _) {
1476 MethodElement method,
1477 ast.Node argument,
1478 _) {
1479 // TODO(johnniwinther): Special case ==. 1258 // TODO(johnniwinther): Special case ==.
1480 return handleSuperMethodInvoke( 1259 return handleSuperMethodInvoke(
1481 node, method, analyzeArguments(node.arguments)); 1260 node, method, analyzeArguments(node.arguments));
1482 } 1261 }
1483 1262
1484 @override 1263 @override
1485 T visitSuperNotEquals( 1264 T visitSuperNotEquals(
1486 ast.Send node, 1265 ast.Send node, MethodElement method, ast.Node argument, _) {
1487 MethodElement method,
1488 ast.Node argument,
1489 _) {
1490 // TODO(johnniwinther): Special case !=. 1266 // TODO(johnniwinther): Special case !=.
1491 return handleSuperMethodInvoke( 1267 return handleSuperMethodInvoke(
1492 node, method, analyzeArguments(node.arguments)); 1268 node, method, analyzeArguments(node.arguments));
1493 } 1269 }
1494 1270
1495 @override 1271 @override
1496 T visitSuperBinary( 1272 T visitSuperBinary(ast.Send node, MethodElement method,
1497 ast.Send node, 1273 op.BinaryOperator operator, ast.Node argument, _) {
1498 MethodElement method,
1499 op.BinaryOperator operator,
1500 ast.Node argument,
1501 _) {
1502 return handleSuperMethodInvoke( 1274 return handleSuperMethodInvoke(
1503 node, method, analyzeArguments(node.arguments)); 1275 node, method, analyzeArguments(node.arguments));
1504 } 1276 }
1505 1277
1506 @override 1278 @override
1507 T visitSuperUnary( 1279 T visitSuperUnary(
1508 ast.Send node, 1280 ast.Send node, op.UnaryOperator operator, MethodElement method, _) {
1509 op.UnaryOperator operator,
1510 MethodElement method,
1511 _) {
1512 return handleSuperMethodInvoke( 1281 return handleSuperMethodInvoke(
1513 node, method, analyzeArguments(node.arguments)); 1282 node, method, analyzeArguments(node.arguments));
1514 } 1283 }
1515 1284
1516 @override 1285 @override
1517 T visitSuperMethodIncompatibleInvoke( 1286 T visitSuperMethodIncompatibleInvoke(ast.Send node, MethodElement method,
1518 ast.Send node, 1287 ast.NodeList arguments, CallStructure callStructure, _) {
1519 MethodElement method,
1520 ast.NodeList arguments,
1521 CallStructure callStructure,
1522 _) {
1523 return handleErroneousSuperSend(node); 1288 return handleErroneousSuperSend(node);
1524 } 1289 }
1525 1290
1526 // Try to find the length given to a fixed array constructor call. 1291 // Try to find the length given to a fixed array constructor call.
1527 int findLength(ast.Send node) { 1292 int findLength(ast.Send node) {
1528 ast.Node firstArgument = node.arguments.head; 1293 ast.Node firstArgument = node.arguments.head;
1529 Element element = elements[firstArgument]; 1294 Element element = elements[firstArgument];
1530 ast.LiteralInt length = firstArgument.asLiteralInt(); 1295 ast.LiteralInt length = firstArgument.asLiteralInt();
1531 if (length != null) { 1296 if (length != null) {
1532 return length.value; 1297 return length.value;
1533 } else if (element != null 1298 } else if (element != null &&
1534 && element.isField 1299 element.isField &&
1535 && Elements.isStaticOrTopLevelField(element) 1300 Elements.isStaticOrTopLevelField(element) &&
1536 && compiler.world.fieldNeverChanges(element)) { 1301 compiler.world.fieldNeverChanges(element)) {
1537 ConstantValue value = 1302 ConstantValue value =
1538 compiler.backend.constants.getConstantValueForVariable(element); 1303 compiler.backend.constants.getConstantValueForVariable(element);
1539 if (value != null && value.isInt) { 1304 if (value != null && value.isInt) {
1540 IntConstantValue intValue = value; 1305 IntConstantValue intValue = value;
1541 return intValue.primitiveValue; 1306 return intValue.primitiveValue;
1542 } 1307 }
1543 } 1308 }
1544 return null; 1309 return null;
1545 } 1310 }
1546 1311
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 // match the function element. 1352 // match the function element.
1588 // TODO(polux): return nonNullEmpty and check it doesn't break anything 1353 // TODO(polux): return nonNullEmpty and check it doesn't break anything
1589 if (!selector.applies(target, compiler.world) || 1354 if (!selector.applies(target, compiler.world) ||
1590 (mask != null && !mask.canHit(target, selector, compiler.world))) { 1355 (mask != null && !mask.canHit(target, selector, compiler.world))) {
1591 return types.dynamicType; 1356 return types.dynamicType;
1592 } 1357 }
1593 1358
1594 T returnType = handleStaticSend(node, selector, mask, target, arguments); 1359 T returnType = handleStaticSend(node, selector, mask, target, arguments);
1595 if (Elements.isGrowableListConstructorCall(constructor, node, compiler)) { 1360 if (Elements.isGrowableListConstructorCall(constructor, node, compiler)) {
1596 return inferrer.concreteTypes.putIfAbsent( 1361 return inferrer.concreteTypes.putIfAbsent(
1597 node, () => types.allocateList( 1362 node,
1598 types.growableListType, node, outermostElement, 1363 () => types.allocateList(types.growableListType, node,
1599 types.nonNullEmpty(), 0)); 1364 outermostElement, types.nonNullEmpty(), 0));
1600 } else if (Elements.isFixedListConstructorCall(constructor, node, compiler) 1365 } else if (Elements.isFixedListConstructorCall(
1601 || Elements.isFilledListConstructorCall(constructor, node, compiler)) { 1366 constructor, node, compiler) ||
1602 1367 Elements.isFilledListConstructorCall(constructor, node, compiler)) {
1603 int length = findLength(node); 1368 int length = findLength(node);
1604 T elementType = 1369 T elementType =
1605 Elements.isFixedListConstructorCall(constructor, node, compiler) 1370 Elements.isFixedListConstructorCall(constructor, node, compiler)
1606 ? types.nullType 1371 ? types.nullType
1607 : arguments.positional[1]; 1372 : arguments.positional[1];
1608 1373
1609 return inferrer.concreteTypes.putIfAbsent( 1374 return inferrer.concreteTypes.putIfAbsent(
1610 node, () => types.allocateList( 1375 node,
1611 types.fixedListType, node, outermostElement, 1376 () => types.allocateList(types.fixedListType, node, outermostElement,
1612 elementType, length)); 1377 elementType, length));
1613 } else if ( 1378 } else if (Elements.isConstructorOfTypedArraySubclass(
1614 Elements.isConstructorOfTypedArraySubclass(constructor, compiler)) { 1379 constructor, compiler)) {
1615 int length = findLength(node); 1380 int length = findLength(node);
1616 T elementType = inferrer.returnTypeOfElement( 1381 T elementType = inferrer
1617 target.enclosingClass.lookupMember('[]')); 1382 .returnTypeOfElement(target.enclosingClass.lookupMember('[]'));
1618 return inferrer.concreteTypes.putIfAbsent( 1383 return inferrer.concreteTypes.putIfAbsent(
1619 node, () => types.allocateList( 1384 node,
1620 types.nonNullExact(target.enclosingClass), node, 1385 () => types.allocateList(types.nonNullExact(target.enclosingClass),
1621 outermostElement, elementType, length)); 1386 node, outermostElement, elementType, length));
1622 } else { 1387 } else {
1623 return returnType; 1388 return returnType;
1624 } 1389 }
1625 } 1390 }
1626 1391
1627 @override 1392 @override
1628 T bulkHandleNew(ast.NewExpression node, _) { 1393 T bulkHandleNew(ast.NewExpression node, _) {
1629 Element element = elements[node.send]; 1394 Element element = elements[node.send];
1630 return handleConstructorSend(node.send, element); 1395 return handleConstructorSend(node.send, element);
1631 } 1396 }
1632 1397
1633 @override 1398 @override
1634 T errorNonConstantConstructorInvoke( 1399 T errorNonConstantConstructorInvoke(ast.NewExpression node, Element element,
1635 ast.NewExpression node, 1400 DartType type, ast.NodeList arguments, CallStructure callStructure, _) {
1636 Element element,
1637 DartType type,
1638 ast.NodeList arguments,
1639 CallStructure callStructure,
1640 _) {
1641 return bulkHandleNew(node, _); 1401 return bulkHandleNew(node, _);
1642 } 1402 }
1643 1403
1644 /// Handle invocation of a top level or static field or getter [element]. 1404 /// Handle invocation of a top level or static field or getter [element].
1645 T handleStaticFieldOrGetterInvoke(ast.Send node, Element element) { 1405 T handleStaticFieldOrGetterInvoke(ast.Send node, Element element) {
1646 ArgumentsTypes arguments = analyzeArguments(node.arguments); 1406 ArgumentsTypes arguments = analyzeArguments(node.arguments);
1647 Selector selector = elements.getSelector(node); 1407 Selector selector = elements.getSelector(node);
1648 TypeMask mask = elements.getTypeMask(node); 1408 TypeMask mask = elements.getTypeMask(node);
1649 handleStaticSend(node, selector, mask, element, arguments); 1409 handleStaticSend(node, selector, mask, element, arguments);
1650 return inferrer.registerCalledClosure( 1410 return inferrer.registerCalledClosure(
1651 node, selector, mask, inferrer.typeOfElement(element), 1411 node,
1652 outermostElement, arguments, sideEffects, inLoop); 1412 selector,
1413 mask,
1414 inferrer.typeOfElement(element),
1415 outermostElement,
1416 arguments,
1417 sideEffects,
1418 inLoop);
1653 } 1419 }
1654 1420
1655 /// Handle invocation of a top level or static [function]. 1421 /// Handle invocation of a top level or static [function].
1656 T handleStaticFunctionInvoke(ast.Send node, MethodElement function) { 1422 T handleStaticFunctionInvoke(ast.Send node, MethodElement function) {
1657 if (compiler.backend.isForeign(function)) { 1423 if (compiler.backend.isForeign(function)) {
1658 return handleForeignSend(node, function); 1424 return handleForeignSend(node, function);
1659 } 1425 }
1660 ArgumentsTypes arguments = analyzeArguments(node.arguments); 1426 ArgumentsTypes arguments = analyzeArguments(node.arguments);
1661 Selector selector = elements.getSelector(node); 1427 Selector selector = elements.getSelector(node);
1662 TypeMask mask = elements.getTypeMask(node); 1428 TypeMask mask = elements.getTypeMask(node);
1663 return handleStaticSend(node, selector, mask, function, arguments); 1429 return handleStaticSend(node, selector, mask, function, arguments);
1664 } 1430 }
1665 1431
1666 /// Handle an static invocation of an unresolved target or with incompatible 1432 /// Handle an static invocation of an unresolved target or with incompatible
1667 /// arguments to a resolved target. 1433 /// arguments to a resolved target.
1668 T handleInvalidStaticInvoke(ast.Send node) { 1434 T handleInvalidStaticInvoke(ast.Send node) {
1669 analyzeArguments(node.arguments); 1435 analyzeArguments(node.arguments);
1670 return types.dynamicType; 1436 return types.dynamicType;
1671 } 1437 }
1672 1438
1673 @override 1439 @override
1674 T visitStaticFieldInvoke( 1440 T visitStaticFieldInvoke(ast.Send node, FieldElement field,
1675 ast.Send node, 1441 ast.NodeList arguments, CallStructure callStructure, _) {
1676 FieldElement field,
1677 ast.NodeList arguments,
1678 CallStructure callStructure,
1679 _) {
1680 return handleStaticFieldOrGetterInvoke(node, field); 1442 return handleStaticFieldOrGetterInvoke(node, field);
1681 } 1443 }
1682 1444
1683 @override 1445 @override
1684 T visitStaticFunctionInvoke( 1446 T visitStaticFunctionInvoke(ast.Send node, MethodElement function,
1685 ast.Send node, 1447 ast.NodeList arguments, CallStructure callStructure, _) {
1686 MethodElement function,
1687 ast.NodeList arguments,
1688 CallStructure callStructure,
1689 _) {
1690 return handleStaticFunctionInvoke(node, function); 1448 return handleStaticFunctionInvoke(node, function);
1691 } 1449 }
1692 1450
1693 @override 1451 @override
1694 T visitStaticFunctionIncompatibleInvoke( 1452 T visitStaticFunctionIncompatibleInvoke(ast.Send node, MethodElement function,
1695 ast.Send node, 1453 ast.NodeList arguments, CallStructure callStructure, _) {
1696 MethodElement function,
1697 ast.NodeList arguments,
1698 CallStructure callStructure,
1699 _) {
1700 return handleInvalidStaticInvoke(node); 1454 return handleInvalidStaticInvoke(node);
1701 } 1455 }
1702 1456
1703 @override 1457 @override
1704 T visitStaticGetterInvoke( 1458 T visitStaticGetterInvoke(ast.Send node, FunctionElement getter,
1705 ast.Send node, 1459 ast.NodeList arguments, CallStructure callStructure, _) {
1706 FunctionElement getter,
1707 ast.NodeList arguments,
1708 CallStructure callStructure,
1709 _) {
1710 return handleStaticFieldOrGetterInvoke(node, getter); 1460 return handleStaticFieldOrGetterInvoke(node, getter);
1711 } 1461 }
1712 1462
1713 @override 1463 @override
1714 T visitTopLevelFieldInvoke( 1464 T visitTopLevelFieldInvoke(ast.Send node, FieldElement field,
1715 ast.Send node, 1465 ast.NodeList arguments, CallStructure callStructure, _) {
1716 FieldElement field,
1717 ast.NodeList arguments,
1718 CallStructure callStructure,
1719 _) {
1720 return handleStaticFieldOrGetterInvoke(node, field); 1466 return handleStaticFieldOrGetterInvoke(node, field);
1721 } 1467 }
1722 1468
1723 @override 1469 @override
1724 T visitTopLevelFunctionInvoke( 1470 T visitTopLevelFunctionInvoke(ast.Send node, MethodElement function,
1725 ast.Send node, 1471 ast.NodeList arguments, CallStructure callStructure, _) {
1726 MethodElement function,
1727 ast.NodeList arguments,
1728 CallStructure callStructure,
1729 _) {
1730 return handleStaticFunctionInvoke(node, function); 1472 return handleStaticFunctionInvoke(node, function);
1731 } 1473 }
1732 1474
1733 @override 1475 @override
1734 T visitTopLevelFunctionIncompatibleInvoke( 1476 T visitTopLevelFunctionIncompatibleInvoke(
1735 ast.Send node, 1477 ast.Send node,
1736 MethodElement function, 1478 MethodElement function,
1737 ast.NodeList arguments, 1479 ast.NodeList arguments,
1738 CallStructure callStructure, 1480 CallStructure callStructure,
1739 _) { 1481 _) {
1740 return handleInvalidStaticInvoke(node); 1482 return handleInvalidStaticInvoke(node);
1741 } 1483 }
1742 1484
1743 @override 1485 @override
1744 T visitTopLevelGetterInvoke( 1486 T visitTopLevelGetterInvoke(ast.Send node, FunctionElement getter,
1745 ast.Send node, 1487 ast.NodeList arguments, CallStructure callStructure, _) {
1746 FunctionElement getter,
1747 ast.NodeList arguments,
1748 CallStructure callStructure,
1749 _) {
1750 return handleStaticFieldOrGetterInvoke(node, getter); 1488 return handleStaticFieldOrGetterInvoke(node, getter);
1751 } 1489 }
1752 1490
1753 @override 1491 @override
1754 T visitStaticSetterInvoke( 1492 T visitStaticSetterInvoke(ast.Send node, MethodElement setter,
1755 ast.Send node, 1493 ast.NodeList arguments, CallStructure callStructure, _) {
1756 MethodElement setter,
1757 ast.NodeList arguments,
1758 CallStructure callStructure,
1759 _) {
1760 return handleInvalidStaticInvoke(node); 1494 return handleInvalidStaticInvoke(node);
1761 } 1495 }
1762 1496
1763 @override 1497 @override
1764 T visitTopLevelSetterInvoke( 1498 T visitTopLevelSetterInvoke(ast.Send node, MethodElement setter,
1765 ast.Send node, 1499 ast.NodeList arguments, CallStructure callStructure, _) {
1766 MethodElement setter,
1767 ast.NodeList arguments,
1768 CallStructure callStructure,
1769 _) {
1770 return handleInvalidStaticInvoke(node); 1500 return handleInvalidStaticInvoke(node);
1771 } 1501 }
1772 1502
1773 @override 1503 @override
1774 T visitUnresolvedInvoke( 1504 T visitUnresolvedInvoke(ast.Send node, Element element,
1775 ast.Send node, 1505 ast.NodeList arguments, Selector selector, _) {
1776 Element element,
1777 ast.NodeList arguments,
1778 Selector selector,
1779 _) {
1780 return handleInvalidStaticInvoke(node); 1506 return handleInvalidStaticInvoke(node);
1781 } 1507 }
1782 1508
1783 T handleForeignSend(ast.Send node, Element element) { 1509 T handleForeignSend(ast.Send node, Element element) {
1784 ArgumentsTypes arguments = analyzeArguments(node.arguments); 1510 ArgumentsTypes arguments = analyzeArguments(node.arguments);
1785 Selector selector = elements.getSelector(node); 1511 Selector selector = elements.getSelector(node);
1786 TypeMask mask = elements.getTypeMask(node); 1512 TypeMask mask = elements.getTypeMask(node);
1787 String name = element.name; 1513 String name = element.name;
1788 handleStaticSend(node, selector, mask, element, arguments); 1514 handleStaticSend(node, selector, mask, element, arguments);
1789 if (name == 'JS' || name == 'JS_EMBEDDED_GLOBAL' || name == 'JS_BUILTIN') { 1515 if (name == 'JS' || name == 'JS_EMBEDDED_GLOBAL' || name == 'JS_BUILTIN') {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 } 1565 }
1840 1566
1841 /// Closurize a static or top level function. 1567 /// Closurize a static or top level function.
1842 T handleStaticFunctionGet(ast.Send node, MethodElement function) { 1568 T handleStaticFunctionGet(ast.Send node, MethodElement function) {
1843 Selector selector = elements.getSelector(node); 1569 Selector selector = elements.getSelector(node);
1844 TypeMask mask = elements.getTypeMask(node); 1570 TypeMask mask = elements.getTypeMask(node);
1845 return handleStaticSend(node, selector, mask, function, null); 1571 return handleStaticSend(node, selector, mask, function, null);
1846 } 1572 }
1847 1573
1848 @override 1574 @override
1849 T visitDynamicPropertyGet( 1575 T visitDynamicPropertyGet(ast.Send node, ast.Node receiver, Name name, _) {
1850 ast.Send node,
1851 ast.Node receiver,
1852 Name name,
1853 _) {
1854 return handleDynamicGet(node); 1576 return handleDynamicGet(node);
1855 } 1577 }
1856 1578
1857 @override 1579 @override
1858 T visitIfNotNullDynamicPropertyGet( 1580 T visitIfNotNullDynamicPropertyGet(
1859 ast.Send node, 1581 ast.Send node, ast.Node receiver, Name name, _) {
1860 ast.Node receiver,
1861 Name name,
1862 _) {
1863 return handleDynamicGet(node); 1582 return handleDynamicGet(node);
1864 } 1583 }
1865 1584
1866 @override 1585 @override
1867 T visitLocalVariableGet( 1586 T visitLocalVariableGet(ast.Send node, LocalVariableElement variable, _) {
1868 ast.Send node,
1869 LocalVariableElement variable,
1870 _) {
1871 return handleLocalGet(node, variable); 1587 return handleLocalGet(node, variable);
1872 } 1588 }
1873 1589
1874 @override 1590 @override
1875 T visitParameterGet( 1591 T visitParameterGet(ast.Send node, ParameterElement parameter, _) {
1876 ast.Send node,
1877 ParameterElement parameter,
1878 _) {
1879 return handleLocalGet(node, parameter); 1592 return handleLocalGet(node, parameter);
1880 } 1593 }
1881 1594
1882 @override 1595 @override
1883 T visitLocalFunctionGet( 1596 T visitLocalFunctionGet(ast.Send node, LocalFunctionElement function, _) {
1884 ast.Send node,
1885 LocalFunctionElement function,
1886 _) {
1887 return handleLocalGet(node, function); 1597 return handleLocalGet(node, function);
1888 } 1598 }
1889 1599
1890 @override 1600 @override
1891 T visitStaticFieldGet( 1601 T visitStaticFieldGet(ast.Send node, FieldElement field, _) {
1892 ast.Send node,
1893 FieldElement field,
1894 _) {
1895 return handleStaticFieldGet(node, field); 1602 return handleStaticFieldGet(node, field);
1896 } 1603 }
1897 1604
1898 @override 1605 @override
1899 T visitStaticFunctionGet( 1606 T visitStaticFunctionGet(ast.Send node, MethodElement function, _) {
1900 ast.Send node,
1901 MethodElement function,
1902 _) {
1903 return handleStaticFunctionGet(node, function); 1607 return handleStaticFunctionGet(node, function);
1904 } 1608 }
1905 1609
1906 @override 1610 @override
1907 T visitStaticGetterGet( 1611 T visitStaticGetterGet(ast.Send node, FunctionElement getter, _) {
1908 ast.Send node,
1909 FunctionElement getter,
1910 _) {
1911 return handleStaticGetterGet(node, getter); 1612 return handleStaticGetterGet(node, getter);
1912 } 1613 }
1913 1614
1914 @override 1615 @override
1915 T visitThisPropertyGet( 1616 T visitThisPropertyGet(ast.Send node, Name name, _) {
1916 ast.Send node,
1917 Name name,
1918 _) {
1919 return handleDynamicGet(node); 1617 return handleDynamicGet(node);
1920 } 1618 }
1921 1619
1922 @override 1620 @override
1923 T visitTopLevelFieldGet( 1621 T visitTopLevelFieldGet(ast.Send node, FieldElement field, _) {
1924 ast.Send node,
1925 FieldElement field,
1926 _) {
1927 return handleStaticFieldGet(node, field); 1622 return handleStaticFieldGet(node, field);
1928 } 1623 }
1929 1624
1930 @override 1625 @override
1931 T visitTopLevelFunctionGet( 1626 T visitTopLevelFunctionGet(ast.Send node, MethodElement function, _) {
1932 ast.Send node,
1933 MethodElement function,
1934 _) {
1935 return handleStaticFunctionGet(node, function); 1627 return handleStaticFunctionGet(node, function);
1936 } 1628 }
1937 1629
1938 @override 1630 @override
1939 T visitTopLevelGetterGet( 1631 T visitTopLevelGetterGet(ast.Send node, FunctionElement getter, _) {
1940 ast.Send node,
1941 FunctionElement getter,
1942 _) {
1943 return handleStaticGetterGet(node, getter); 1632 return handleStaticGetterGet(node, getter);
1944 } 1633 }
1945 1634
1946 @override 1635 @override
1947 T visitStaticSetterGet( 1636 T visitStaticSetterGet(ast.Send node, MethodElement setter, _) {
1948 ast.Send node,
1949 MethodElement setter,
1950 _) {
1951 return types.dynamicType; 1637 return types.dynamicType;
1952 } 1638 }
1953 1639
1954 @override 1640 @override
1955 T visitTopLevelSetterGet( 1641 T visitTopLevelSetterGet(ast.Send node, MethodElement setter, _) {
1956 ast.Send node,
1957 MethodElement setter,
1958 _) {
1959 return types.dynamicType; 1642 return types.dynamicType;
1960 } 1643 }
1961 1644
1962 @override 1645 @override
1963 T visitUnresolvedGet( 1646 T visitUnresolvedGet(ast.Send node, Element element, _) {
1964 ast.Send node,
1965 Element element,
1966 _) {
1967 return types.dynamicType; 1647 return types.dynamicType;
1968 } 1648 }
1969 1649
1970 /// Handle .call invocation on [closure]. 1650 /// Handle .call invocation on [closure].
1971 T handleCallInvoke(ast.Send node, T closure) { 1651 T handleCallInvoke(ast.Send node, T closure) {
1972 ArgumentsTypes arguments = analyzeArguments(node.arguments); 1652 ArgumentsTypes arguments = analyzeArguments(node.arguments);
1973 Selector selector = elements.getSelector(node); 1653 Selector selector = elements.getSelector(node);
1974 TypeMask mask = elements.getTypeMask(node); 1654 TypeMask mask = elements.getTypeMask(node);
1975 return inferrer.registerCalledClosure( 1655 return inferrer.registerCalledClosure(node, selector, mask, closure,
1976 node, selector, mask, closure, outermostElement, arguments, 1656 outermostElement, arguments, sideEffects, inLoop);
1977 sideEffects, inLoop);
1978 } 1657 }
1979 1658
1980 @override 1659 @override
1981 T visitExpressionInvoke( 1660 T visitExpressionInvoke(ast.Send node, ast.Node expression,
1982 ast.Send node, 1661 ast.NodeList arguments, CallStructure callStructure, _) {
1983 ast.Node expression,
1984 ast.NodeList arguments,
1985 CallStructure callStructure,
1986 _) {
1987 return handleCallInvoke(node, expression.accept(this)); 1662 return handleCallInvoke(node, expression.accept(this));
1988 } 1663 }
1989 1664
1990 @override 1665 @override
1991 T visitThisInvoke( 1666 T visitThisInvoke(
1992 ast.Send node, 1667 ast.Send node, ast.NodeList arguments, CallStructure callStructure, _) {
1993 ast.NodeList arguments,
1994 CallStructure callStructure,
1995 _) {
1996 return handleCallInvoke(node, thisType); 1668 return handleCallInvoke(node, thisType);
1997 } 1669 }
1998 1670
1999 @override 1671 @override
2000 T visitParameterInvoke( 1672 T visitParameterInvoke(ast.Send node, ParameterElement parameter,
2001 ast.Send node, 1673 ast.NodeList arguments, CallStructure callStructure, _) {
2002 ParameterElement parameter,
2003 ast.NodeList arguments,
2004 CallStructure callStructure,
2005 _) {
2006 return handleCallInvoke(node, locals.use(parameter)); 1674 return handleCallInvoke(node, locals.use(parameter));
2007 } 1675 }
2008 1676
2009 @override 1677 @override
2010 T visitLocalVariableInvoke( 1678 T visitLocalVariableInvoke(ast.Send node, LocalVariableElement variable,
2011 ast.Send node, 1679 ast.NodeList arguments, CallStructure callStructure, _) {
2012 LocalVariableElement variable,
2013 ast.NodeList arguments,
2014 CallStructure callStructure,
2015 _) {
2016 return handleCallInvoke(node, locals.use(variable)); 1680 return handleCallInvoke(node, locals.use(variable));
2017 } 1681 }
2018 1682
2019 @override 1683 @override
2020 T visitLocalFunctionInvoke( 1684 T visitLocalFunctionInvoke(ast.Send node, LocalFunctionElement function,
2021 ast.Send node, 1685 ast.NodeList arguments, CallStructure callStructure, _) {
2022 LocalFunctionElement function,
2023 ast.NodeList arguments,
2024 CallStructure callStructure,
2025 _) {
2026 ArgumentsTypes argumentTypes = analyzeArguments(node.arguments); 1686 ArgumentsTypes argumentTypes = analyzeArguments(node.arguments);
2027 Selector selector = elements.getSelector(node); 1687 Selector selector = elements.getSelector(node);
2028 TypeMask mask = elements.getTypeMask(node); 1688 TypeMask mask = elements.getTypeMask(node);
2029 // This only works for function statements. We need a 1689 // This only works for function statements. We need a
2030 // more sophisticated type system with function types to support 1690 // more sophisticated type system with function types to support
2031 // more. 1691 // more.
2032 return inferrer.registerCalledElement( 1692 return inferrer.registerCalledElement(node, selector, mask,
2033 node, selector, mask, outermostElement, function, argumentTypes, 1693 outermostElement, function, argumentTypes, sideEffects, inLoop);
2034 sideEffects, inLoop);
2035 } 1694 }
2036 1695
2037 @override 1696 @override
2038 T visitLocalFunctionIncompatibleInvoke( 1697 T visitLocalFunctionIncompatibleInvoke(
2039 ast.Send node, 1698 ast.Send node,
2040 LocalFunctionElement function, 1699 LocalFunctionElement function,
2041 ast.NodeList arguments, 1700 ast.NodeList arguments,
2042 CallStructure callStructure, 1701 CallStructure callStructure,
2043 _) { 1702 _) {
2044 analyzeArguments(node.arguments); 1703 analyzeArguments(node.arguments);
2045 return types.dynamicType; 1704 return types.dynamicType;
2046 } 1705 }
2047 1706
2048 T handleStaticSend(ast.Node node, 1707 T handleStaticSend(ast.Node node, Selector selector, TypeMask mask,
2049 Selector selector, 1708 Element element, ArgumentsTypes arguments) {
2050 TypeMask mask,
2051 Element element,
2052 ArgumentsTypes arguments) {
2053 assert(!element.isFactoryConstructor || 1709 assert(!element.isFactoryConstructor ||
2054 !(element as ConstructorElement).isRedirectingFactory); 1710 !(element as ConstructorElement).isRedirectingFactory);
2055 // Erroneous elements may be unresolved, for example missing getters. 1711 // Erroneous elements may be unresolved, for example missing getters.
2056 if (Elements.isUnresolved(element)) return types.dynamicType; 1712 if (Elements.isUnresolved(element)) return types.dynamicType;
2057 // TODO(herhut): should we follow redirecting constructors here? We would 1713 // TODO(herhut): should we follow redirecting constructors here? We would
2058 // need to pay attention if the constructor is pointing to an erroneous 1714 // need to pay attention if the constructor is pointing to an erroneous
2059 // element. 1715 // element.
2060 return inferrer.registerCalledElement( 1716 return inferrer.registerCalledElement(node, selector, mask,
2061 node, selector, mask, outermostElement, element, arguments, 1717 outermostElement, element, arguments, sideEffects, inLoop);
2062 sideEffects, inLoop);
2063 } 1718 }
2064 1719
2065 T handleDynamicSend(ast.Node node, 1720 T handleDynamicSend(ast.Node node, Selector selector, TypeMask mask,
2066 Selector selector, 1721 T receiverType, ArgumentsTypes arguments) {
2067 TypeMask mask,
2068 T receiverType,
2069 ArgumentsTypes arguments) {
2070 assert(receiverType != null); 1722 assert(receiverType != null);
2071 if (types.selectorNeedsUpdate(receiverType, mask)) { 1723 if (types.selectorNeedsUpdate(receiverType, mask)) {
2072 mask = receiverType == types.dynamicType 1724 mask = receiverType == types.dynamicType
2073 ? null 1725 ? null
2074 : types.newTypedSelector(receiverType, mask); 1726 : types.newTypedSelector(receiverType, mask);
2075 inferrer.updateSelectorInTree(analyzedElement, node, selector, mask); 1727 inferrer.updateSelectorInTree(analyzedElement, node, selector, mask);
2076 } 1728 }
2077 1729
2078 // If the receiver of the call is a local, we may know more about 1730 // If the receiver of the call is a local, we may know more about
2079 // its type by refining it with the potential targets of the 1731 // its type by refining it with the potential targets of the
2080 // calls. 1732 // calls.
2081 ast.Send send = node.asSend(); 1733 ast.Send send = node.asSend();
2082 if (send != null) { 1734 if (send != null) {
2083 ast.Node receiver = send.receiver; 1735 ast.Node receiver = send.receiver;
2084 if (receiver != null) { 1736 if (receiver != null) {
2085 Element element = elements[receiver]; 1737 Element element = elements[receiver];
2086 if (Elements.isLocal(element) && !capturedVariables.contains(element)) { 1738 if (Elements.isLocal(element) && !capturedVariables.contains(element)) {
2087 T refinedType = types.refineReceiver( 1739 T refinedType = types.refineReceiver(
2088 selector, mask, receiverType, send.isConditional); 1740 selector, mask, receiverType, send.isConditional);
2089 locals.update(element, refinedType, node); 1741 locals.update(element, refinedType, node);
2090 } 1742 }
2091 } 1743 }
2092 } 1744 }
2093 1745
2094 return inferrer.registerCalledSelector( 1746 return inferrer.registerCalledSelector(node, selector, mask, receiverType,
2095 node, selector, mask, receiverType, outermostElement, arguments, 1747 outermostElement, arguments, sideEffects, inLoop);
2096 sideEffects, inLoop);
2097 } 1748 }
2098 1749
2099 T handleDynamicInvoke(ast.Send node) { 1750 T handleDynamicInvoke(ast.Send node) {
2100 return _handleDynamicSend(node); 1751 return _handleDynamicSend(node);
2101 } 1752 }
2102 1753
2103 T handleDynamicGet(ast.Send node) { 1754 T handleDynamicGet(ast.Send node) {
2104 return _handleDynamicSend(node); 1755 return _handleDynamicSend(node);
2105 } 1756 }
2106 1757
(...skipping 11 matching lines...) Expand all
2118 isCallOnThis = isThisOrSuper(receiver); 1769 isCallOnThis = isThisOrSuper(receiver);
2119 receiverType = visit(receiver); 1770 receiverType = visit(receiver);
2120 } 1771 }
2121 1772
2122 Selector selector = elements.getSelector(node); 1773 Selector selector = elements.getSelector(node);
2123 TypeMask mask = elements.getTypeMask(node); 1774 TypeMask mask = elements.getTypeMask(node);
2124 if (!isThisExposed && isCallOnThis) { 1775 if (!isThisExposed && isCallOnThis) {
2125 checkIfExposesThis(selector, types.newTypedSelector(receiverType, mask)); 1776 checkIfExposesThis(selector, types.newTypedSelector(receiverType, mask));
2126 } 1777 }
2127 1778
2128 ArgumentsTypes arguments = node.isPropertyAccess 1779 ArgumentsTypes arguments =
2129 ? null 1780 node.isPropertyAccess ? null : analyzeArguments(node.arguments);
2130 : analyzeArguments(node.arguments); 1781 if (selector.name == '==' || selector.name == '!=') {
2131 if (selector.name == '==' ||
2132 selector.name == '!=') {
2133 if (types.isNull(receiverType)) { 1782 if (types.isNull(receiverType)) {
2134 potentiallyAddNullCheck(node, node.arguments.head); 1783 potentiallyAddNullCheck(node, node.arguments.head);
2135 return types.boolType; 1784 return types.boolType;
2136 } else if (types.isNull(arguments.positional[0])) { 1785 } else if (types.isNull(arguments.positional[0])) {
2137 potentiallyAddNullCheck(node, node.receiver); 1786 potentiallyAddNullCheck(node, node.receiver);
2138 return types.boolType; 1787 return types.boolType;
2139 } 1788 }
2140 } 1789 }
2141 return handleDynamicSend(node, selector, mask, receiverType, arguments); 1790 return handleDynamicSend(node, selector, mask, receiverType, arguments);
2142 } 1791 }
(...skipping 23 matching lines...) Expand all
2166 signature.forEachOptionalParameter((ParameterElement element) { 1815 signature.forEachOptionalParameter((ParameterElement element) {
2167 named[element.name] = locals.use(element); 1816 named[element.name] = locals.use(element);
2168 }); 1817 });
2169 } else { 1818 } else {
2170 signature.forEachOptionalParameter((ParameterElement element) { 1819 signature.forEachOptionalParameter((ParameterElement element) {
2171 unnamed.add(locals.use(element)); 1820 unnamed.add(locals.use(element));
2172 }); 1821 });
2173 } 1822 }
2174 1823
2175 ArgumentsTypes arguments = new ArgumentsTypes<T>(unnamed, named); 1824 ArgumentsTypes arguments = new ArgumentsTypes<T>(unnamed, named);
2176 return inferrer.registerCalledElement(node, 1825 return inferrer.registerCalledElement(node, null, null, outermostElement,
2177 null, 1826 element, arguments, sideEffects, inLoop);
2178 null,
2179 outermostElement,
2180 element,
2181 arguments,
2182 sideEffects,
2183 inLoop);
2184 } 1827 }
2185 1828
2186 T visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { 1829 T visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) {
2187 Element element = elements.getRedirectingTargetConstructor(node); 1830 Element element = elements.getRedirectingTargetConstructor(node);
2188 if (Elements.isMalformed(element)) { 1831 if (Elements.isMalformed(element)) {
2189 recordReturnType(types.dynamicType); 1832 recordReturnType(types.dynamicType);
2190 } else { 1833 } else {
2191 // We don't create a selector for redirecting factories, and 1834 // We don't create a selector for redirecting factories, and
2192 // the send is just a property access. Therefore we must 1835 // the send is just a property access. Therefore we must
2193 // manually create the [ArgumentsTypes] of the call, and 1836 // manually create the [ArgumentsTypes] of the call, and
2194 // manually register [analyzedElement] as a caller of [element]. 1837 // manually register [analyzedElement] as a caller of [element].
2195 T mask = synthesizeForwardingCall(node.constructorReference, element); 1838 T mask = synthesizeForwardingCall(node.constructorReference, element);
2196 recordReturnType(mask); 1839 recordReturnType(mask);
2197 } 1840 }
2198 locals.seenReturnOrThrow = true; 1841 locals.seenReturnOrThrow = true;
2199 return null; 1842 return null;
2200 } 1843 }
2201 1844
2202 T visitReturn(ast.Return node) { 1845 T visitReturn(ast.Return node) {
2203 ast.Node expression = node.expression; 1846 ast.Node expression = node.expression;
2204 recordReturnType(expression == null 1847 recordReturnType(
2205 ? types.nullType 1848 expression == null ? types.nullType : expression.accept(this));
2206 : expression.accept(this));
2207 locals.seenReturnOrThrow = true; 1849 locals.seenReturnOrThrow = true;
2208 return null; 1850 return null;
2209 } 1851 }
2210 1852
2211 T handleForInLoop(ast.ForIn node, 1853 T handleForInLoop(ast.ForIn node, T iteratorType, Selector currentSelector,
2212 T iteratorType, 1854 TypeMask currentMask, Selector moveNextSelector, TypeMask moveNextMask) {
2213 Selector currentSelector, 1855 handleDynamicSend(node, moveNextSelector, moveNextMask, iteratorType,
2214 TypeMask currentMask,
2215 Selector moveNextSelector,
2216 TypeMask moveNextMask) {
2217 handleDynamicSend(
2218 node, moveNextSelector, moveNextMask, iteratorType,
2219 new ArgumentsTypes<T>.empty()); 1856 new ArgumentsTypes<T>.empty());
2220 T currentType = handleDynamicSend( 1857 T currentType = handleDynamicSend(node, currentSelector, currentMask,
2221 node, currentSelector, currentMask, iteratorType, 1858 iteratorType, new ArgumentsTypes<T>.empty());
2222 new ArgumentsTypes<T>.empty());
2223 1859
2224 if (node.expression.isThis()) { 1860 if (node.expression.isThis()) {
2225 // Any reasonable implementation of an iterator would expose 1861 // Any reasonable implementation of an iterator would expose
2226 // this, so we play it safe and assume it will. 1862 // this, so we play it safe and assume it will.
2227 isThisExposed = true; 1863 isThisExposed = true;
2228 } 1864 }
2229 1865
2230 ast.Node identifier = node.declaredIdentifier; 1866 ast.Node identifier = node.declaredIdentifier;
2231 Element element = elements.getForInVariable(node); 1867 Element element = elements.getForInVariable(node);
2232 Selector selector = elements.getSelector(identifier); 1868 Selector selector = elements.getSelector(identifier);
2233 TypeMask mask = elements.getTypeMask(identifier); 1869 TypeMask mask = elements.getTypeMask(identifier);
2234 1870
2235 T receiverType; 1871 T receiverType;
2236 if (element != null && element.isInstanceMember) { 1872 if (element != null && element.isInstanceMember) {
2237 receiverType = thisType; 1873 receiverType = thisType;
2238 } else { 1874 } else {
2239 receiverType = types.dynamicType; 1875 receiverType = types.dynamicType;
2240 } 1876 }
2241 1877
2242 handlePlainAssignment(identifier, element, selector, mask, 1878 handlePlainAssignment(identifier, element, selector, mask, receiverType,
2243 receiverType, currentType, 1879 currentType, node.expression);
2244 node.expression);
2245 return handleLoop(node, () { 1880 return handleLoop(node, () {
2246 visit(node.body); 1881 visit(node.body);
2247 }); 1882 });
2248 } 1883 }
2249 1884
2250 T visitAsyncForIn(ast.AsyncForIn node) { 1885 T visitAsyncForIn(ast.AsyncForIn node) {
2251 T expressionType = visit(node.expression); 1886 T expressionType = visit(node.expression);
2252 1887
2253 Selector currentSelector = Selectors.current; 1888 Selector currentSelector = Selectors.current;
2254 TypeMask currentMask = elements.getCurrentTypeMask(node); 1889 TypeMask currentMask = elements.getCurrentTypeMask(node);
2255 Selector moveNextSelector = Selectors.moveNext; 1890 Selector moveNextSelector = Selectors.moveNext;
2256 TypeMask moveNextMask = elements.getMoveNextTypeMask(node); 1891 TypeMask moveNextMask = elements.getMoveNextTypeMask(node);
2257 1892
2258 js.JavaScriptBackend backend = compiler.backend; 1893 js.JavaScriptBackend backend = compiler.backend;
2259 Element ctor = backend.helpers.streamIteratorConstructor; 1894 Element ctor = backend.helpers.streamIteratorConstructor;
2260 1895
2261 /// Synthesize a call to the [StreamIterator] constructor. 1896 /// Synthesize a call to the [StreamIterator] constructor.
2262 T iteratorType = handleStaticSend(node, null, null, ctor, 1897 T iteratorType = handleStaticSend(
2263 new ArgumentsTypes<T>([expressionType], 1898 node, null, null, ctor, new ArgumentsTypes<T>([expressionType], null));
2264 null));
2265 1899
2266 return handleForInLoop(node, iteratorType, currentSelector, currentMask, 1900 return handleForInLoop(node, iteratorType, currentSelector, currentMask,
2267 moveNextSelector, moveNextMask); 1901 moveNextSelector, moveNextMask);
2268 } 1902 }
2269 1903
2270 T visitSyncForIn(ast.SyncForIn node) { 1904 T visitSyncForIn(ast.SyncForIn node) {
2271 T expressionType = visit(node.expression); 1905 T expressionType = visit(node.expression);
2272 Selector iteratorSelector = Selectors.iterator; 1906 Selector iteratorSelector = Selectors.iterator;
2273 TypeMask iteratorMask = elements.getIteratorTypeMask(node); 1907 TypeMask iteratorMask = elements.getIteratorTypeMask(node);
2274 Selector currentSelector = Selectors.current; 1908 Selector currentSelector = Selectors.current;
2275 TypeMask currentMask = elements.getCurrentTypeMask(node); 1909 TypeMask currentMask = elements.getCurrentTypeMask(node);
2276 Selector moveNextSelector = Selectors.moveNext; 1910 Selector moveNextSelector = Selectors.moveNext;
2277 TypeMask moveNextMask = elements.getMoveNextTypeMask(node); 1911 TypeMask moveNextMask = elements.getMoveNextTypeMask(node);
2278 1912
2279 T iteratorType = handleDynamicSend( 1913 T iteratorType = handleDynamicSend(node, iteratorSelector, iteratorMask,
2280 node, iteratorSelector, iteratorMask, expressionType, 1914 expressionType, new ArgumentsTypes<T>.empty());
2281 new ArgumentsTypes<T>.empty());
2282 1915
2283 return handleForInLoop(node, iteratorType, currentSelector, currentMask, 1916 return handleForInLoop(node, iteratorType, currentSelector, currentMask,
2284 moveNextSelector, moveNextMask); 1917 moveNextSelector, moveNextMask);
2285 } 1918 }
2286 } 1919 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/node_tracer.dart ('k') | pkg/compiler/lib/src/inferrer/type_graph_dump.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698