OLD | NEW |
1 | 1 |
2 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 library dart2js.common.resolution; | 6 library dart2js.common.resolution; |
7 | 7 |
8 import '../compiler.dart' show | 8 import '../compiler.dart' show |
9 Compiler; | 9 Compiler; |
10 import '../core_types.dart' show | 10 import '../core_types.dart' show |
11 CoreTypes; | 11 CoreTypes; |
12 import '../dart_types.dart' show | 12 import '../dart_types.dart' show |
13 DartType, | 13 DartType; |
14 InterfaceType; | |
15 import '../diagnostics/diagnostic_listener.dart' show | 14 import '../diagnostics/diagnostic_listener.dart' show |
16 DiagnosticReporter; | 15 DiagnosticReporter; |
17 import '../elements/elements.dart' show | 16 import '../elements/elements.dart' show |
18 AstElement, | 17 AstElement, |
19 ClassElement, | 18 ClassElement, |
20 Element, | 19 Element, |
21 ErroneousElement, | 20 ErroneousElement, |
22 FunctionElement, | 21 FunctionElement, |
23 FunctionSignature, | 22 FunctionSignature, |
24 LocalFunctionElement, | |
25 MetadataAnnotation, | 23 MetadataAnnotation, |
26 MethodElement, | |
27 TypedefElement, | 24 TypedefElement, |
28 TypeVariableElement; | 25 TypeVariableElement; |
29 import '../enqueue.dart' show | 26 import '../enqueue.dart' show |
30 ResolutionEnqueuer, | 27 ResolutionEnqueuer, |
31 WorldImpact; | 28 WorldImpact; |
32 import '../tree/tree.dart' show | 29 import '../tree/tree.dart' show |
33 AsyncForIn, | 30 AsyncForIn, |
34 Send, | 31 Send, |
35 TypeAnnotation; | 32 TypeAnnotation; |
36 import '../universe/universe.dart' show | |
37 UniverseSelector; | |
38 import '../util/util.dart' show | |
39 Setlet; | |
40 import 'registry.dart' show | 33 import 'registry.dart' show |
41 Registry; | 34 Registry; |
42 import 'work.dart' show | 35 import 'work.dart' show |
43 ItemCompilationContext, | 36 ItemCompilationContext, |
44 WorkItem; | 37 WorkItem; |
45 | 38 |
46 /// [WorkItem] used exclusively by the [ResolutionEnqueuer]. | 39 /// [WorkItem] used exclusively by the [ResolutionEnqueuer]. |
47 class ResolutionWorkItem extends WorkItem { | 40 class ResolutionWorkItem extends WorkItem { |
48 bool _isAnalyzed = false; | 41 bool _isAnalyzed = false; |
49 | 42 |
50 ResolutionWorkItem(AstElement element, | 43 ResolutionWorkItem(AstElement element, |
51 ItemCompilationContext compilationContext) | 44 ItemCompilationContext compilationContext) |
52 : super(element, compilationContext); | 45 : super(element, compilationContext); |
53 | 46 |
54 WorldImpact run(Compiler compiler, ResolutionEnqueuer world) { | 47 WorldImpact run(Compiler compiler, ResolutionEnqueuer world) { |
55 WorldImpact impact = compiler.analyze(this, world); | 48 WorldImpact impact = compiler.analyze(this, world); |
56 impact = compiler.backend.resolutionCallbacks.transformImpact(impact); | |
57 _isAnalyzed = true; | 49 _isAnalyzed = true; |
58 return impact; | 50 return impact; |
59 } | 51 } |
60 | 52 |
61 bool get isAnalyzed => _isAnalyzed; | 53 bool get isAnalyzed => _isAnalyzed; |
62 } | 54 } |
63 | 55 |
64 // TODO(johnniwinther): Rename this to something like `BackendResolutionApi` | |
65 // and clean up the interface. | |
66 /// Backend callbacks function specific to the resolution phase. | 56 /// Backend callbacks function specific to the resolution phase. |
67 class ResolutionCallbacks { | 57 class ResolutionCallbacks { |
68 /// | |
69 WorldImpact transformImpact(ResolutionWorldImpact worldImpact) => worldImpact; | |
70 | |
71 /// Register that an assert has been seen. | 58 /// Register that an assert has been seen. |
72 void onAssert(bool hasMessage, Registry registry) {} | 59 void onAssert(bool hasMessage, Registry registry) {} |
73 | 60 |
74 /// Register that an 'await for' has been seen. | 61 /// Register that an 'await for' has been seen. |
75 void onAsyncForIn(AsyncForIn node, Registry registry) {} | 62 void onAsyncForIn(AsyncForIn node, Registry registry) {} |
76 | 63 |
77 /// Called during resolution to notify to the backend that the | 64 /// Called during resolution to notify to the backend that the |
78 /// program uses string interpolation. | 65 /// program uses string interpolation. |
79 void onStringInterpolation(Registry registry) {} | 66 void onStringInterpolation(Registry registry) {} |
80 | 67 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 /// Register that the application creates a constant map. | 126 /// Register that the application creates a constant map. |
140 void onMapLiteral(Registry registry, DartType type, bool isConstant) {} | 127 void onMapLiteral(Registry registry, DartType type, bool isConstant) {} |
141 | 128 |
142 /// Called when resolving the `Symbol` constructor. | 129 /// Called when resolving the `Symbol` constructor. |
143 void onSymbolConstructor(Registry registry) {} | 130 void onSymbolConstructor(Registry registry) {} |
144 | 131 |
145 /// Called when resolving a prefix or postfix expression. | 132 /// Called when resolving a prefix or postfix expression. |
146 void onIncDecOperation(Registry registry) {} | 133 void onIncDecOperation(Registry registry) {} |
147 } | 134 } |
148 | 135 |
149 class ResolutionWorldImpact extends WorldImpact { | |
150 const ResolutionWorldImpact(); | |
151 | |
152 // TODO(johnniwinther): Remove this. | |
153 void registerDependency(Element element) {} | |
154 | |
155 Iterable<Feature> get features => const <Feature>[]; | |
156 Iterable<DartType> get requiredTypes => const <DartType>[]; | |
157 Iterable<MapLiteralUse> get mapLiterals => const <MapLiteralUse>[]; | |
158 Iterable<ListLiteralUse> get listLiterals => const <ListLiteralUse>[]; | |
159 Iterable<DartType> get typeLiterals => const <DartType>[]; | |
160 Iterable<String> get constSymbolNames => const <String>[]; | |
161 } | |
162 | |
163 /// A language feature seen during resolution. | |
164 // TODO(johnniwinther): Should mirror usage be part of this? | |
165 enum Feature { | |
166 /// Invocation of a generative construction on an abstract class. | |
167 ABSTRACT_CLASS_INSTANTIATION, | |
168 /// An assert statement with no message. | |
169 ASSERT, | |
170 /// An assert statement with a message. | |
171 ASSERT_WITH_MESSAGE, | |
172 /// A method with an `async` body modifier. | |
173 ASYNC, | |
174 /// An asynchronous for in statement like `await for (var e in i) {}`. | |
175 ASYNC_FOR_IN, | |
176 /// A method with an `async*` body modifier. | |
177 ASYNC_STAR, | |
178 /// A catch statement. | |
179 CATCH_STATEMENT, | |
180 /// A compile time error. | |
181 COMPILE_TIME_ERROR, | |
182 /// A fall through in a switch case. | |
183 FALL_THROUGH_ERROR, | |
184 /// A ++/-- operation. | |
185 INC_DEC_OPERATION, | |
186 /// A field whose initialization is not a constant. | |
187 LAZY_FIELD, | |
188 /// A call to `new Symbol`. | |
189 NEW_SYMBOL, | |
190 /// A catch clause with a variable for the stack trace. | |
191 STACK_TRACE_IN_CATCH, | |
192 /// String interpolation. | |
193 STRING_INTERPOLATION, | |
194 /// An implicit call to `super.noSuchMethod`, like calling an unresolved | |
195 /// super method. | |
196 SUPER_NO_SUCH_METHOD, | |
197 /// A redirection to the `Symbol` constructor. | |
198 SYMBOL_CONSTRUCTOR, | |
199 /// An synchronous for in statement, like `for (var e in i) {}`. | |
200 SYNC_FOR_IN, | |
201 /// A method with a `sync*` body modifier. | |
202 SYNC_STAR, | |
203 /// A throw expression. | |
204 THROW_EXPRESSION, | |
205 /// An implicit throw of a `NoSuchMethodError`, like calling an unresolved | |
206 /// static method. | |
207 THROW_NO_SUCH_METHOD, | |
208 /// An implicit throw of a runtime error, like | |
209 THROW_RUNTIME_ERROR, | |
210 /// The need for a type variable bound check, like instantiation of a generic | |
211 /// type whose type variable have non-trivial bounds. | |
212 TYPE_VARIABLE_BOUNDS_CHECK, | |
213 } | |
214 | |
215 /// A use of a map literal seen during resolution. | |
216 class MapLiteralUse { | |
217 final InterfaceType type; | |
218 final bool isConstant; | |
219 final bool isEmpty; | |
220 | |
221 MapLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false}); | |
222 | |
223 int get hashCode { | |
224 return | |
225 type.hashCode * 13 + | |
226 isConstant.hashCode * 17 + | |
227 isEmpty.hashCode * 19; | |
228 } | |
229 | |
230 bool operator ==(other) { | |
231 if (identical(this, other)) return true; | |
232 if (other is! MapLiteralUse) return false; | |
233 return | |
234 type == other.type && | |
235 isConstant == other.isConstant && | |
236 isEmpty == other.isEmpty; | |
237 } | |
238 } | |
239 | |
240 /// A use of a list literal seen during resolution. | |
241 class ListLiteralUse { | |
242 final InterfaceType type; | |
243 final bool isConstant; | |
244 final bool isEmpty; | |
245 | |
246 ListLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false}); | |
247 | |
248 int get hashCode { | |
249 return | |
250 type.hashCode * 13 + | |
251 isConstant.hashCode * 17 + | |
252 isEmpty.hashCode * 19; | |
253 } | |
254 | |
255 bool operator ==(other) { | |
256 if (identical(this, other)) return true; | |
257 if (other is! ListLiteralUse) return false; | |
258 return | |
259 type == other.type && | |
260 isConstant == other.isConstant && | |
261 isEmpty == other.isEmpty; | |
262 } | |
263 } | |
264 | |
265 /// Mutable implementation of [WorldImpact] used to transform | |
266 /// [ResolutionWorldImpact] to [WorldImpact]. | |
267 // TODO(johnniwinther): Remove [Registry] when dependency is tracked directly | |
268 // on [WorldImpact]. | |
269 class TransformedWorldImpact implements WorldImpact, Registry { | |
270 final ResolutionWorldImpact worldImpact; | |
271 | |
272 Setlet<Element> _staticUses; | |
273 Setlet<InterfaceType> _instantiatedTypes; | |
274 Setlet<UniverseSelector> _dynamicGetters; | |
275 Setlet<UniverseSelector> _dynamicInvocations; | |
276 Setlet<UniverseSelector> _dynamicSetters; | |
277 | |
278 TransformedWorldImpact(this.worldImpact); | |
279 | |
280 @override | |
281 Iterable<DartType> get asCasts => worldImpact.asCasts; | |
282 | |
283 @override | |
284 Iterable<DartType> get checkedModeChecks => worldImpact.checkedModeChecks; | |
285 | |
286 @override | |
287 Iterable<MethodElement> get closurizedFunctions { | |
288 return worldImpact.closurizedFunctions; | |
289 } | |
290 | |
291 @override | |
292 Iterable<UniverseSelector> get dynamicGetters { | |
293 return _dynamicGetters != null | |
294 ? _dynamicGetters : worldImpact.dynamicGetters; | |
295 } | |
296 | |
297 @override | |
298 Iterable<UniverseSelector> get dynamicInvocations { | |
299 return _dynamicInvocations != null | |
300 ? _dynamicInvocations : worldImpact.dynamicInvocations; | |
301 } | |
302 | |
303 @override | |
304 Iterable<UniverseSelector> get dynamicSetters { | |
305 return _dynamicSetters != null | |
306 ? _dynamicSetters : worldImpact.dynamicSetters; | |
307 } | |
308 | |
309 @override | |
310 Iterable<DartType> get isChecks => worldImpact.isChecks; | |
311 | |
312 @override | |
313 Iterable<Element> get staticUses { | |
314 if (_staticUses == null) { | |
315 return worldImpact.staticUses; | |
316 } | |
317 return _staticUses; | |
318 } | |
319 | |
320 @override | |
321 bool get isForResolution => true; | |
322 | |
323 _unsupported(String message) => throw new UnsupportedError(message); | |
324 | |
325 @override | |
326 Iterable<Element> get otherDependencies => _unsupported('otherDependencies'); | |
327 | |
328 // TODO(johnniwinther): Remove this. | |
329 @override | |
330 void registerAssert(bool hasMessage) => _unsupported('registerAssert'); | |
331 | |
332 @override | |
333 void registerDependency(Element element) { | |
334 worldImpact.registerDependency(element); | |
335 } | |
336 | |
337 @override | |
338 void registerDynamicGetter(UniverseSelector selector) { | |
339 if (_dynamicGetters == null) { | |
340 _dynamicGetters = new Setlet<UniverseSelector>(); | |
341 _dynamicGetters.addAll(worldImpact.dynamicGetters); | |
342 } | |
343 _dynamicGetters.add(selector); | |
344 } | |
345 | |
346 @override | |
347 void registerDynamicInvocation(UniverseSelector selector) { | |
348 if (_dynamicInvocations == null) { | |
349 _dynamicInvocations = new Setlet<UniverseSelector>(); | |
350 _dynamicInvocations.addAll(worldImpact.dynamicInvocations); | |
351 } | |
352 _dynamicInvocations.add(selector); | |
353 } | |
354 | |
355 @override | |
356 void registerDynamicSetter(UniverseSelector selector) { | |
357 if (_dynamicSetters == null) { | |
358 _dynamicSetters = new Setlet<UniverseSelector>(); | |
359 _dynamicSetters.addAll(worldImpact.dynamicSetters); | |
360 } | |
361 _dynamicSetters.add(selector); | |
362 } | |
363 | |
364 @override | |
365 void registerGetOfStaticFunction(FunctionElement element) { | |
366 _unsupported('registerGetOfStaticFunction($element)'); | |
367 } | |
368 | |
369 @override | |
370 void registerInstantiation(InterfaceType type) { | |
371 // TODO(johnniwinther): Remove this when dependency tracking is done on | |
372 // the world impact itself. | |
373 registerDependency(type.element); | |
374 if (_instantiatedTypes == null) { | |
375 _instantiatedTypes = new Setlet<InterfaceType>(); | |
376 } | |
377 _instantiatedTypes.add(type); | |
378 } | |
379 | |
380 @override | |
381 Iterable<InterfaceType> get instantiatedTypes { | |
382 return _instantiatedTypes != null | |
383 ? _instantiatedTypes : const <InterfaceType>[]; | |
384 } | |
385 | |
386 @override | |
387 void registerStaticInvocation(Element element) { | |
388 if (_staticUses == null) { | |
389 _staticUses = new Setlet<Element>(); | |
390 _staticUses.addAll(worldImpact.staticUses); | |
391 } | |
392 _staticUses.add(element); | |
393 } | |
394 | |
395 @override | |
396 Iterable<LocalFunctionElement> get closures => worldImpact.closures; | |
397 } | |
398 | |
399 // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`. | 136 // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`. |
400 abstract class Resolution { | 137 abstract class Resolution { |
401 Parsing get parsing; | 138 Parsing get parsing; |
402 DiagnosticReporter get reporter; | 139 DiagnosticReporter get reporter; |
403 CoreTypes get coreTypes; | 140 CoreTypes get coreTypes; |
404 | 141 |
405 void resolveTypedef(TypedefElement typdef); | 142 void resolveTypedef(TypedefElement typdef); |
406 void resolveClass(ClassElement cls); | 143 void resolveClass(ClassElement cls); |
407 void registerClass(ClassElement cls); | 144 void registerClass(ClassElement cls); |
408 void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation); | 145 void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation); |
409 FunctionSignature resolveSignature(FunctionElement function); | 146 FunctionSignature resolveSignature(FunctionElement function); |
410 DartType resolveTypeAnnotation(Element element, TypeAnnotation node); | 147 DartType resolveTypeAnnotation(Element element, TypeAnnotation node); |
411 | |
412 bool hasBeenResolved(Element element); | |
413 ResolutionWorldImpact analyzeElement(Element element); | |
414 } | 148 } |
415 | 149 |
416 // TODO(johnniwinther): Rename to `Parser` or `ParsingContext`. | 150 // TODO(johnniwinther): Rename to `Parser` or `ParsingContext`. |
417 abstract class Parsing { | 151 abstract class Parsing { |
418 DiagnosticReporter get reporter; | 152 DiagnosticReporter get reporter; |
419 void parsePatchClass(ClassElement cls); | 153 void parsePatchClass(ClassElement cls); |
420 measure(f()); | 154 measure(f()); |
421 } | 155 } |
OLD | NEW |