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

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

Issue 2977963002: Use entities in the InferrerEngine interface (Closed)
Patch Set: Created 3 years, 5 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
« no previous file with comments | « pkg/compiler/lib/src/inferrer/builder.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../common/names.dart'; 8 import '../common/names.dart';
9 import '../compiler.dart'; 9 import '../compiler.dart';
10 import '../constants/expressions.dart'; 10 import '../constants/expressions.dart';
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments); 79 void analyze(ResolvedAst resolvedAst, ArgumentsTypes arguments);
80 void analyzeListAndEnqueue(ListTypeInformation info); 80 void analyzeListAndEnqueue(ListTypeInformation info);
81 void analyzeMapAndEnqueue(MapTypeInformation info); 81 void analyzeMapAndEnqueue(MapTypeInformation info);
82 82
83 /// Notifies to the inferrer that [analyzedElement] can have return type 83 /// Notifies to the inferrer that [analyzedElement] can have return type
84 /// [newType]. [currentType] is the type the [ElementGraphBuilder] currently 84 /// [newType]. [currentType] is the type the [ElementGraphBuilder] currently
85 /// found. 85 /// found.
86 /// 86 ///
87 /// Returns the new type for [analyzedElement]. 87 /// Returns the new type for [analyzedElement].
88 TypeInformation addReturnTypeForMethod( 88 TypeInformation addReturnTypeForMethod(
89 MethodElement element, TypeInformation unused, TypeInformation newType); 89 FunctionEntity element, TypeInformation unused, TypeInformation newType);
90 90
91 /// Applies [f] to all elements in the universe that match [selector] and 91 /// Applies [f] to all elements in the universe that match [selector] and
92 /// [mask]. If [f] returns false, aborts the iteration. 92 /// [mask]. If [f] returns false, aborts the iteration.
93 void forEachElementMatching( 93 void forEachElementMatching(
94 Selector selector, TypeMask mask, bool f(Element element)); 94 Selector selector, TypeMask mask, bool f(MemberEntity element));
95 95
96 /// Returns the [TypeInformation] node for the default value of a parameter. 96 /// Returns the [TypeInformation] node for the default value of a parameter.
97 /// If this is queried before it is set by [setDefaultTypeOfParameter], a 97 /// If this is queried before it is set by [setDefaultTypeOfParameter], a
98 /// [PlaceholderTypeInformation] is returned, which will later be replaced 98 /// [PlaceholderTypeInformation] is returned, which will later be replaced
99 /// by the actual node when [setDefaultTypeOfParameter] is called. 99 /// by the actual node when [setDefaultTypeOfParameter] is called.
100 /// 100 ///
101 /// Invariant: After graph construction, no [PlaceholderTypeInformation] nodes 101 /// Invariant: After graph construction, no [PlaceholderTypeInformation] nodes
102 /// should be present and a default type for each parameter should exist. 102 /// should be present and a default type for each parameter should exist.
103 TypeInformation getDefaultTypeOfParameter(ParameterElement parameter); 103 TypeInformation getDefaultTypeOfParameter(Local parameter);
104 104
105 /// This helper breaks abstractions but is currently required to work around 105 /// This helper breaks abstractions but is currently required to work around
106 /// the wrong modeling of default values of optional parameters of 106 /// the wrong modeling of default values of optional parameters of
107 /// synthetic constructors. 107 /// synthetic constructors.
108 /// 108 ///
109 /// TODO(johnniwinther): Remove once default values of synthetic parameters 109 /// TODO(johnniwinther): Remove once default values of synthetic parameters
110 /// are fixed. 110 /// are fixed.
111 bool hasAlreadyComputedTypeOfParameterDefault(ParameterElement parameter); 111 bool hasAlreadyComputedTypeOfParameterDefault(Local parameter);
112 112
113 /// Sets the type of a parameter's default value to [type]. If the global 113 /// Sets the type of a parameter's default value to [type]. If the global
114 /// mapping in [defaultTypeOfParameter] already contains a type, it must be 114 /// mapping in [defaultTypeOfParameter] already contains a type, it must be
115 /// a [PlaceholderTypeInformation], which will be replaced. All its uses are 115 /// a [PlaceholderTypeInformation], which will be replaced. All its uses are
116 /// updated. 116 /// updated.
117 void setDefaultTypeOfParameter( 117 void setDefaultTypeOfParameter(Local parameter, TypeInformation type);
118 ParameterElement parameter, TypeInformation type);
119 118
120 Iterable<MemberEntity> getCallersOf(MemberElement element); 119 Iterable<MemberEntity> getCallersOf(MemberEntity element);
121 120
122 // TODO(johnniwinther): Make this private again. 121 // TODO(johnniwinther): Make this private again.
123 GlobalTypeInferenceElementData dataOfMember(MemberElement element); 122 GlobalTypeInferenceElementData dataOfMember(MemberEntity element);
124 123
125 GlobalTypeInferenceElementData lookupDataOfMember(MemberElement element); 124 GlobalTypeInferenceElementData lookupDataOfMember(MemberEntity element);
126 125
127 bool checkIfExposesThis(ConstructorElement element); 126 bool checkIfExposesThis(ConstructorEntity element);
128 127
129 void recordExposesThis(ConstructorElement element, bool exposesThis); 128 void recordExposesThis(ConstructorEntity element, bool exposesThis);
130 129
131 /// Records that the return type [element] is of type [type]. 130 /// Records that the return type [element] is of type [type].
132 void recordReturnType(MethodElement element, TypeInformation type); 131 void recordReturnType(FunctionEntity element, TypeInformation type);
133 132
134 /// Records that [element] is of type [type]. 133 /// Records that [element] is of type [type].
135 void recordTypeOfField(FieldElement element, TypeInformation type); 134 void recordTypeOfField(FieldEntity element, TypeInformation type);
136 135
137 /// Registers a call to await with an expression of type [argumentType] as 136 /// Registers a call to await with an expression of type [argumentType] as
138 /// argument. 137 /// argument.
139 TypeInformation registerAwait(ast.Node node, TypeInformation argument); 138 TypeInformation registerAwait(ast.Node node, TypeInformation argument);
140 139
141 /// Registers a call to yield with an expression of type [argumentType] as 140 /// Registers a call to yield with an expression of type [argumentType] as
142 /// argument. 141 /// argument.
143 TypeInformation registerYield(ast.Node node, TypeInformation argument); 142 TypeInformation registerYield(ast.Node node, TypeInformation argument);
144 143
145 /// Registers that [caller] calls [closure] with [arguments]. 144 /// Registers that [caller] calls [closure] with [arguments].
146 /// 145 ///
147 /// [sideEffects] will be updated to incorporate the potential callees' side 146 /// [sideEffects] will be updated to incorporate the potential callees' side
148 /// effects. 147 /// effects.
149 /// 148 ///
150 /// [inLoop] tells whether the call happens in a loop. 149 /// [inLoop] tells whether the call happens in a loop.
151 TypeInformation registerCalledClosure( 150 TypeInformation registerCalledClosure(
152 ast.Node node, 151 ast.Node node,
153 Selector selector, 152 Selector selector,
154 TypeMask mask, 153 TypeMask mask,
155 TypeInformation closure, 154 TypeInformation closure,
156 MemberElement caller, 155 MemberEntity caller,
157 ArgumentsTypes arguments, 156 ArgumentsTypes arguments,
158 SideEffects sideEffects, 157 SideEffects sideEffects,
159 bool inLoop); 158 bool inLoop);
160 159
161 /// Registers that [caller] calls [callee] at location [node], with 160 /// Registers that [caller] calls [callee] at location [node], with
162 /// [selector], and [arguments]. Note that [selector] is null for forwarding 161 /// [selector], and [arguments]. Note that [selector] is null for forwarding
163 /// constructors. 162 /// constructors.
164 /// 163 ///
165 /// [sideEffects] will be updated to incorporate [callee]'s side effects. 164 /// [sideEffects] will be updated to incorporate [callee]'s side effects.
166 /// 165 ///
167 /// [inLoop] tells whether the call happens in a loop. 166 /// [inLoop] tells whether the call happens in a loop.
168 TypeInformation registerCalledMember( 167 TypeInformation registerCalledMember(
169 Spannable node, 168 Spannable node,
170 Selector selector, 169 Selector selector,
171 TypeMask mask, 170 TypeMask mask,
172 MemberElement caller, 171 MemberEntity caller,
173 MemberElement callee, 172 MemberEntity callee,
174 ArgumentsTypes arguments, 173 ArgumentsTypes arguments,
175 SideEffects sideEffects, 174 SideEffects sideEffects,
176 bool inLoop); 175 bool inLoop);
177 176
178 /// Registers that [caller] calls [selector] with [receiverType] as receiver, 177 /// Registers that [caller] calls [selector] with [receiverType] as receiver,
179 /// and [arguments]. 178 /// and [arguments].
180 /// 179 ///
181 /// [sideEffects] will be updated to incorporate the potential callees' side 180 /// [sideEffects] will be updated to incorporate the potential callees' side
182 /// effects. 181 /// effects.
183 /// 182 ///
184 /// [inLoop] tells whether the call happens in a loop. 183 /// [inLoop] tells whether the call happens in a loop.
185 TypeInformation registerCalledSelector( 184 TypeInformation registerCalledSelector(
186 ast.Node node, 185 ast.Node node,
187 Selector selector, 186 Selector selector,
188 TypeMask mask, 187 TypeMask mask,
189 TypeInformation receiverType, 188 TypeInformation receiverType,
190 MemberElement caller, 189 MemberEntity caller,
191 ArgumentsTypes arguments, 190 ArgumentsTypes arguments,
192 SideEffects sideEffects, 191 SideEffects sideEffects,
193 bool inLoop, 192 bool inLoop,
194 bool isConditional); 193 bool isConditional);
195 194
196 /// Update the assignments to parameters in the graph. [remove] tells whether 195 /// Update the assignments to parameters in the graph. [remove] tells whether
197 /// assignments must be added or removed. If [init] is false, parameters are 196 /// assignments must be added or removed. If [init] is false, parameters are
198 /// added to the work queue. 197 /// added to the work queue.
199 void updateParameterAssignments(TypeInformation caller, MemberEntity callee, 198 void updateParameterAssignments(TypeInformation caller, MemberEntity callee,
200 ArgumentsTypes arguments, Selector selector, TypeMask mask, 199 ArgumentsTypes arguments, Selector selector, TypeMask mask,
201 {bool remove, bool addToQueue: true}); 200 {bool remove, bool addToQueue: true});
202 201
203 void updateSelectorInMember( 202 void updateSelectorInMember(
204 MemberElement owner, Spannable node, Selector selector, TypeMask mask); 203 MemberEntity owner, ast.Node node, Selector selector, TypeMask mask);
205 204
206 /// Returns the return type of [element]. 205 /// Returns the return type of [element].
207 TypeInformation returnTypeOfMember(MemberElement element); 206 TypeInformation returnTypeOfMember(MemberEntity element);
208 207
209 /// Returns the type of [element] when being called with [selector]. 208 /// Returns the type of [element] when being called with [selector].
210 TypeInformation typeOfMemberWithSelector( 209 TypeInformation typeOfMemberWithSelector(
211 MemberElement element, Selector selector); 210 MemberEntity element, Selector selector);
212 211
213 /// Returns the type of [element]. 212 /// Returns the type of [element].
214 TypeInformation typeOfMember(MemberElement element); 213 TypeInformation typeOfMember(MemberEntity element);
215 214
216 /// Returns the type of [element]. 215 /// Returns the type of [element].
217 TypeInformation typeOfParameter(ParameterElement element); 216 TypeInformation typeOfParameter(Local element);
218 217
219 /// Returns the type for [nativeBehavior]. See documentation on 218 /// Returns the type for [nativeBehavior]. See documentation on
220 /// [native.NativeBehavior]. 219 /// [native.NativeBehavior].
221 TypeInformation typeOfNativeBehavior(native.NativeBehavior nativeBehavior); 220 TypeInformation typeOfNativeBehavior(native.NativeBehavior nativeBehavior);
222 221
223 bool returnsListElementType(Selector selector, TypeMask mask); 222 bool returnsListElementType(Selector selector, TypeMask mask);
224 223
225 bool returnsMapValueType(Selector selector, TypeMask mask); 224 bool returnsMapValueType(Selector selector, TypeMask mask);
226 225
227 void clear(); 226 void clear();
(...skipping 19 matching lines...) Expand all
247 /// The [ClosedWorld] on which inference reasoning is based. 246 /// The [ClosedWorld] on which inference reasoning is based.
248 final ClosedWorld closedWorld; 247 final ClosedWorld closedWorld;
249 248
250 final ClosedWorldRefiner closedWorldRefiner; 249 final ClosedWorldRefiner closedWorldRefiner;
251 final TypeSystem<ast.Node> types; 250 final TypeSystem<ast.Node> types;
252 final Map<ast.Node, TypeInformation> concreteTypes = 251 final Map<ast.Node, TypeInformation> concreteTypes =
253 new Map<ast.Node, TypeInformation>(); 252 new Map<ast.Node, TypeInformation>();
254 253
255 final Map<ir.Node, TypeInformation> concreteKernelTypes = 254 final Map<ir.Node, TypeInformation> concreteKernelTypes =
256 new Map<ir.Node, TypeInformation>(); 255 new Map<ir.Node, TypeInformation>();
257 final Set<ConstructorElement> generativeConstructorsExposingThis = 256 final Set<ConstructorEntity> generativeConstructorsExposingThis =
258 new Set<ConstructorElement>(); 257 new Set<ConstructorEntity>();
259 258
260 /// Data computed internally within elements, like the type-mask of a send a 259 /// Data computed internally within elements, like the type-mask of a send a
261 /// list allocation, or a for-in loop. 260 /// list allocation, or a for-in loop.
262 final Map<MemberElement, GlobalTypeInferenceElementData> _memberData = 261 final Map<MemberElement, GlobalTypeInferenceElementData> _memberData =
263 new Map<MemberElement, GlobalTypeInferenceElementData>(); 262 new Map<MemberElement, GlobalTypeInferenceElementData>();
264 263
265 InferrerEngineImpl(this.compiler, ClosedWorld closedWorld, 264 InferrerEngineImpl(this.compiler, ClosedWorld closedWorld,
266 this.closedWorldRefiner, this.mainElement) 265 this.closedWorldRefiner, this.mainElement)
267 : this.types = new TypeSystem<ast.Node>( 266 : this.types = new TypeSystem<ast.Node>(
268 closedWorld, const TypeSystemStrategyImpl()), 267 closedWorld, const TypeSystemStrategyImpl()),
269 this.closedWorld = closedWorld; 268 this.closedWorld = closedWorld;
270 269
271 void forEachElementMatching( 270 void forEachElementMatching(
272 Selector selector, TypeMask mask, bool f(Element element)) { 271 Selector selector, TypeMask mask, bool f(MemberEntity element)) {
273 Iterable<MemberEntity> elements = closedWorld.locateMembers(selector, mask); 272 Iterable<MemberEntity> elements = closedWorld.locateMembers(selector, mask);
274 for (MemberElement e in elements) { 273 for (MemberElement e in elements) {
275 if (!f(e.implementation)) return; 274 if (!f(e)) return;
276 } 275 }
277 } 276 }
278 277
279 // TODO(johnniwinther): Make this private again. 278 // TODO(johnniwinther): Make this private again.
280 GlobalTypeInferenceElementData dataOfMember(MemberElement element) => 279 GlobalTypeInferenceElementData dataOfMember(MemberEntity element) =>
281 _memberData.putIfAbsent( 280 _memberData.putIfAbsent(
282 element, () => new GlobalTypeInferenceElementData()); 281 element, () => new GlobalTypeInferenceElementData());
283 282
284 GlobalTypeInferenceElementData lookupDataOfMember(MemberElement element) => 283 GlobalTypeInferenceElementData lookupDataOfMember(MemberEntity element) =>
285 _memberData[element]; 284 _memberData[element];
286 285
287 /** 286 /**
288 * Update [sideEffects] with the side effects of [callee] being 287 * Update [sideEffects] with the side effects of [callee] being
289 * called with [selector]. 288 * called with [selector].
290 */ 289 */
291 void updateSideEffects( 290 void updateSideEffects(
292 SideEffects sideEffects, Selector selector, MemberElement callee) { 291 SideEffects sideEffects, Selector selector, MemberElement callee) {
293 if (callee.isField) { 292 if (callee.isField) {
294 if (callee.isInstanceMember) { 293 if (callee.isInstanceMember) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 } 350 }
352 returnType = types.computeLUB(returnType, mappedType); 351 returnType = types.computeLUB(returnType, mappedType);
353 if (returnType == types.dynamicType) { 352 if (returnType == types.dynamicType) {
354 break; 353 break;
355 } 354 }
356 } 355 }
357 return returnType; 356 return returnType;
358 } 357 }
359 358
360 void updateSelectorInMember( 359 void updateSelectorInMember(
361 MemberElement owner, Spannable node, Selector selector, TypeMask mask) { 360 MemberEntity owner, ast.Node node, Selector selector, TypeMask mask) {
362 GlobalTypeInferenceElementData data = dataOfMember(owner); 361 GlobalTypeInferenceElementData data = dataOfMember(owner);
363 ast.Node astNode = node; 362 if (node.asSendSet() != null) {
364 if (astNode.asSendSet() != null) {
365 if (selector.isSetter || selector.isIndexSet) { 363 if (selector.isSetter || selector.isIndexSet) {
366 data.setTypeMask(node, mask); 364 data.setTypeMask(node, mask);
367 } else if (selector.isGetter || selector.isIndex) { 365 } else if (selector.isGetter || selector.isIndex) {
368 data.setGetterTypeMaskInComplexSendSet(node, mask); 366 data.setGetterTypeMaskInComplexSendSet(node, mask);
369 } else { 367 } else {
370 assert(selector.isOperator); 368 assert(selector.isOperator);
371 data.setOperatorTypeMaskInComplexSendSet(node, mask); 369 data.setOperatorTypeMaskInComplexSendSet(node, mask);
372 } 370 }
373 } else if (astNode.asSend() != null) { 371 } else if (node.asSend() != null) {
374 data.setTypeMask(node, mask); 372 data.setTypeMask(node, mask);
375 } else { 373 } else {
376 assert(astNode.asForIn() != null); 374 assert(node.asForIn() != null);
377 if (selector == Selectors.iterator) { 375 if (selector == Selectors.iterator) {
378 data.setIteratorTypeMask(node, mask); 376 data.setIteratorTypeMask(node, mask);
379 } else if (selector == Selectors.current) { 377 } else if (selector == Selectors.current) {
380 data.setCurrentTypeMask(node, mask); 378 data.setCurrentTypeMask(node, mask);
381 } else { 379 } else {
382 assert(selector == Selectors.moveNext); 380 assert(selector == Selectors.moveNext);
383 data.setMoveNextTypeMask(node, mask); 381 data.setMoveNextTypeMask(node, mask);
384 } 382 }
385 } 383 }
386 } 384 }
387 385
388 bool checkIfExposesThis(ConstructorElement element) { 386 bool checkIfExposesThis(ConstructorEntity element) {
389 element = element.implementation; 387 assert(!(element is ConstructorElement && !element.isDeclaration));
390 return generativeConstructorsExposingThis.contains(element); 388 return generativeConstructorsExposingThis.contains(element);
391 } 389 }
392 390
393 void recordExposesThis(ConstructorElement element, bool exposesThis) { 391 void recordExposesThis(ConstructorEntity element, bool exposesThis) {
394 element = element.implementation; 392 assert(!(element is ConstructorElement && !element.isDeclaration));
395 if (exposesThis) { 393 if (exposesThis) {
396 generativeConstructorsExposingThis.add(element); 394 generativeConstructorsExposingThis.add(element);
397 } 395 }
398 } 396 }
399 397
400 bool returnsListElementType(Selector selector, TypeMask mask) { 398 bool returnsListElementType(Selector selector, TypeMask mask) {
401 return mask != null && 399 return mask != null &&
402 mask.isContainer && 400 mask.isContainer &&
403 returnsListElementTypeSet.contains(selector); 401 returnsListElementTypeSet.contains(selector);
404 } 402 }
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 ? new KernelTypeGraphBuilder(element, resolvedAst, compiler, this) 649 ? new KernelTypeGraphBuilder(element, resolvedAst, compiler, this)
652 : new ElementGraphBuilder(element, resolvedAst, compiler, this); 650 : new ElementGraphBuilder(element, resolvedAst, compiler, this);
653 TypeInformation type; 651 TypeInformation type;
654 reporter.withCurrentElement(element, () { 652 reporter.withCurrentElement(element, () {
655 // ignore: UNDEFINED_METHOD 653 // ignore: UNDEFINED_METHOD
656 type = visitor.run(); 654 type = visitor.run();
657 }); 655 });
658 addedInGraph++; 656 addedInGraph++;
659 657
660 if (element.isField) { 658 if (element.isField) {
661 FieldElement fieldElement = element; 659 FieldElement field = element;
662 ast.Node initializer = resolvedAst.body; 660 ast.Node initializer = resolvedAst.body;
663 if (element.isFinal || element.isConst) { 661 if (field.isFinal || field.isConst) {
664 // If [element] is final and has an initializer, we record 662 // If [element] is final and has an initializer, we record
665 // the inferred type. 663 // the inferred type.
666 if (resolvedAst.body != null) { 664 if (resolvedAst.body != null) {
667 if (type is! ListTypeInformation && type is! MapTypeInformation) { 665 if (type is! ListTypeInformation && type is! MapTypeInformation) {
668 // For non-container types, the constant handler does 666 // For non-container types, the constant handler does
669 // constant folding that could give more precise results. 667 // constant folding that could give more precise results.
670 ConstantExpression constant = fieldElement.constant; 668 ConstantExpression constant = field.constant;
671 if (constant != null) { 669 if (constant != null) {
672 ConstantValue value = 670 ConstantValue value =
673 compiler.backend.constants.getConstantValue(constant); 671 compiler.backend.constants.getConstantValue(constant);
674 if (value != null) { 672 if (value != null) {
675 if (value.isFunction) { 673 if (value.isFunction) {
676 FunctionConstantValue functionConstant = value; 674 FunctionConstantValue functionConstant = value;
677 MethodElement function = functionConstant.element; 675 MethodElement function = functionConstant.element;
678 type = types.allocateClosure(function); 676 type = types.allocateClosure(function);
679 } else { 677 } else {
680 // Although we might find a better type, we have to keep 678 // Although we might find a better type, we have to keep
681 // the old type around to ensure that we get a complete view 679 // the old type around to ensure that we get a complete view
682 // of the type graph and do not drop any flow edges. 680 // of the type graph and do not drop any flow edges.
683 TypeMask refinedType = computeTypeMask(closedWorld, value); 681 TypeMask refinedType = computeTypeMask(closedWorld, value);
684 assert(TypeMask.assertIsNormalized(refinedType, closedWorld)); 682 assert(TypeMask.assertIsNormalized(refinedType, closedWorld));
685 type = new NarrowTypeInformation(type, refinedType); 683 type = new NarrowTypeInformation(type, refinedType);
686 types.allocatedTypes.add(type); 684 types.allocatedTypes.add(type);
687 } 685 }
688 } else { 686 } else {
689 assert( 687 assert(
690 fieldElement.isInstanceMember || 688 field.isInstanceMember ||
691 constant.isImplicit || 689 constant.isImplicit ||
692 constant.isPotential, 690 constant.isPotential,
693 failedAt( 691 failedAt(
694 fieldElement, 692 field,
695 "Constant expression without value: " 693 "Constant expression without value: "
696 "${constant.toStructuredText()}.")); 694 "${constant.toStructuredText()}."));
697 } 695 }
698 } 696 }
699 } 697 }
700 recordTypeOfField(element, type); 698 recordTypeOfField(field, type);
701 } else if (!element.isInstanceMember) { 699 } else if (!element.isInstanceMember) {
702 recordTypeOfField(element, types.nullType); 700 recordTypeOfField(field, types.nullType);
703 } 701 }
704 } else if (initializer == null) { 702 } else if (initializer == null) {
705 // Only update types of static fields if there is no 703 // Only update types of static fields if there is no
706 // assignment. Instance fields are dealt with in the constructor. 704 // assignment. Instance fields are dealt with in the constructor.
707 if (Elements.isStaticOrTopLevelField(element)) { 705 if (Elements.isStaticOrTopLevelField(element)) {
708 recordTypeOfField(element, type); 706 recordTypeOfField(field, type);
709 } 707 }
710 } else { 708 } else {
711 recordTypeOfField(element, type); 709 recordTypeOfField(field, type);
712 } 710 }
713 if (Elements.isStaticOrTopLevelField(element) && 711 if (Elements.isStaticOrTopLevelField(field) &&
714 resolvedAst.body != null && 712 resolvedAst.body != null &&
715 !element.isConst) { 713 !element.isConst) {
716 dynamic argument = resolvedAst.body; 714 dynamic argument = resolvedAst.body;
717 // TODO(13429): We could do better here by using the 715 // TODO(13429): We could do better here by using the
718 // constant handler to figure out if it's a lazy field or not. 716 // constant handler to figure out if it's a lazy field or not.
719 if (argument.asSend() != null || 717 if (argument.asSend() != null ||
720 (argument.asNewExpression() != null && !argument.isConst)) { 718 (argument.asNewExpression() != null && !argument.isConst)) {
721 recordTypeOfField(element, types.nullType); 719 recordTypeOfField(field, types.nullType);
722 } 720 }
723 } 721 }
724 } else { 722 } else {
725 recordReturnType(element, type); 723 MethodElement method = element;
724 recordReturnType(method, type);
726 } 725 }
727 } 726 }
728 727
729 void processLoopInformation() { 728 void processLoopInformation() {
730 types.allocatedCalls.forEach((dynamic info) { 729 types.allocatedCalls.forEach((dynamic info) {
731 if (!info.inLoop) return; 730 if (!info.inLoop) return;
732 if (info is StaticCallSiteTypeInformation) { 731 if (info is StaticCallSiteTypeInformation) {
733 MemberEntity member = info.calledElement; 732 MemberEntity member = info.calledElement;
734 closedWorldRefiner.addFunctionCalledInLoop(member); 733 closedWorldRefiner.addFunctionCalledInLoop(member);
735 } else if (info.mask != null && !info.mask.containsAll(closedWorld)) { 734 } else if (info.mask != null && !info.mask.containsAll(closedWorld)) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 } else { 849 } else {
851 info.addAssignment(type); 850 info.addAssignment(type);
852 } 851 }
853 parameterIndex++; 852 parameterIndex++;
854 if (addToQueue) workQueue.add(info); 853 if (addToQueue) workQueue.add(info);
855 }); 854 });
856 } 855 }
857 } 856 }
858 857
859 void setDefaultTypeOfParameter( 858 void setDefaultTypeOfParameter(
860 ParameterElement parameter, TypeInformation type) { 859 covariant ParameterElement parameter, TypeInformation type) {
861 assert(parameter.functionDeclaration.isImplementation); 860 assert(parameter.functionDeclaration.isImplementation);
862 TypeInformation existing = defaultTypeOfParameter[parameter]; 861 TypeInformation existing = defaultTypeOfParameter[parameter];
863 defaultTypeOfParameter[parameter] = type; 862 defaultTypeOfParameter[parameter] = type;
864 TypeInformation info = types.getInferredTypeOfParameter(parameter); 863 TypeInformation info = types.getInferredTypeOfParameter(parameter);
865 if (existing != null && existing is PlaceholderTypeInformation) { 864 if (existing != null && existing is PlaceholderTypeInformation) {
866 // Replace references to [existing] to use [type] instead. 865 // Replace references to [existing] to use [type] instead.
867 if (parameter.functionDeclaration.isInstanceMember) { 866 if (parameter.functionDeclaration.isInstanceMember) {
868 ParameterAssignments assignments = info.assignments; 867 ParameterAssignments assignments = info.assignments;
869 assignments.replace(existing, type); 868 assignments.replace(existing, type);
870 } else { 869 } else {
871 List<TypeInformation> assignments = info.assignments; 870 List<TypeInformation> assignments = info.assignments;
872 for (int i = 0; i < assignments.length; i++) { 871 for (int i = 0; i < assignments.length; i++) {
873 if (assignments[i] == existing) { 872 if (assignments[i] == existing) {
874 assignments[i] = type; 873 assignments[i] = type;
875 } 874 }
876 } 875 }
877 } 876 }
878 // Also forward all users. 877 // Also forward all users.
879 type.addUsersOf(existing); 878 type.addUsersOf(existing);
880 } else { 879 } else {
881 assert(existing == null); 880 assert(existing == null);
882 } 881 }
883 } 882 }
884 883
885 TypeInformation getDefaultTypeOfParameter(ParameterElement parameter) { 884 TypeInformation getDefaultTypeOfParameter(Local parameter) {
886 return defaultTypeOfParameter.putIfAbsent(parameter, () { 885 return defaultTypeOfParameter.putIfAbsent(parameter, () {
887 return new PlaceholderTypeInformation(types.currentMember); 886 return new PlaceholderTypeInformation(types.currentMember);
888 }); 887 });
889 } 888 }
890 889
891 bool hasAlreadyComputedTypeOfParameterDefault(ParameterElement parameter) { 890 bool hasAlreadyComputedTypeOfParameterDefault(Local parameter) {
892 TypeInformation seen = defaultTypeOfParameter[parameter]; 891 TypeInformation seen = defaultTypeOfParameter[parameter];
893 return (seen != null && seen is! PlaceholderTypeInformation); 892 return (seen != null && seen is! PlaceholderTypeInformation);
894 } 893 }
895 894
896 TypeInformation typeOfParameter(ParameterElement element) { 895 TypeInformation typeOfParameter(Local element) {
897 return types.getInferredTypeOfParameter(element); 896 return types.getInferredTypeOfParameter(element);
898 } 897 }
899 898
900 TypeInformation typeOfMember(MemberElement element) { 899 TypeInformation typeOfMember(MemberEntity element) {
901 if (element is MethodElement) return types.functionType; 900 if (element is FunctionEntity) return types.functionType;
902 return types.getInferredTypeOfMember(element); 901 return types.getInferredTypeOfMember(element);
903 } 902 }
904 903
905 TypeInformation returnTypeOfMember(MemberElement element) { 904 TypeInformation returnTypeOfMember(MemberEntity element) {
906 if (element is! MethodElement) return types.dynamicType; 905 if (element is! FunctionEntity) return types.dynamicType;
907 return types.getInferredTypeOfMember(element); 906 return types.getInferredTypeOfMember(element);
908 } 907 }
909 908
910 void recordTypeOfField(FieldElement element, TypeInformation type) { 909 void recordTypeOfField(FieldEntity element, TypeInformation type) {
911 types.getInferredTypeOfMember(element).addAssignment(type); 910 types.getInferredTypeOfMember(element).addAssignment(type);
912 } 911 }
913 912
914 void recordReturnType(MethodElement element, TypeInformation type) { 913 void recordReturnType(FunctionEntity element, TypeInformation type) {
915 TypeInformation info = types.getInferredTypeOfMember(element); 914 TypeInformation info = types.getInferredTypeOfMember(element);
916 if (element.name == '==') { 915 if (element.name == '==') {
917 // Even if x.== doesn't return a bool, 'x == null' evaluates to 'false'. 916 // Even if x.== doesn't return a bool, 'x == null' evaluates to 'false'.
918 info.addAssignment(types.boolType); 917 info.addAssignment(types.boolType);
919 } 918 }
920 // TODO(ngeoffray): Clean up. We do these checks because 919 // TODO(ngeoffray): Clean up. We do these checks because
921 // [SimpleTypesInferrer] deals with two different inferrers. 920 // [SimpleTypesInferrer] deals with two different inferrers.
922 if (type == null) return; 921 if (type == null) return;
923 if (info.assignments.isEmpty) info.addAssignment(type); 922 if (info.assignments.isEmpty) info.addAssignment(type);
924 } 923 }
925 924
926 TypeInformation addReturnTypeForMethod( 925 TypeInformation addReturnTypeForMethod(covariant MethodElement element,
927 MethodElement element, TypeInformation unused, TypeInformation newType) { 926 TypeInformation unused, TypeInformation newType) {
928 TypeInformation type = types.getInferredTypeOfMember(element); 927 TypeInformation type = types.getInferredTypeOfMember(element);
929 // TODO(ngeoffray): Clean up. We do this check because 928 // TODO(ngeoffray): Clean up. We do this check because
930 // [SimpleTypesInferrer] deals with two different inferrers. 929 // [SimpleTypesInferrer] deals with two different inferrers.
931 if (element.isGenerativeConstructor) return type; 930 if (element.isGenerativeConstructor) return type;
932 type.addAssignment(newType); 931 type.addAssignment(newType);
933 return type; 932 return type;
934 } 933 }
935 934
936 TypeInformation registerCalledMember( 935 TypeInformation registerCalledMember(
937 Spannable node, 936 Spannable node,
938 Selector selector, 937 Selector selector,
939 TypeMask mask, 938 TypeMask mask,
940 MemberElement caller, 939 MemberEntity caller,
941 MemberElement callee, 940 covariant MemberElement callee,
942 ArgumentsTypes arguments, 941 ArgumentsTypes arguments,
943 SideEffects sideEffects, 942 SideEffects sideEffects,
944 bool inLoop) { 943 bool inLoop) {
945 CallSiteTypeInformation info = new StaticCallSiteTypeInformation( 944 CallSiteTypeInformation info = new StaticCallSiteTypeInformation(
946 types.currentMember, 945 types.currentMember,
947 node, 946 node,
948 caller, 947 caller,
949 callee, 948 callee,
950 selector, 949 selector,
951 mask, 950 mask,
(...skipping 14 matching lines...) Expand all
966 types.allocatedCalls.add(info); 965 types.allocatedCalls.add(info);
967 updateSideEffects(sideEffects, selector, callee); 966 updateSideEffects(sideEffects, selector, callee);
968 return info; 967 return info;
969 } 968 }
970 969
971 TypeInformation registerCalledSelector( 970 TypeInformation registerCalledSelector(
972 ast.Node node, 971 ast.Node node,
973 Selector selector, 972 Selector selector,
974 TypeMask mask, 973 TypeMask mask,
975 TypeInformation receiverType, 974 TypeInformation receiverType,
976 MemberElement caller, 975 MemberEntity caller,
977 ArgumentsTypes arguments, 976 ArgumentsTypes arguments,
978 SideEffects sideEffects, 977 SideEffects sideEffects,
979 bool inLoop, 978 bool inLoop,
980 bool isConditional) { 979 bool isConditional) {
981 if (selector.isClosureCall) { 980 if (selector.isClosureCall) {
982 return registerCalledClosure(node, selector, mask, receiverType, caller, 981 return registerCalledClosure(node, selector, mask, receiverType, caller,
983 arguments, sideEffects, inLoop); 982 arguments, sideEffects, inLoop);
984 } 983 }
985 984
986 closedWorld.locateMembers(selector, mask).forEach((_callee) { 985 closedWorld.locateMembers(selector, mask).forEach((_callee) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 info.addAssignment(argument); 1017 info.addAssignment(argument);
1019 types.allocatedTypes.add(info); 1018 types.allocatedTypes.add(info);
1020 return info; 1019 return info;
1021 } 1020 }
1022 1021
1023 TypeInformation registerCalledClosure( 1022 TypeInformation registerCalledClosure(
1024 ast.Node node, 1023 ast.Node node,
1025 Selector selector, 1024 Selector selector,
1026 TypeMask mask, 1025 TypeMask mask,
1027 TypeInformation closure, 1026 TypeInformation closure,
1028 MemberElement caller, 1027 MemberEntity caller,
1029 ArgumentsTypes arguments, 1028 ArgumentsTypes arguments,
1030 SideEffects sideEffects, 1029 SideEffects sideEffects,
1031 bool inLoop) { 1030 bool inLoop) {
1032 sideEffects.setDependsOnSomething(); 1031 sideEffects.setDependsOnSomething();
1033 sideEffects.setAllSideEffects(); 1032 sideEffects.setAllSideEffects();
1034 CallSiteTypeInformation info = new ClosureCallSiteTypeInformation( 1033 CallSiteTypeInformation info = new ClosureCallSiteTypeInformation(
1035 types.currentMember, 1034 types.currentMember,
1036 node, 1035 node,
1037 caller, 1036 caller,
1038 selector, 1037 selector,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 types.allocatedClosures.forEach(cleanup); 1103 types.allocatedClosures.forEach(cleanup);
1105 types.allocatedClosures.clear(); 1104 types.allocatedClosures.clear();
1106 1105
1107 analyzedElements.clear(); 1106 analyzedElements.clear();
1108 generativeConstructorsExposingThis.clear(); 1107 generativeConstructorsExposingThis.clear();
1109 1108
1110 types.allocatedMaps.values.forEach(cleanup); 1109 types.allocatedMaps.values.forEach(cleanup);
1111 types.allocatedLists.values.forEach(cleanup); 1110 types.allocatedLists.values.forEach(cleanup);
1112 } 1111 }
1113 1112
1114 Iterable<MemberEntity> getCallersOf(MemberElement element) { 1113 Iterable<MemberEntity> getCallersOf(MemberEntity element) {
1115 if (compiler.disableTypeInference) { 1114 if (compiler.disableTypeInference) {
1116 throw new UnsupportedError( 1115 throw new UnsupportedError(
1117 "Cannot query the type inferrer when type inference is disabled."); 1116 "Cannot query the type inferrer when type inference is disabled.");
1118 } 1117 }
1119 MemberTypeInformation info = types.getInferredTypeOfMember(element); 1118 MemberTypeInformation info = types.getInferredTypeOfMember(element);
1120 return info.callers; 1119 return info.callers;
1121 } 1120 }
1122 1121
1123 TypeInformation typeOfMemberWithSelector( 1122 TypeInformation typeOfMemberWithSelector(
1124 MemberElement element, Selector selector) { 1123 covariant MemberElement element, Selector selector) {
1125 if (element.name == Identifiers.noSuchMethod_ && 1124 if (element.name == Identifiers.noSuchMethod_ &&
1126 selector.name != element.name) { 1125 selector.name != element.name) {
1127 // An invocation can resolve to a [noSuchMethod], in which case 1126 // An invocation can resolve to a [noSuchMethod], in which case
1128 // we get the return type of [noSuchMethod]. 1127 // we get the return type of [noSuchMethod].
1129 return returnTypeOfMember(element); 1128 return returnTypeOfMember(element);
1130 } else if (selector.isGetter) { 1129 } else if (selector.isGetter) {
1131 if (element.isFunction) { 1130 if (element.isFunction) {
1132 // [functionType] is null if the inferrer did not run. 1131 // [functionType] is null if the inferrer did not run.
1133 return types.functionType == null 1132 return types.functionType == null
1134 ? types.dynamicType 1133 ? types.dynamicType
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
1243 @override 1242 @override
1244 bool checkPhiNode(ast.Node node) { 1243 bool checkPhiNode(ast.Node node) {
1245 return true; 1244 return true;
1246 } 1245 }
1247 1246
1248 @override 1247 @override
1249 bool checkClassEntity(covariant ClassElement cls) { 1248 bool checkClassEntity(covariant ClassElement cls) {
1250 return cls.isDeclaration; 1249 return cls.isDeclaration;
1251 } 1250 }
1252 } 1251 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/builder.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698