| 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 |