OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 part of resolution; | |
6 | |
7 /// [ResolutionRegistry] collects all resolution information. It stores node | |
8 /// related information in a [TreeElements] mapping and registers calls with | |
9 /// [Backend], [World] and [Enqueuer]. | |
10 // TODO(johnniwinther): Split this into an interface and implementation class. | |
11 class ResolutionRegistry extends Registry { | |
12 final Compiler compiler; | |
13 final TreeElementMapping mapping; | |
14 | |
15 ResolutionRegistry(Compiler compiler, Element element) | |
16 : this.internal(compiler, _ensureTreeElements(element)); | |
17 | |
18 ResolutionRegistry.internal(this.compiler, this.mapping); | |
19 | |
20 bool get isForResolution => true; | |
21 | |
22 ResolutionEnqueuer get world => compiler.enqueuer.resolution; | |
23 | |
24 World get universe => compiler.world; | |
25 | |
26 Backend get backend => compiler.backend; | |
27 | |
28 ////////////////////////////////////////////////////////////////////////////// | |
29 // Node-to-Element mapping functionality. | |
30 ////////////////////////////////////////////////////////////////////////////// | |
31 | |
32 /// Register [node] as the declaration of [element]. | |
33 void defineFunction(FunctionExpression node, FunctionElement element) { | |
34 // TODO(sigurdm): Remove when not needed by the dart2dart backend. | |
35 if (node.name != null) { | |
36 mapping[node.name] = element; | |
37 } | |
38 mapping[node] = element; | |
39 } | |
40 | |
41 /// Register [node] as a reference to [element]. | |
42 Element useElement(Node node, Element element) { | |
43 if (element == null) return null; | |
44 return mapping[node] = element; | |
45 } | |
46 | |
47 /// Register [node] as the declaration of [element]. | |
48 void defineElement(Node node, Element element) { | |
49 mapping[node] = element; | |
50 } | |
51 | |
52 /// Returns the [Element] defined by [node]. | |
53 Element getDefinition(Node node) { | |
54 return mapping[node]; | |
55 } | |
56 | |
57 /// Sets the loop variable of the for-in [node] to be [element]. | |
58 void setForInVariable(ForIn node, Element element) { | |
59 mapping[node] = element; | |
60 } | |
61 | |
62 /// Sets the target constructor [node] to be [element]. | |
63 void setRedirectingTargetConstructor(RedirectingFactoryBody node, | |
64 ConstructorElement element) { | |
65 useElement(node, element); | |
66 } | |
67 | |
68 ////////////////////////////////////////////////////////////////////////////// | |
69 // Node-to-Selector mapping functionality. | |
70 ////////////////////////////////////////////////////////////////////////////// | |
71 | |
72 void setSelector(Node node, Selector selector) { | |
73 mapping.setSelector(node, selector); | |
74 } | |
75 | |
76 Selector getSelector(Node node) => mapping.getSelector(node); | |
77 | |
78 void setGetterSelectorInComplexSendSet(SendSet node, Selector selector) { | |
79 mapping.setGetterSelectorInComplexSendSet(node, selector); | |
80 } | |
81 | |
82 void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector) { | |
83 mapping.setOperatorSelectorInComplexSendSet(node, selector); | |
84 } | |
85 | |
86 void setIteratorSelector(ForIn node, Selector selector) { | |
87 mapping.setIteratorSelector(node, selector); | |
88 } | |
89 | |
90 void setMoveNextSelector(ForIn node, Selector selector) { | |
91 mapping.setMoveNextSelector(node, selector); | |
92 } | |
93 | |
94 void setCurrentSelector(ForIn node, Selector selector) { | |
95 mapping.setCurrentSelector(node, selector); | |
96 } | |
97 | |
98 ////////////////////////////////////////////////////////////////////////////// | |
99 // Node-to-Type mapping functionality. | |
100 ////////////////////////////////////////////////////////////////////////////// | |
101 | |
102 DartType useType(Node annotation, DartType type) { | |
103 if (type != null) { | |
104 mapping.setType(annotation, type); | |
105 } | |
106 return type; | |
107 } | |
108 | |
109 void setType(Node node, DartType type) => mapping.setType(node, type); | |
110 | |
111 DartType getType(Node node) => mapping.getType(node); | |
112 | |
113 ////////////////////////////////////////////////////////////////////////////// | |
114 // Node-to-Constant mapping functionality. | |
115 ////////////////////////////////////////////////////////////////////////////// | |
116 | |
117 ConstantExpression getConstant(Node node) => mapping.getConstant(node); | |
118 | |
119 ////////////////////////////////////////////////////////////////////////////// | |
120 // Target/Label functionality. | |
121 ////////////////////////////////////////////////////////////////////////////// | |
122 | |
123 /// Register [node] to be the declaration of [label]. | |
124 void defineLabel(Label node, LabelDefinition label) { | |
125 mapping.defineLabel(node, label); | |
126 } | |
127 | |
128 /// Undefine the label of [node]. | |
129 /// This is used to cleanup and detect unused labels. | |
130 void undefineLabel(Label node) { | |
131 mapping.undefineLabel(node); | |
132 } | |
133 | |
134 /// Register the target of [node] as reference to [label]. | |
135 void useLabel(GotoStatement node, LabelDefinition label) { | |
136 mapping.registerTargetLabel(node, label); | |
137 } | |
138 | |
139 /// Register [node] to be the declaration of [target]. | |
140 void defineTarget(Node node, JumpTarget target) { | |
141 assert(invariant(node, node is Statement || node is SwitchCase, | |
142 message: "Only statements and switch cases can define targets.")); | |
143 mapping.defineTarget(node, target); | |
144 } | |
145 | |
146 /// Returns the [JumpTarget] defined by [node]. | |
147 JumpTarget getTargetDefinition(Node node) { | |
148 assert(invariant(node, node is Statement || node is SwitchCase, | |
149 message: "Only statements and switch cases can define targets.")); | |
150 return mapping.getTargetDefinition(node); | |
151 } | |
152 | |
153 /// Undefine the target of [node]. This is used to cleanup unused targets. | |
154 void undefineTarget(Node node) { | |
155 assert(invariant(node, node is Statement || node is SwitchCase, | |
156 message: "Only statements and switch cases can define targets.")); | |
157 mapping.undefineTarget(node); | |
158 } | |
159 | |
160 /// Register the target of [node] to be [target]. | |
161 void registerTargetOf(GotoStatement node, JumpTarget target) { | |
162 mapping.registerTargetOf(node, target); | |
163 } | |
164 | |
165 ////////////////////////////////////////////////////////////////////////////// | |
166 // Potential access registration. | |
167 ////////////////////////////////////////////////////////////////////////////// | |
168 | |
169 void setAccessedByClosureIn(Node contextNode, VariableElement element, | |
170 Node accessNode) { | |
171 mapping.setAccessedByClosureIn(contextNode, element, accessNode); | |
172 } | |
173 | |
174 void registerPotentialMutation(VariableElement element, Node mutationNode) { | |
175 mapping.registerPotentialMutation(element, mutationNode); | |
176 } | |
177 | |
178 void registerPotentialMutationInClosure(VariableElement element, | |
179 Node mutationNode) { | |
180 mapping.registerPotentialMutationInClosure(element, mutationNode); | |
181 } | |
182 | |
183 void registerPotentialMutationIn(Node contextNode, VariableElement element, | |
184 Node mutationNode) { | |
185 mapping.registerPotentialMutationIn(contextNode, element, mutationNode); | |
186 } | |
187 | |
188 ////////////////////////////////////////////////////////////////////////////// | |
189 // Various Backend/Enqueuer/World registration. | |
190 ////////////////////////////////////////////////////////////////////////////// | |
191 | |
192 void registerStaticUse(Element element) { | |
193 world.registerStaticUse(element); | |
194 } | |
195 | |
196 void registerImplicitSuperCall(FunctionElement superConstructor) { | |
197 universe.registerImplicitSuperCall(this, superConstructor); | |
198 } | |
199 | |
200 void registerInstantiatedClass(ClassElement element) { | |
201 world.registerInstantiatedClass(element, this); | |
202 } | |
203 | |
204 void registerLazyField() { | |
205 backend.resolutionCallbacks.onLazyField(this); | |
206 } | |
207 | |
208 void registerMetadataConstant(MetadataAnnotation metadata, | |
209 Element annotatedElement) { | |
210 backend.registerMetadataConstant(metadata, annotatedElement, this); | |
211 } | |
212 | |
213 void registerThrowRuntimeError() { | |
214 backend.resolutionCallbacks.onThrowRuntimeError(this); | |
215 } | |
216 | |
217 void registerTypeVariableBoundCheck() { | |
218 backend.resolutionCallbacks.onTypeVariableBoundCheck(this); | |
219 } | |
220 | |
221 void registerThrowNoSuchMethod() { | |
222 backend.resolutionCallbacks.onThrowNoSuchMethod(this); | |
223 } | |
224 | |
225 void registerIsCheck(DartType type) { | |
226 world.registerIsCheck(type, this); | |
227 backend.resolutionCallbacks.onIsCheck(type, this); | |
228 } | |
229 | |
230 void registerAsCheck(DartType type) { | |
231 registerIsCheck(type); | |
232 backend.resolutionCallbacks.onAsCheck(type, this); | |
233 } | |
234 | |
235 void registerClosure(LocalFunctionElement element) { | |
236 world.registerClosure(element, this); | |
237 } | |
238 | |
239 void registerSuperUse(Node node) { | |
240 mapping.addSuperUse(node); | |
241 } | |
242 | |
243 void registerDynamicInvocation(Selector selector) { | |
244 world.registerDynamicInvocation(selector); | |
245 } | |
246 | |
247 void registerSuperNoSuchMethod() { | |
248 backend.resolutionCallbacks.onSuperNoSuchMethod(this); | |
249 } | |
250 | |
251 void registerClassUsingVariableExpression(ClassElement element) { | |
252 backend.registerClassUsingVariableExpression(element); | |
253 } | |
254 | |
255 void registerTypeVariableExpression() { | |
256 backend.resolutionCallbacks.onTypeVariableExpression(this); | |
257 } | |
258 | |
259 void registerTypeLiteral(Send node, DartType type) { | |
260 mapping.setType(node, type); | |
261 backend.resolutionCallbacks.onTypeLiteral(type, this); | |
262 world.registerInstantiatedClass(compiler.typeClass, this); | |
263 } | |
264 | |
265 // TODO(johnniwinther): Remove the [ResolverVisitor] dependency. Its only | |
266 // needed to lookup types in the current scope. | |
267 void registerJsCall(Node node, ResolverVisitor visitor) { | |
268 world.registerJsCall(node, visitor); | |
269 } | |
270 | |
271 // TODO(johnniwinther): Remove the [ResolverVisitor] dependency. Its only | |
272 // needed to lookup types in the current scope. | |
273 void registerJsEmbeddedGlobalCall(Node node, ResolverVisitor visitor) { | |
274 world.registerJsEmbeddedGlobalCall(node, visitor); | |
275 } | |
276 | |
277 void registerGetOfStaticFunction(FunctionElement element) { | |
278 world.registerGetOfStaticFunction(element); | |
279 } | |
280 | |
281 void registerDynamicGetter(Selector selector) { | |
282 world.registerDynamicGetter(selector); | |
283 } | |
284 | |
285 void registerDynamicSetter(Selector selector) { | |
286 world.registerDynamicSetter(selector); | |
287 } | |
288 | |
289 void registerConstSymbol(String name) { | |
290 backend.registerConstSymbol(name, this); | |
291 } | |
292 | |
293 void registerSymbolConstructor() { | |
294 backend.resolutionCallbacks.onSymbolConstructor(this); | |
295 } | |
296 | |
297 void registerInstantiatedType(InterfaceType type) { | |
298 world.registerInstantiatedType(type, this); | |
299 } | |
300 | |
301 void registerFactoryWithTypeArguments() { | |
302 world.registerFactoryWithTypeArguments(this); | |
303 } | |
304 | |
305 void registerAbstractClassInstantiation() { | |
306 backend.resolutionCallbacks.onAbstractClassInstantiation(this); | |
307 } | |
308 | |
309 void registerNewSymbol() { | |
310 backend.registerNewSymbol(this); | |
311 } | |
312 | |
313 void registerRequiredType(DartType type, Element enclosingElement) { | |
314 backend.registerRequiredType(type, enclosingElement); | |
315 } | |
316 | |
317 void registerStringInterpolation() { | |
318 backend.resolutionCallbacks.onStringInterpolation(this); | |
319 } | |
320 | |
321 void registerConstantMap() { | |
322 backend.resolutionCallbacks.onConstantMap(this); | |
323 } | |
324 | |
325 void registerFallThroughError() { | |
326 backend.resolutionCallbacks.onFallThroughError(this); | |
327 } | |
328 | |
329 void registerCatchStatement() { | |
330 backend.resolutionCallbacks.onCatchStatement(this); | |
331 } | |
332 | |
333 void registerStackTraceInCatch() { | |
334 backend.resolutionCallbacks.onStackTraceInCatch(this); | |
335 } | |
336 | |
337 ClassElement defaultSuperclass(ClassElement element) { | |
338 return backend.defaultSuperclass(element); | |
339 } | |
340 | |
341 void registerMixinUse(MixinApplicationElement mixinApplication, | |
342 ClassElement mixin) { | |
343 universe.registerMixinUse(mixinApplication, mixin); | |
344 } | |
345 | |
346 void registerThrowExpression() { | |
347 backend.resolutionCallbacks.onThrowExpression(this); | |
348 } | |
349 | |
350 void registerDependency(Element element) { | |
351 mapping.registerDependency(element); | |
352 } | |
353 | |
354 Setlet<Element> get otherDependencies => mapping.otherDependencies; | |
355 | |
356 void registerStaticInvocation(Element element) { | |
357 if (element == null) return; | |
358 world.addToWorkList(element); | |
359 registerDependency(element); | |
360 } | |
361 | |
362 void registerInstantiation(InterfaceType type) { | |
363 world.registerInstantiatedType(type, this); | |
364 } | |
365 | |
366 void registerAssert(Send node) { | |
367 mapping.setAssert(node); | |
368 backend.resolutionCallbacks.onAssert(node, this); | |
369 } | |
370 | |
371 bool isAssert(Send node) { | |
372 return mapping.isAssert(node); | |
373 } | |
374 } | |
OLD | NEW |