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 |