OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 types; | 5 library types; |
6 | 6 |
7 import '../common.dart' show failedAt; | 7 import '../common.dart' show failedAt; |
8 import '../common/tasks.dart' show CompilerTask; | 8 import '../common/tasks.dart' show CompilerTask; |
9 import '../compiler.dart' show Compiler; | 9 import '../compiler.dart' show Compiler; |
10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
(...skipping 15 matching lines...) Expand all Loading... |
26 /// closed-world semantics. Any [TypeMask] for an element or node that we return | 26 /// closed-world semantics. Any [TypeMask] for an element or node that we return |
27 /// was inferred to be a "guaranteed type", that means, it is a type that we | 27 /// was inferred to be a "guaranteed type", that means, it is a type that we |
28 /// can prove to be correct for all executions of the program. A trivial | 28 /// can prove to be correct for all executions of the program. A trivial |
29 /// implementation would return false on all boolean properties (giving no | 29 /// implementation would return false on all boolean properties (giving no |
30 /// guarantees) and the `subclass of Object or null` type mask for the type | 30 /// guarantees) and the `subclass of Object or null` type mask for the type |
31 /// based queries (the runtime value could be anything). | 31 /// based queries (the runtime value could be anything). |
32 abstract class GlobalTypeInferenceElementResult { | 32 abstract class GlobalTypeInferenceElementResult { |
33 /// Whether the method element associated with this result always throws. | 33 /// Whether the method element associated with this result always throws. |
34 bool get throwsAlways; | 34 bool get throwsAlways; |
35 | 35 |
36 /// Whether the element associated with this result is only called once in one | |
37 /// location in the entire program. | |
38 bool get isCalledOnce; | |
39 | |
40 /// The inferred type when this result belongs to a parameter or field | 36 /// The inferred type when this result belongs to a parameter or field |
41 /// element, null otherwise. | 37 /// element, null otherwise. |
42 TypeMask get type; | 38 TypeMask get type; |
43 | 39 |
44 /// The inferred return type when this result belongs to a function element. | 40 /// The inferred return type when this result belongs to a function element. |
45 TypeMask get returnType; | 41 TypeMask get returnType; |
46 | 42 |
47 /// Returns the type of a list new expression [node]. | 43 /// Returns the type of a list new expression [node]. |
48 TypeMask typeOfNewList(Send node); | 44 TypeMask typeOfNewList(Send node); |
49 | 45 |
(...skipping 14 matching lines...) Expand all Loading... |
64 /// Returns the type of the iterator in a [loop]. | 60 /// Returns the type of the iterator in a [loop]. |
65 TypeMask typeOfIterator(ForIn node); | 61 TypeMask typeOfIterator(ForIn node); |
66 | 62 |
67 /// Returns the type of the `moveNext` call of an iterator in a [loop]. | 63 /// Returns the type of the `moveNext` call of an iterator in a [loop]. |
68 TypeMask typeOfIteratorMoveNext(ForIn node); | 64 TypeMask typeOfIteratorMoveNext(ForIn node); |
69 | 65 |
70 /// Returns the type of the `current` getter of an iterator in a [loop]. | 66 /// Returns the type of the `current` getter of an iterator in a [loop]. |
71 TypeMask typeOfIteratorCurrent(ForIn node); | 67 TypeMask typeOfIteratorCurrent(ForIn node); |
72 } | 68 } |
73 | 69 |
| 70 abstract class GlobalTypeInferenceMemberResult |
| 71 extends GlobalTypeInferenceElementResult { |
| 72 /// Whether the member associated with this result is only called once in one |
| 73 /// location in the entire program. |
| 74 bool get isCalledOnce; |
| 75 } |
| 76 |
74 abstract class GlobalTypeInferenceElementResultImpl | 77 abstract class GlobalTypeInferenceElementResultImpl |
75 implements GlobalTypeInferenceElementResult { | 78 implements GlobalTypeInferenceElementResult { |
76 // TODO(sigmund): delete, store data directly here. | 79 // TODO(sigmund): delete, store data directly here. |
77 final Element _owner; | 80 final Element _owner; |
78 | 81 |
79 // TODO(sigmund): split - stop using _data after inference is done. | 82 // TODO(sigmund): split - stop using _data after inference is done. |
80 final GlobalTypeInferenceElementData _data; | 83 final GlobalTypeInferenceElementData _data; |
81 | 84 |
82 // TODO(sigmund): store relevant data & drop reference to inference engine. | 85 // TODO(sigmund): store relevant data & drop reference to inference engine. |
83 final TypesInferrer _inferrer; | 86 final TypesInferrer _inferrer; |
(...skipping 17 matching lines...) Expand all Loading... |
101 TypeMask typeOfSend(Send node) => _data?.typeOfSend(node); | 104 TypeMask typeOfSend(Send node) => _data?.typeOfSend(node); |
102 TypeMask typeOfGetter(SendSet node) => _data?.typeOfGetter(node); | 105 TypeMask typeOfGetter(SendSet node) => _data?.typeOfGetter(node); |
103 TypeMask typeOfOperator(SendSet node) => _data?.typeOfOperator(node); | 106 TypeMask typeOfOperator(SendSet node) => _data?.typeOfOperator(node); |
104 TypeMask typeOfIterator(ForIn node) => _data?.typeOfIterator(node); | 107 TypeMask typeOfIterator(ForIn node) => _data?.typeOfIterator(node); |
105 TypeMask typeOfIteratorMoveNext(ForIn node) => | 108 TypeMask typeOfIteratorMoveNext(ForIn node) => |
106 _data?.typeOfIteratorMoveNext(node); | 109 _data?.typeOfIteratorMoveNext(node); |
107 TypeMask typeOfIteratorCurrent(ForIn node) => | 110 TypeMask typeOfIteratorCurrent(ForIn node) => |
108 _data?.typeOfIteratorCurrent(node); | 111 _data?.typeOfIteratorCurrent(node); |
109 } | 112 } |
110 | 113 |
111 class GlobalTypeInferenceMemberResult | 114 class GlobalTypeInferenceMemberResultImpl |
112 extends GlobalTypeInferenceElementResultImpl { | 115 extends GlobalTypeInferenceElementResultImpl |
113 GlobalTypeInferenceMemberResult( | 116 implements GlobalTypeInferenceMemberResult { |
| 117 GlobalTypeInferenceMemberResultImpl( |
114 MemberElement owner, | 118 MemberElement owner, |
115 GlobalTypeInferenceElementData data, | 119 GlobalTypeInferenceElementData data, |
116 TypesInferrer inferrer, | 120 TypesInferrer inferrer, |
117 bool isJsInterop, | 121 bool isJsInterop, |
118 TypeMask _dynamic) | 122 TypeMask _dynamic) |
119 : super.internal(owner, data, inferrer, isJsInterop, _dynamic); | 123 : super.internal(owner, data, inferrer, isJsInterop, _dynamic); |
120 | 124 |
121 bool get isCalledOnce => _inferrer.isMemberCalledOnce(_owner); | 125 bool get isCalledOnce => _inferrer.isMemberCalledOnce(_owner); |
122 | 126 |
123 TypeMask get returnType => | 127 TypeMask get returnType => |
124 _isJsInterop ? _dynamic : _inferrer.getReturnTypeOfMember(_owner); | 128 _isJsInterop ? _dynamic : _inferrer.getReturnTypeOfMember(_owner); |
125 | 129 |
126 TypeMask get type => | 130 TypeMask get type => |
127 _isJsInterop ? _dynamic : _inferrer.getTypeOfMember(_owner); | 131 _isJsInterop ? _dynamic : _inferrer.getTypeOfMember(_owner); |
128 } | 132 } |
129 | 133 |
130 class GlobalTypeInferenceParameterResult | 134 class GlobalTypeInferenceParameterResult |
131 extends GlobalTypeInferenceElementResultImpl { | 135 extends GlobalTypeInferenceElementResultImpl { |
132 GlobalTypeInferenceParameterResult( | 136 GlobalTypeInferenceParameterResult( |
133 ParameterElement owner, TypesInferrer inferrer, TypeMask _dynamic) | 137 ParameterElement owner, TypesInferrer inferrer, TypeMask _dynamic) |
134 : super.internal(owner, null, inferrer, false, _dynamic); | 138 : super.internal(owner, null, inferrer, false, _dynamic); |
135 | 139 |
136 bool get isCalledOnce => _inferrer.isParameterCalledOnce(_owner); | |
137 | |
138 TypeMask get returnType => | 140 TypeMask get returnType => |
139 _isJsInterop ? _dynamic : _inferrer.getReturnTypeOfParameter(_owner); | 141 _isJsInterop ? _dynamic : _inferrer.getReturnTypeOfParameter(_owner); |
140 | 142 |
141 TypeMask get type => | 143 TypeMask get type => |
142 _isJsInterop ? _dynamic : _inferrer.getTypeOfParameter(_owner); | 144 _isJsInterop ? _dynamic : _inferrer.getTypeOfParameter(_owner); |
143 } | 145 } |
144 | 146 |
145 /// Internal data used during type-inference to store intermediate results about | 147 /// Internal data used during type-inference to store intermediate results about |
146 /// a single element. | 148 /// a single element. |
147 class GlobalTypeInferenceElementData { | 149 class GlobalTypeInferenceElementData { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 abstract class TypesInferrer { | 200 abstract class TypesInferrer { |
199 void analyzeMain(FunctionEntity element); | 201 void analyzeMain(FunctionEntity element); |
200 TypeMask getReturnTypeOfMember(MemberElement element); | 202 TypeMask getReturnTypeOfMember(MemberElement element); |
201 TypeMask getReturnTypeOfParameter(ParameterElement element); | 203 TypeMask getReturnTypeOfParameter(ParameterElement element); |
202 TypeMask getTypeOfMember(MemberElement element); | 204 TypeMask getTypeOfMember(MemberElement element); |
203 TypeMask getTypeOfParameter(ParameterElement element); | 205 TypeMask getTypeOfParameter(ParameterElement element); |
204 TypeMask getTypeForNewList(Node node); | 206 TypeMask getTypeForNewList(Node node); |
205 TypeMask getTypeOfSelector(Selector selector, TypeMask mask); | 207 TypeMask getTypeOfSelector(Selector selector, TypeMask mask); |
206 void clear(); | 208 void clear(); |
207 bool isMemberCalledOnce(MemberElement element); | 209 bool isMemberCalledOnce(MemberElement element); |
208 bool isParameterCalledOnce(ParameterElement element); | |
209 bool isFixedArrayCheckedForGrowable(Node node); | 210 bool isFixedArrayCheckedForGrowable(Node node); |
210 } | 211 } |
211 | 212 |
212 /// Results produced by the global type-inference algorithm. | 213 /// Results produced by the global type-inference algorithm. |
213 /// | 214 /// |
214 /// All queries in this class may contain results that assume whole-program | 215 /// All queries in this class may contain results that assume whole-program |
215 /// closed-world semantics. Any [TypeMask] for an element or node that we return | 216 /// closed-world semantics. Any [TypeMask] for an element or node that we return |
216 /// was inferred to be a "guaranteed type", that means, it is a type that we | 217 /// was inferred to be a "guaranteed type", that means, it is a type that we |
217 /// can prove to be correct for all executions of the program. | 218 /// can prove to be correct for all executions of the program. |
218 class GlobalTypeInferenceResults { | 219 class GlobalTypeInferenceResults { |
219 // TODO(sigmund): store relevant data & drop reference to inference engine. | 220 // TODO(sigmund): store relevant data & drop reference to inference engine. |
220 final TypeGraphInferrer _inferrer; | 221 final TypeGraphInferrer _inferrer; |
221 final ClosedWorld closedWorld; | 222 final ClosedWorld closedWorld; |
222 final Map<MemberElement, GlobalTypeInferenceMemberResult> _memberResults = | 223 final Map<MemberElement, GlobalTypeInferenceMemberResult> _memberResults = |
223 <MemberElement, GlobalTypeInferenceMemberResult>{}; | 224 <MemberElement, GlobalTypeInferenceMemberResult>{}; |
224 final Map<ParameterElement, GlobalTypeInferenceParameterResult> | 225 final Map<ParameterElement, GlobalTypeInferenceParameterResult> |
225 _parameterResults = | 226 _parameterResults = |
226 <ParameterElement, GlobalTypeInferenceParameterResult>{}; | 227 <ParameterElement, GlobalTypeInferenceParameterResult>{}; |
227 | 228 |
228 // TODO(sigmund,johnniwinther): compute result objects eagerly and make it an | 229 // TODO(sigmund,johnniwinther): compute result objects eagerly and make it an |
229 // error to query for results that don't exist. | 230 // error to query for results that don't exist. |
230 GlobalTypeInferenceElementResult resultOfMember(MemberElement member) { | 231 GlobalTypeInferenceMemberResult resultOfMember(MemberElement member) { |
231 assert( | 232 assert( |
232 !member.isGenerativeConstructorBody, | 233 !member.isGenerativeConstructorBody, |
233 failedAt( | 234 failedAt( |
234 member, | 235 member, |
235 "unexpected input: ConstructorBodyElements are created" | 236 "unexpected input: ConstructorBodyElements are created" |
236 " after global type inference, no data is avaiable for them.")); | 237 " after global type inference, no data is avaiable for them.")); |
237 | 238 |
238 bool isJsInterop = closedWorld.nativeData.isJsInteropMember(member); | 239 bool isJsInterop = closedWorld.nativeData.isJsInteropMember(member); |
239 return _memberResults.putIfAbsent( | 240 return _memberResults.putIfAbsent( |
240 member, | 241 member, |
241 () => new GlobalTypeInferenceMemberResult( | 242 () => new GlobalTypeInferenceMemberResultImpl( |
242 member, | 243 member, |
243 // We store data in the context of the enclosing method, even | 244 // We store data in the context of the enclosing method, even |
244 // for closure elements. | 245 // for closure elements. |
245 _inferrer.inferrer.lookupDataOfMember(member.memberContext), | 246 _inferrer.inferrer.lookupDataOfMember(member.memberContext), |
246 _inferrer, | 247 _inferrer, |
247 isJsInterop, | 248 isJsInterop, |
248 dynamicType)); | 249 dynamicType)); |
249 } | 250 } |
250 | 251 |
251 // TODO(sigmund,johnniwinther): compute result objects eagerly and make it an | 252 // TODO(sigmund,johnniwinther): compute result objects eagerly and make it an |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 measure(() { | 300 measure(() { |
300 typesInferrerInternal ??= | 301 typesInferrerInternal ??= |
301 new TypeGraphInferrer(compiler, closedWorld, closedWorldRefiner); | 302 new TypeGraphInferrer(compiler, closedWorld, closedWorldRefiner); |
302 typesInferrerInternal.analyzeMain(mainElement); | 303 typesInferrerInternal.analyzeMain(mainElement); |
303 typesInferrerInternal.clear(); | 304 typesInferrerInternal.clear(); |
304 results = new GlobalTypeInferenceResults(typesInferrerInternal, | 305 results = new GlobalTypeInferenceResults(typesInferrerInternal, |
305 closedWorld, typesInferrerInternal.inferrer.types); | 306 closedWorld, typesInferrerInternal.inferrer.types); |
306 }); | 307 }); |
307 } | 308 } |
308 } | 309 } |
OLD | NEW |