OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 /// Analysis to determine how to generate code for `LookupMap`s. | 5 /// Analysis to determine how to generate code for `LookupMap`s. |
6 library compiler.src.js_backend.lookup_map_analysis; | 6 library compiler.src.js_backend.lookup_map_analysis; |
7 | 7 |
8 import 'package:pub_semver/pub_semver.dart'; | 8 import 'package:pub_semver/pub_semver.dart'; |
9 | 9 |
10 import '../common.dart'; | 10 import '../common.dart'; |
11 import '../common_elements.dart'; | 11 import '../common_elements.dart'; |
12 import '../common/backend_api.dart'; | 12 import '../common/backend_api.dart'; |
13 import '../compile_time_constants.dart'; | 13 import '../compile_time_constants.dart'; |
14 import '../constants/constant_system.dart'; | 14 import '../constants/constant_system.dart'; |
15 import '../constants/values.dart' | 15 import '../constants/values.dart' |
16 show | 16 show |
17 ConstantValue, | 17 ConstantValue, |
18 ConstructedConstantValue, | 18 ConstructedConstantValue, |
19 ListConstantValue, | 19 ListConstantValue, |
20 NullConstantValue, | 20 NullConstantValue, |
21 StringConstantValue, | 21 StringConstantValue, |
22 TypeConstantValue; | 22 TypeConstantValue; |
23 import '../elements/elements.dart' show ClassElement, FieldElement; | 23 import '../elements/elements.dart' show ClassElement, FieldElement; |
24 import '../elements/entities.dart'; | 24 import '../elements/entities.dart'; |
25 import '../elements/resolution_types.dart' show ResolutionInterfaceType; | 25 import '../elements/resolution_types.dart' show ResolutionInterfaceType; |
26 import '../universe/use.dart' show ConstantUse, StaticUse; | 26 import '../universe/use.dart' show ConstantUse, StaticUse; |
27 import '../universe/world_impact.dart' | 27 import '../universe/world_impact.dart' |
28 show WorldImpact, StagedWorldImpactBuilder; | 28 show WorldImpact, StagedWorldImpactBuilder; |
29 import 'backend_helpers.dart'; | |
30 | 29 |
31 /// Lookup map handling for resolution. | 30 /// Lookup map handling for resolution. |
32 /// | 31 /// |
33 /// This analysis checks for the import of `package:lookup_map/lookup_map.dart`, | 32 /// This analysis checks for the import of `package:lookup_map/lookup_map.dart`, |
34 /// and if found, read the `_version` variable from it. | 33 /// and if found, read the `_version` variable from it. |
35 /// | 34 /// |
36 /// In [LookupMapAnalysis] the value of `_version` is checked to ensure that it | 35 /// In [LookupMapAnalysis] the value of `_version` is checked to ensure that it |
37 /// is valid to perform the optimization of `LookupMap`. The actual optimization | 36 /// is valid to perform the optimization of `LookupMap`. The actual optimization |
38 /// is performed by [LookupMapAnalysis]. | 37 /// is performed by [LookupMapAnalysis]. |
39 class LookupMapResolutionAnalysis { | 38 class LookupMapResolutionAnalysis { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 // TODO(sigmund): detect uses of mirrors | 120 // TODO(sigmund): detect uses of mirrors |
122 class LookupMapAnalysis { | 121 class LookupMapAnalysis { |
123 const LookupMapAnalysis._(); | 122 const LookupMapAnalysis._(); |
124 | 123 |
125 factory LookupMapAnalysis( | 124 factory LookupMapAnalysis( |
126 DiagnosticReporter reporter, | 125 DiagnosticReporter reporter, |
127 ConstantSystem constantSystem, | 126 ConstantSystem constantSystem, |
128 ConstantEnvironment constants, | 127 ConstantEnvironment constants, |
129 ElementEnvironment elementEnvironment, | 128 ElementEnvironment elementEnvironment, |
130 CommonElements commonElements, | 129 CommonElements commonElements, |
131 BackendHelpers helpers, | |
132 BackendClasses backendClasses, | 130 BackendClasses backendClasses, |
133 LookupMapResolutionAnalysis analysis) { | 131 LookupMapResolutionAnalysis analysis) { |
134 /// Checks if the version of lookup_map is valid, and if so, enable this | 132 /// Checks if the version of lookup_map is valid, and if so, enable this |
135 /// analysis during codegen. | 133 /// analysis during codegen. |
136 FieldElement lookupMapVersionVariable = analysis.lookupMapVersionVariable; | 134 FieldElement lookupMapVersionVariable = analysis.lookupMapVersionVariable; |
137 if (lookupMapVersionVariable == null) return const LookupMapAnalysis._(); | 135 if (lookupMapVersionVariable == null) return const LookupMapAnalysis._(); |
138 | 136 |
139 // At this point, the lookupMapVersionVariable should be resolved and it's | 137 // At this point, the lookupMapVersionVariable should be resolved and it's |
140 // constant value should be available. | 138 // constant value should be available. |
141 StringConstantValue value = | 139 StringConstantValue value = |
(...skipping 20 matching lines...) Expand all Loading... |
162 ClassEntity typeLookupMapClass = | 160 ClassEntity typeLookupMapClass = |
163 elementEnvironment.lookupClass(analysis.lookupMapLibrary, 'LookupMap'); | 161 elementEnvironment.lookupClass(analysis.lookupMapLibrary, 'LookupMap'); |
164 FieldElement entriesField = | 162 FieldElement entriesField = |
165 elementEnvironment.lookupClassMember(typeLookupMapClass, '_entries'); | 163 elementEnvironment.lookupClassMember(typeLookupMapClass, '_entries'); |
166 FieldElement keyField = | 164 FieldElement keyField = |
167 elementEnvironment.lookupClassMember(typeLookupMapClass, '_key'); | 165 elementEnvironment.lookupClassMember(typeLookupMapClass, '_key'); |
168 FieldElement valueField = | 166 FieldElement valueField = |
169 elementEnvironment.lookupClassMember(typeLookupMapClass, '_value'); | 167 elementEnvironment.lookupClassMember(typeLookupMapClass, '_value'); |
170 // TODO(sigmund): Maybe inline nested maps to make the output code smaller? | 168 // TODO(sigmund): Maybe inline nested maps to make the output code smaller? |
171 | 169 |
172 return new _LookupMapAnalysis(constantSystem, commonElements, helpers, | 170 return new _LookupMapAnalysis(constantSystem, commonElements, |
173 backendClasses, entriesField, keyField, valueField, typeLookupMapClass); | 171 backendClasses, entriesField, keyField, valueField, typeLookupMapClass); |
174 } | 172 } |
175 | 173 |
176 /// Compute the [WorldImpact] for the constants registered since last flush. | 174 /// Compute the [WorldImpact] for the constants registered since last flush. |
177 WorldImpact flush() => const WorldImpact(); | 175 WorldImpact flush() => const WorldImpact(); |
178 | 176 |
179 /// Whether [constant] is an instance of a `LookupMap`. | 177 /// Whether [constant] is an instance of a `LookupMap`. |
180 bool isLookupMap(ConstantValue constant) => false; | 178 bool isLookupMap(ConstantValue constant) => false; |
181 | 179 |
182 /// Registers an instance of a lookup-map with the analysis. | 180 /// Registers an instance of a lookup-map with the analysis. |
(...skipping 17 matching lines...) Expand all Loading... |
200 } | 198 } |
201 | 199 |
202 class _LookupMapAnalysis implements LookupMapAnalysis { | 200 class _LookupMapAnalysis implements LookupMapAnalysis { |
203 static final Uri PACKAGE_LOOKUP_MAP = | 201 static final Uri PACKAGE_LOOKUP_MAP = |
204 new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart'); | 202 new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart'); |
205 | 203 |
206 final ConstantSystem _constantSystem; | 204 final ConstantSystem _constantSystem; |
207 | 205 |
208 final CommonElements _commonElements; | 206 final CommonElements _commonElements; |
209 | 207 |
210 final BackendHelpers _helpers; | |
211 | |
212 final BackendClasses _backendClasses; | 208 final BackendClasses _backendClasses; |
213 | 209 |
214 /// The resolved [ClassElement] associated with `LookupMap`. | 210 /// The resolved [ClassElement] associated with `LookupMap`. |
215 final ClassElement _typeLookupMapClass; | 211 final ClassElement _typeLookupMapClass; |
216 | 212 |
217 /// The resolved [FieldElement] for `LookupMap._entries`. | 213 /// The resolved [FieldElement] for `LookupMap._entries`. |
218 final FieldElement _entriesField; | 214 final FieldElement _entriesField; |
219 | 215 |
220 /// The resolved [FieldElement] for `LookupMap._key`. | 216 /// The resolved [FieldElement] for `LookupMap._key`. |
221 final FieldElement _keyField; | 217 final FieldElement _keyField; |
(...skipping 25 matching lines...) Expand all Loading... |
247 /// that we haven't seen, we record the list of lookup-maps that contain an | 243 /// that we haven't seen, we record the list of lookup-maps that contain an |
248 /// entry with that key. | 244 /// entry with that key. |
249 final _pending = <ConstantValue, List<_LookupMapInfo>>{}; | 245 final _pending = <ConstantValue, List<_LookupMapInfo>>{}; |
250 | 246 |
251 final StagedWorldImpactBuilder _impactBuilder = | 247 final StagedWorldImpactBuilder _impactBuilder = |
252 new StagedWorldImpactBuilder(); | 248 new StagedWorldImpactBuilder(); |
253 | 249 |
254 _LookupMapAnalysis( | 250 _LookupMapAnalysis( |
255 this._constantSystem, | 251 this._constantSystem, |
256 this._commonElements, | 252 this._commonElements, |
257 this._helpers, | |
258 this._backendClasses, | 253 this._backendClasses, |
259 this._entriesField, | 254 this._entriesField, |
260 this._keyField, | 255 this._keyField, |
261 this._valueField, | 256 this._valueField, |
262 this._typeLookupMapClass); | 257 this._typeLookupMapClass); |
263 | 258 |
264 /// Compute the [WorldImpact] for the constants registered since last flush. | 259 /// Compute the [WorldImpact] for the constants registered since last flush. |
265 WorldImpact flush() { | 260 WorldImpact flush() { |
266 return _impactBuilder.flush(); | 261 return _impactBuilder.flush(); |
267 } | 262 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 void _addGenerics(ResolutionInterfaceType type) { | 339 void _addGenerics(ResolutionInterfaceType type) { |
345 if (!type.isGeneric) return; | 340 if (!type.isGeneric) return; |
346 for (var arg in type.typeArguments) { | 341 for (var arg in type.typeArguments) { |
347 if (arg is ResolutionInterfaceType) { | 342 if (arg is ResolutionInterfaceType) { |
348 _addClassUse(arg.element); | 343 _addClassUse(arg.element); |
349 // Note: this call was needed to generate correct code for | 344 // Note: this call was needed to generate correct code for |
350 // type_lookup_map/generic_type_test | 345 // type_lookup_map/generic_type_test |
351 // TODO(sigmund): can we get rid of this? | 346 // TODO(sigmund): can we get rid of this? |
352 _impactBuilder.registerStaticUse(new StaticUse.staticInvoke( | 347 _impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
353 // TODO(johnniwinther): Find the right [CallStructure]. | 348 // TODO(johnniwinther): Find the right [CallStructure]. |
354 _helpers.createRuntimeType, | 349 _commonElements.createRuntimeType, |
355 null)); | 350 null)); |
356 _addGenerics(arg); | 351 _addGenerics(arg); |
357 } | 352 } |
358 } | 353 } |
359 } | 354 } |
360 | 355 |
361 /// Callback from the codegen enqueuer, invoked when a constant (which is | 356 /// Callback from the codegen enqueuer, invoked when a constant (which is |
362 /// possibly a const key or a type literal) is used in the program. | 357 /// possibly a const key or a type literal) is used in the program. |
363 void registerTypeConstant(ClassElement element) { | 358 void registerTypeConstant(ClassElement element) { |
364 _addClassUse(element); | 359 _addClassUse(element); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 original.fields[analysis._valueField] = keyValuePairs[1]; | 504 original.fields[analysis._valueField] = keyValuePairs[1]; |
510 } | 505 } |
511 } else { | 506 } else { |
512 original.fields[analysis._entriesField] = | 507 original.fields[analysis._entriesField] = |
513 new ListConstantValue(listType, keyValuePairs); | 508 new ListConstantValue(listType, keyValuePairs); |
514 } | 509 } |
515 } | 510 } |
516 } | 511 } |
517 | 512 |
518 final _validLookupMapVersionConstraint = new VersionConstraint.parse('^0.0.1'); | 513 final _validLookupMapVersionConstraint = new VersionConstraint.parse('^0.0.1'); |
OLD | NEW |