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