| OLD | NEW |
| 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 '../common.dart'; | 5 import '../common.dart'; |
| 6 import '../common_elements.dart'; | 6 import '../common_elements.dart'; |
| 7 import '../elements/elements.dart' show Element; | 7 import '../elements/elements.dart' show Element; |
| 8 import '../elements/entities.dart'; | 8 import '../elements/entities.dart'; |
| 9 import '../elements/types.dart'; | 9 import '../elements/types.dart'; |
| 10 import '../util/util.dart' show Setlet; | 10 import '../util/util.dart' show Setlet; |
| 11 import 'backend_helpers.dart'; | |
| 12 import 'backend_impact.dart'; | 11 import 'backend_impact.dart'; |
| 13 | 12 |
| 14 abstract class BackendUsage { | 13 abstract class BackendUsage { |
| 15 bool needToInitializeIsolateAffinityTag; | 14 bool needToInitializeIsolateAffinityTag; |
| 16 bool needToInitializeDispatchProperty; | 15 bool needToInitializeDispatchProperty; |
| 17 | 16 |
| 18 /// Returns `true` if [element] is a function called by the backend. | 17 /// Returns `true` if [element] is a function called by the backend. |
| 19 bool isFunctionUsedByBackend(FunctionEntity element); | 18 bool isFunctionUsedByBackend(FunctionEntity element); |
| 20 | 19 |
| 21 /// Returns `true` if [element] is an instance field of a class instantiated | 20 /// Returns `true` if [element] is an instance field of a class instantiated |
| 22 /// by the backend. | 21 /// by the backend. |
| 23 bool isFieldUsedByBackend(FieldEntity element); | 22 bool isFieldUsedByBackend(FieldEntity element); |
| 24 | 23 |
| 25 Iterable<FunctionEntity> get globalFunctionDependencies; | 24 Iterable<FunctionEntity> get globalFunctionDependencies; |
| 26 | 25 |
| 27 Iterable<ClassEntity> get globalClassDependencies; | 26 Iterable<ClassEntity> get globalClassDependencies; |
| 28 | 27 |
| 29 /// `true` if a core-library function requires the preamble file to function. | 28 /// `true` if a core-library function requires the preamble file to function. |
| 30 bool get requiresPreamble; | 29 bool get requiresPreamble; |
| 31 | 30 |
| 32 /// `true` if [BackendHelpers.invokeOnMethod] is used. | 31 /// `true` if [CommonElements.invokeOnMethod] is used. |
| 33 bool get isInvokeOnUsed; | 32 bool get isInvokeOnUsed; |
| 34 | 33 |
| 35 /// `true` of `Object.runtimeType` is used. | 34 /// `true` of `Object.runtimeType` is used. |
| 36 bool get isRuntimeTypeUsed; | 35 bool get isRuntimeTypeUsed; |
| 37 | 36 |
| 38 /// `true` if the `dart:isolate` library is in use. | 37 /// `true` if the `dart:isolate` library is in use. |
| 39 bool get isIsolateInUse; | 38 bool get isIsolateInUse; |
| 40 | 39 |
| 41 /// `true` if `Function.apply` is used. | 40 /// `true` if `Function.apply` is used. |
| 42 bool get isFunctionApplyUsed; | 41 bool get isFunctionApplyUsed; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 bool isFunctionApplyUsed; | 80 bool isFunctionApplyUsed; |
| 82 | 81 |
| 83 /// `true` if `noSuchMethod` is used. | 82 /// `true` if `noSuchMethod` is used. |
| 84 bool isNoSuchMethodUsed; | 83 bool isNoSuchMethodUsed; |
| 85 | 84 |
| 86 BackendUsage close(); | 85 BackendUsage close(); |
| 87 } | 86 } |
| 88 | 87 |
| 89 class BackendUsageBuilderImpl implements BackendUsageBuilder { | 88 class BackendUsageBuilderImpl implements BackendUsageBuilder { |
| 90 final CommonElements _commonElements; | 89 final CommonElements _commonElements; |
| 91 final BackendHelpers _helpers; | |
| 92 // TODO(johnniwinther): Remove the need for these. | 90 // TODO(johnniwinther): Remove the need for these. |
| 93 Setlet<FunctionEntity> _globalFunctionDependencies; | 91 Setlet<FunctionEntity> _globalFunctionDependencies; |
| 94 Setlet<ClassEntity> _globalClassDependencies; | 92 Setlet<ClassEntity> _globalClassDependencies; |
| 95 | 93 |
| 96 /// List of methods that the backend may use. | 94 /// List of methods that the backend may use. |
| 97 final Set<FunctionEntity> _helperFunctionsUsed = new Set<FunctionEntity>(); | 95 final Set<FunctionEntity> _helperFunctionsUsed = new Set<FunctionEntity>(); |
| 98 | 96 |
| 99 /// List of classes that the backend may use. | 97 /// List of classes that the backend may use. |
| 100 final Set<ClassEntity> _helperClassesUsed = new Set<ClassEntity>(); | 98 final Set<ClassEntity> _helperClassesUsed = new Set<ClassEntity>(); |
| 101 | 99 |
| 102 bool _needToInitializeIsolateAffinityTag = false; | 100 bool _needToInitializeIsolateAffinityTag = false; |
| 103 bool _needToInitializeDispatchProperty = false; | 101 bool _needToInitializeDispatchProperty = false; |
| 104 | 102 |
| 105 /// `true` if a core-library function requires the preamble file to function. | 103 /// `true` if a core-library function requires the preamble file to function. |
| 106 bool requiresPreamble = false; | 104 bool requiresPreamble = false; |
| 107 | 105 |
| 108 /// `true` if [BackendHelpers.invokeOnMethod] is used. | 106 /// `true` if [CommonElements.invokeOnMethod] is used. |
| 109 bool isInvokeOnUsed = false; | 107 bool isInvokeOnUsed = false; |
| 110 | 108 |
| 111 /// `true` of `Object.runtimeType` is used. | 109 /// `true` of `Object.runtimeType` is used. |
| 112 bool isRuntimeTypeUsed = false; | 110 bool isRuntimeTypeUsed = false; |
| 113 | 111 |
| 114 /// `true` if the `dart:isolate` library is in use. | 112 /// `true` if the `dart:isolate` library is in use. |
| 115 bool isIsolateInUse = false; | 113 bool isIsolateInUse = false; |
| 116 | 114 |
| 117 /// `true` if `Function.apply` is used. | 115 /// `true` if `Function.apply` is used. |
| 118 bool isFunctionApplyUsed = false; | 116 bool isFunctionApplyUsed = false; |
| 119 | 117 |
| 120 /// `true` if `noSuchMethod` is used. | 118 /// `true` if `noSuchMethod` is used. |
| 121 bool isNoSuchMethodUsed = false; | 119 bool isNoSuchMethodUsed = false; |
| 122 | 120 |
| 123 BackendUsageBuilderImpl(this._commonElements, this._helpers); | 121 BackendUsageBuilderImpl(this._commonElements); |
| 124 | 122 |
| 125 @override | 123 @override |
| 126 void registerBackendFunctionUse(FunctionEntity element) { | 124 void registerBackendFunctionUse(FunctionEntity element) { |
| 127 assert(invariant(element, _isValidBackendUse(element), | 125 assert(invariant(element, _isValidBackendUse(element), |
| 128 message: "Backend use of $element is not allowed.")); | 126 message: "Backend use of $element is not allowed.")); |
| 129 _helperFunctionsUsed.add(element); | 127 _helperFunctionsUsed.add(element); |
| 130 } | 128 } |
| 131 | 129 |
| 132 @override | 130 @override |
| 133 void registerBackendClassUse(ClassEntity element) { | 131 void registerBackendClassUse(ClassEntity element) { |
| 134 assert(invariant(element, _isValidBackendUse(element), | 132 assert(invariant(element, _isValidBackendUse(element), |
| 135 message: "Backend use of $element is not allowed.")); | 133 message: "Backend use of $element is not allowed.")); |
| 136 _helperClassesUsed.add(element); | 134 _helperClassesUsed.add(element); |
| 137 } | 135 } |
| 138 | 136 |
| 139 bool _isValidBackendUse(Entity element) { | 137 bool _isValidBackendUse(Entity element) { |
| 140 if (_isValidEntity(element)) return true; | 138 if (_isValidEntity(element)) return true; |
| 141 if (element is Element) { | 139 if (element is Element) { |
| 142 assert(invariant(element, element.isDeclaration, | 140 assert(invariant(element, element.isDeclaration, |
| 143 message: "Backend use $element must be the declaration.")); | 141 message: "Backend use $element must be the declaration.")); |
| 144 if (element.implementationLibrary.isPatch || | 142 if (element.implementationLibrary.isPatch || |
| 145 // Needed to detect deserialized injected elements, that is | 143 // Needed to detect deserialized injected elements, that is |
| 146 // element declared in patch files. | 144 // element declared in patch files. |
| 147 (element.library.isPlatformLibrary && | 145 (element.library.isPlatformLibrary && |
| 148 element.sourcePosition.uri.path | 146 element.sourcePosition.uri.path |
| 149 .contains('_internal/js_runtime/lib/')) || | 147 .contains('_internal/js_runtime/lib/')) || |
| 150 element.library == _helpers.jsHelperLibrary || | 148 element.library == _commonElements.jsHelperLibrary || |
| 151 element.library == _helpers.interceptorsLibrary || | 149 element.library == _commonElements.interceptorsLibrary || |
| 152 element.library == _helpers.isolateHelperLibrary) { | 150 element.library == _commonElements.isolateHelperLibrary) { |
| 153 // TODO(johnniwinther): We should be more precise about these. | 151 // TODO(johnniwinther): We should be more precise about these. |
| 154 return true; | 152 return true; |
| 155 } else { | 153 } else { |
| 156 return false; | 154 return false; |
| 157 } | 155 } |
| 158 } | 156 } |
| 159 // TODO(johnniwinther): Support remaining checks on [Entity]s. | 157 // TODO(johnniwinther): Support remaining checks on [Entity]s. |
| 160 return true; | 158 return true; |
| 161 } | 159 } |
| 162 | 160 |
| 163 bool _isValidEntity(Entity element) { | 161 bool _isValidEntity(Entity element) { |
| 164 if (element is ConstructorEntity && | 162 if (element is ConstructorEntity && |
| 165 (element == _helpers.streamIteratorConstructor || | 163 (element == _commonElements.streamIteratorConstructor || |
| 166 _commonElements.isSymbolConstructor(element) || | 164 _commonElements.isSymbolConstructor(element) || |
| 167 _helpers.isSymbolValidatedConstructor(element) || | 165 _commonElements.isSymbolValidatedConstructor(element) || |
| 168 element == _helpers.syncCompleterConstructor)) { | 166 element == _commonElements.syncCompleterConstructor)) { |
| 169 // TODO(johnniwinther): These are valid but we could be more precise. | 167 // TODO(johnniwinther): These are valid but we could be more precise. |
| 170 return true; | 168 return true; |
| 171 } else if (element == _commonElements.symbolClass || | 169 } else if (element == _commonElements.symbolClass || |
| 172 element == _helpers.objectNoSuchMethod) { | 170 element == _commonElements.objectNoSuchMethod) { |
| 173 // TODO(johnniwinther): These are valid but we could be more precise. | 171 // TODO(johnniwinther): These are valid but we could be more precise. |
| 174 return true; | 172 return true; |
| 175 } else if (element == _commonElements.listClass || | 173 } else if (element == _commonElements.listClass || |
| 176 element == _helpers.mapLiteralClass || | 174 element == _commonElements.mapLiteralClass || |
| 177 element == _commonElements.functionClass || | 175 element == _commonElements.functionClass || |
| 178 element == _commonElements.stringClass) { | 176 element == _commonElements.stringClass) { |
| 179 // TODO(johnniwinther): Avoid these. | 177 // TODO(johnniwinther): Avoid these. |
| 180 return true; | 178 return true; |
| 181 } else if (element == _helpers.genericNoSuchMethod || | 179 } else if (element == _commonElements.genericNoSuchMethod || |
| 182 element == _helpers.unresolvedConstructorError || | 180 element == _commonElements.unresolvedConstructorError || |
| 183 element == _helpers.malformedTypeError) { | 181 element == _commonElements.malformedTypeError) { |
| 184 return true; | 182 return true; |
| 185 } | 183 } |
| 186 return false; | 184 return false; |
| 187 } | 185 } |
| 188 | 186 |
| 189 void _processBackendStaticUse(FunctionEntity element, | 187 void _processBackendStaticUse(FunctionEntity element, |
| 190 {bool isGlobal: false}) { | 188 {bool isGlobal: false}) { |
| 191 registerBackendFunctionUse(element); | 189 registerBackendFunctionUse(element); |
| 192 if (isGlobal) { | 190 if (isGlobal) { |
| 193 registerGlobalFunctionDependency(element); | 191 registerGlobalFunctionDependency(element); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 _needToInitializeDispatchProperty = true; | 226 _needToInitializeDispatchProperty = true; |
| 229 break; | 227 break; |
| 230 case BackendFeature.needToInitializeIsolateAffinityTag: | 228 case BackendFeature.needToInitializeIsolateAffinityTag: |
| 231 _needToInitializeIsolateAffinityTag = true; | 229 _needToInitializeIsolateAffinityTag = true; |
| 232 break; | 230 break; |
| 233 } | 231 } |
| 234 } | 232 } |
| 235 } | 233 } |
| 236 | 234 |
| 237 void registerUsedMember(MemberEntity member) { | 235 void registerUsedMember(MemberEntity member) { |
| 238 if (member == _helpers.getIsolateAffinityTagMarker) { | 236 if (member == _commonElements.getIsolateAffinityTagMarker) { |
| 239 _needToInitializeIsolateAffinityTag = true; | 237 _needToInitializeIsolateAffinityTag = true; |
| 240 } else if (member == _helpers.requiresPreambleMarker) { | 238 } else if (member == _commonElements.requiresPreambleMarker) { |
| 241 requiresPreamble = true; | 239 requiresPreamble = true; |
| 242 } else if (member == _helpers.invokeOnMethod) { | 240 } else if (member == _commonElements.invokeOnMethod) { |
| 243 isInvokeOnUsed = true; | 241 isInvokeOnUsed = true; |
| 244 } else if (_commonElements.isFunctionApplyMethod(member)) { | 242 } else if (_commonElements.isFunctionApplyMethod(member)) { |
| 245 isFunctionApplyUsed = true; | 243 isFunctionApplyUsed = true; |
| 246 } | 244 } |
| 247 } | 245 } |
| 248 | 246 |
| 249 void registerGlobalFunctionDependency(FunctionEntity element) { | 247 void registerGlobalFunctionDependency(FunctionEntity element) { |
| 250 assert(element != null); | 248 assert(element != null); |
| 251 if (_globalFunctionDependencies == null) { | 249 if (_globalFunctionDependencies == null) { |
| 252 _globalFunctionDependencies = new Setlet<FunctionEntity>(); | 250 _globalFunctionDependencies = new Setlet<FunctionEntity>(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 | 287 |
| 290 /// Set of classes instantiated by the backend. | 288 /// Set of classes instantiated by the backend. |
| 291 final Set<ClassEntity> _helperClassesUsed; | 289 final Set<ClassEntity> _helperClassesUsed; |
| 292 | 290 |
| 293 bool needToInitializeIsolateAffinityTag; | 291 bool needToInitializeIsolateAffinityTag; |
| 294 bool needToInitializeDispatchProperty; | 292 bool needToInitializeDispatchProperty; |
| 295 | 293 |
| 296 /// `true` if a core-library function requires the preamble file to function. | 294 /// `true` if a core-library function requires the preamble file to function. |
| 297 final bool requiresPreamble; | 295 final bool requiresPreamble; |
| 298 | 296 |
| 299 /// `true` if [BackendHelpers.invokeOnMethod] is used. | 297 /// `true` if [CommonElements.invokeOnMethod] is used. |
| 300 final bool isInvokeOnUsed; | 298 final bool isInvokeOnUsed; |
| 301 | 299 |
| 302 /// `true` of `Object.runtimeType` is used. | 300 /// `true` of `Object.runtimeType` is used. |
| 303 final bool isRuntimeTypeUsed; | 301 final bool isRuntimeTypeUsed; |
| 304 | 302 |
| 305 /// `true` if the `dart:isolate` library is in use. | 303 /// `true` if the `dart:isolate` library is in use. |
| 306 final bool isIsolateInUse; | 304 final bool isIsolateInUse; |
| 307 | 305 |
| 308 /// `true` if `Function.apply` is used. | 306 /// `true` if `Function.apply` is used. |
| 309 final bool isFunctionApplyUsed; | 307 final bool isFunctionApplyUsed; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 339 return _helperClassesUsed.contains(element.enclosingClass); | 337 return _helperClassesUsed.contains(element.enclosingClass); |
| 340 } | 338 } |
| 341 | 339 |
| 342 @override | 340 @override |
| 343 Iterable<FunctionEntity> get globalFunctionDependencies => | 341 Iterable<FunctionEntity> get globalFunctionDependencies => |
| 344 _globalFunctionDependencies; | 342 _globalFunctionDependencies; |
| 345 | 343 |
| 346 @override | 344 @override |
| 347 Iterable<ClassEntity> get globalClassDependencies => _globalClassDependencies; | 345 Iterable<ClassEntity> get globalClassDependencies => _globalClassDependencies; |
| 348 } | 346 } |
| OLD | NEW |