| 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'; | |
| 13 import '../compile_time_constants.dart'; | 12 import '../compile_time_constants.dart'; |
| 14 import '../constants/constant_system.dart'; | 13 import '../constants/constant_system.dart'; |
| 15 import '../constants/values.dart' | 14 import '../constants/values.dart' |
| 16 show | 15 show |
| 17 ConstantValue, | 16 ConstantValue, |
| 18 ConstructedConstantValue, | 17 ConstructedConstantValue, |
| 19 ListConstantValue, | 18 ListConstantValue, |
| 20 NullConstantValue, | 19 NullConstantValue, |
| 21 StringConstantValue, | 20 StringConstantValue, |
| 22 TypeConstantValue; | 21 TypeConstantValue; |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 // TODO(sigmund): detect uses of mirrors | 119 // TODO(sigmund): detect uses of mirrors |
| 121 class LookupMapAnalysis { | 120 class LookupMapAnalysis { |
| 122 const LookupMapAnalysis._(); | 121 const LookupMapAnalysis._(); |
| 123 | 122 |
| 124 factory LookupMapAnalysis( | 123 factory LookupMapAnalysis( |
| 125 DiagnosticReporter reporter, | 124 DiagnosticReporter reporter, |
| 126 ConstantSystem constantSystem, | 125 ConstantSystem constantSystem, |
| 127 ConstantEnvironment constants, | 126 ConstantEnvironment constants, |
| 128 ElementEnvironment elementEnvironment, | 127 ElementEnvironment elementEnvironment, |
| 129 CommonElements commonElements, | 128 CommonElements commonElements, |
| 130 BackendClasses backendClasses, | |
| 131 LookupMapResolutionAnalysis analysis) { | 129 LookupMapResolutionAnalysis analysis) { |
| 132 /// Checks if the version of lookup_map is valid, and if so, enable this | 130 /// Checks if the version of lookup_map is valid, and if so, enable this |
| 133 /// analysis during codegen. | 131 /// analysis during codegen. |
| 134 FieldElement lookupMapVersionVariable = analysis.lookupMapVersionVariable; | 132 FieldElement lookupMapVersionVariable = analysis.lookupMapVersionVariable; |
| 135 if (lookupMapVersionVariable == null) return const LookupMapAnalysis._(); | 133 if (lookupMapVersionVariable == null) return const LookupMapAnalysis._(); |
| 136 | 134 |
| 137 // At this point, the lookupMapVersionVariable should be resolved and it's | 135 // At this point, the lookupMapVersionVariable should be resolved and it's |
| 138 // constant value should be available. | 136 // constant value should be available. |
| 139 StringConstantValue value = | 137 StringConstantValue value = |
| 140 constants.getConstantValue(lookupMapVersionVariable.constant); | 138 constants.getConstantValue(lookupMapVersionVariable.constant); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 160 ClassEntity typeLookupMapClass = | 158 ClassEntity typeLookupMapClass = |
| 161 elementEnvironment.lookupClass(analysis.lookupMapLibrary, 'LookupMap'); | 159 elementEnvironment.lookupClass(analysis.lookupMapLibrary, 'LookupMap'); |
| 162 FieldElement entriesField = | 160 FieldElement entriesField = |
| 163 elementEnvironment.lookupClassMember(typeLookupMapClass, '_entries'); | 161 elementEnvironment.lookupClassMember(typeLookupMapClass, '_entries'); |
| 164 FieldElement keyField = | 162 FieldElement keyField = |
| 165 elementEnvironment.lookupClassMember(typeLookupMapClass, '_key'); | 163 elementEnvironment.lookupClassMember(typeLookupMapClass, '_key'); |
| 166 FieldElement valueField = | 164 FieldElement valueField = |
| 167 elementEnvironment.lookupClassMember(typeLookupMapClass, '_value'); | 165 elementEnvironment.lookupClassMember(typeLookupMapClass, '_value'); |
| 168 // TODO(sigmund): Maybe inline nested maps to make the output code smaller? | 166 // TODO(sigmund): Maybe inline nested maps to make the output code smaller? |
| 169 | 167 |
| 170 return new _LookupMapAnalysis(constantSystem, commonElements, | 168 return new _LookupMapAnalysis(constantSystem, commonElements, entriesField, |
| 171 backendClasses, entriesField, keyField, valueField, typeLookupMapClass); | 169 keyField, valueField, typeLookupMapClass); |
| 172 } | 170 } |
| 173 | 171 |
| 174 /// Compute the [WorldImpact] for the constants registered since last flush. | 172 /// Compute the [WorldImpact] for the constants registered since last flush. |
| 175 WorldImpact flush() => const WorldImpact(); | 173 WorldImpact flush() => const WorldImpact(); |
| 176 | 174 |
| 177 /// Whether [constant] is an instance of a `LookupMap`. | 175 /// Whether [constant] is an instance of a `LookupMap`. |
| 178 bool isLookupMap(ConstantValue constant) => false; | 176 bool isLookupMap(ConstantValue constant) => false; |
| 179 | 177 |
| 180 /// Registers an instance of a lookup-map with the analysis. | 178 /// Registers an instance of a lookup-map with the analysis. |
| 181 void registerLookupMapReference(ConstantValue lookupMap) {} | 179 void registerLookupMapReference(ConstantValue lookupMap) {} |
| (...skipping 16 matching lines...) Expand all Loading... |
| 198 } | 196 } |
| 199 | 197 |
| 200 class _LookupMapAnalysis implements LookupMapAnalysis { | 198 class _LookupMapAnalysis implements LookupMapAnalysis { |
| 201 static final Uri PACKAGE_LOOKUP_MAP = | 199 static final Uri PACKAGE_LOOKUP_MAP = |
| 202 new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart'); | 200 new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart'); |
| 203 | 201 |
| 204 final ConstantSystem _constantSystem; | 202 final ConstantSystem _constantSystem; |
| 205 | 203 |
| 206 final CommonElements _commonElements; | 204 final CommonElements _commonElements; |
| 207 | 205 |
| 208 final BackendClasses _backendClasses; | |
| 209 | |
| 210 /// The resolved [ClassElement] associated with `LookupMap`. | 206 /// The resolved [ClassElement] associated with `LookupMap`. |
| 211 final ClassElement _typeLookupMapClass; | 207 final ClassElement _typeLookupMapClass; |
| 212 | 208 |
| 213 /// The resolved [FieldElement] for `LookupMap._entries`. | 209 /// The resolved [FieldElement] for `LookupMap._entries`. |
| 214 final FieldElement _entriesField; | 210 final FieldElement _entriesField; |
| 215 | 211 |
| 216 /// The resolved [FieldElement] for `LookupMap._key`. | 212 /// The resolved [FieldElement] for `LookupMap._key`. |
| 217 final FieldElement _keyField; | 213 final FieldElement _keyField; |
| 218 | 214 |
| 219 /// The resolved [FieldElement] for `LookupMap._value`. | 215 /// The resolved [FieldElement] for `LookupMap._value`. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 243 /// that we haven't seen, we record the list of lookup-maps that contain an | 239 /// that we haven't seen, we record the list of lookup-maps that contain an |
| 244 /// entry with that key. | 240 /// entry with that key. |
| 245 final _pending = <ConstantValue, List<_LookupMapInfo>>{}; | 241 final _pending = <ConstantValue, List<_LookupMapInfo>>{}; |
| 246 | 242 |
| 247 final StagedWorldImpactBuilder _impactBuilder = | 243 final StagedWorldImpactBuilder _impactBuilder = |
| 248 new StagedWorldImpactBuilder(); | 244 new StagedWorldImpactBuilder(); |
| 249 | 245 |
| 250 _LookupMapAnalysis( | 246 _LookupMapAnalysis( |
| 251 this._constantSystem, | 247 this._constantSystem, |
| 252 this._commonElements, | 248 this._commonElements, |
| 253 this._backendClasses, | |
| 254 this._entriesField, | 249 this._entriesField, |
| 255 this._keyField, | 250 this._keyField, |
| 256 this._valueField, | 251 this._valueField, |
| 257 this._typeLookupMapClass); | 252 this._typeLookupMapClass); |
| 258 | 253 |
| 259 /// Compute the [WorldImpact] for the constants registered since last flush. | 254 /// Compute the [WorldImpact] for the constants registered since last flush. |
| 260 WorldImpact flush() { | 255 WorldImpact flush() { |
| 261 return _impactBuilder.flush(); | 256 return _impactBuilder.flush(); |
| 262 } | 257 } |
| 263 | 258 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 288 } | 283 } |
| 289 | 284 |
| 290 /// Whether we need to preserve [key]. This is true for keys that are not | 285 /// Whether we need to preserve [key]. This is true for keys that are not |
| 291 /// candidates for tree-shaking in the first place (primitives and non-type | 286 /// candidates for tree-shaking in the first place (primitives and non-type |
| 292 /// const values overriding equals) and keys that we have seen in the program. | 287 /// const values overriding equals) and keys that we have seen in the program. |
| 293 bool _shouldKeep(ConstantValue key) => | 288 bool _shouldKeep(ConstantValue key) => |
| 294 key.isPrimitive || _inUse.contains(key) || _overridesEquals(key); | 289 key.isPrimitive || _inUse.contains(key) || _overridesEquals(key); |
| 295 | 290 |
| 296 void _addClassUse(ClassElement cls) { | 291 void _addClassUse(ClassElement cls) { |
| 297 ConstantValue key = _typeConstants.putIfAbsent( | 292 ConstantValue key = _typeConstants.putIfAbsent( |
| 298 cls, | 293 cls, () => _constantSystem.createType(_commonElements, cls.rawType)); |
| 299 () => _constantSystem.createType( | |
| 300 _commonElements, _backendClasses, cls.rawType)); | |
| 301 _addUse(key); | 294 _addUse(key); |
| 302 } | 295 } |
| 303 | 296 |
| 304 /// Record that [key] is used and update every lookup map that contains it. | 297 /// Record that [key] is used and update every lookup map that contains it. |
| 305 void _addUse(ConstantValue key) { | 298 void _addUse(ConstantValue key) { |
| 306 if (_inUse.add(key)) { | 299 if (_inUse.add(key)) { |
| 307 _pending[key]?.forEach((info) => info._markUsed(key)); | 300 _pending[key]?.forEach((info) => info._markUsed(key)); |
| 308 _pending.remove(key); | 301 _pending.remove(key); |
| 309 } | 302 } |
| 310 } | 303 } |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 original.fields[analysis._valueField] = keyValuePairs[1]; | 497 original.fields[analysis._valueField] = keyValuePairs[1]; |
| 505 } | 498 } |
| 506 } else { | 499 } else { |
| 507 original.fields[analysis._entriesField] = | 500 original.fields[analysis._entriesField] = |
| 508 new ListConstantValue(listType, keyValuePairs); | 501 new ListConstantValue(listType, keyValuePairs); |
| 509 } | 502 } |
| 510 } | 503 } |
| 511 } | 504 } |
| 512 | 505 |
| 513 final _validLookupMapVersionConstraint = new VersionConstraint.parse('^0.0.1'); | 506 final _validLookupMapVersionConstraint = new VersionConstraint.parse('^0.0.1'); |
| OLD | NEW |