Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(496)

Side by Side Diff: lib/compiler/implementation/dart_backend/usager.dart

Issue 10836128: A visitor that builds a map from node to "Usage". (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012, 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 class SendVisitor extends ResolvedVisitor<String> {
6 final Usager usager;
7
8 SendVisitor(this.usager, TreeElements elements) : super(elements);
9
10 R visitSuperSend(Send node) => node.visitChildren(usager);
11 R visitOperatorSend(Send node) => node.visitChildren(usager);
12 R visitClosureSend(Send node) => node.visitChildren(usager);
13 R visitDynamicSend(Send node) => node.visitChildren(usager);
14 R visitForeignSend(Send node) => node.visitChildren(usager);
15
16 R visitGetterSend(Send node) {
17 final element = elements[node];
18 if (element !== null && element.isTopLevel()) {
Anton Muhin 2012/08/07 12:32:11 maybe use early return: if (element === null || el
Roman 2012/08/07 15:44:03 Done.
19 if (node.receiver !== null) {
20 // Library reference prefix. Omit it.
Anton Muhin 2012/08/07 12:32:11 please, add an assert, that receiver resolves to p
Roman 2012/08/07 15:44:03 Done.
21 usager.useNull(node.receiver);
22 }
23 usager.useElement(node.selector, element);
24 usager.visit(node.argumentsNode);
Anton Muhin 2012/08/07 12:32:11 I am not quite happy we duplicate visitChildren he
Roman 2012/08/07 15:44:03 Changed to visitChildren, it should not matter muc
25 } else {
26 node.visitChildren(usager);
27 }
28 }
29
30 R visitStaticSend(Send node) {
Anton Muhin 2012/08/07 12:32:11 isn't that too complicated? e.g. shouldn't we ren
Roman 2012/08/07 15:44:03 I will use magic from your CL to make it better.
31 final element = elements[node];
32 if (element.isTopLevel()) {
33 if (node.receiver !== null) {
34 // Library reference prefix. Omit it.
35 usager.useNull(node.receiver);
36 }
37 usager.useMethod(node.selector, element);
38 usager.visit(node.argumentsNode);
39 } else if (
40 (element.isGenerativeConstructor() || element.isFactoryConstructor())
41 // Don't want to rename redirects to :this(args) or super calls.
42 && !Initializers.isConstructorRedirect(node)
43 && !Initializers.isSuperConstructorCall(node)) {
44 final FunctionElement constructor = element.asFunctionElement();
45 final Send nameAsSend = constructor.cachedNode.name.asSend();
46 if (nameAsSend !== null) {
47 // Named constructor or factory call.
48 if (node.selector is TypeAnnotation) {
49 // Simple A.fromFoo();
50 assert(node.selector.typeName is Send);
51 assert(node.selector.typeName.receiver is Identifier);
52 assert(node.selector.typeName.selector is Identifier);
53 usager.useType(node.selector.typeName.receiver,
54 usager.resolveType(node.selector));
55 usager.useConstructorName(
56 node.selector.typeName.selector, constructor);
57 } else {
58 // lib.A.fromFoo() or A<T>.fromFoo()
59 // or lib.A.fromFoo() or lib.A<T>.fromFoo();
60 assert(node.selector is Send);
61 assert(node.selector.selector is Identifier);
62 assert(node.selector.receiver is TypeAnnotation);
63 usager.useType(node.selector.receiver.typeName,
64 usager.resolveType(node.selector.receiver));
65 usager.useConstructorName(node.selector.selector, constructor);
66 usager.visit(node.selector.receiver.typeArguments);
67 }
68 } else {
69 // Ordinary constructor call.
70 assert(node.selector is TypeAnnotation);
71 usager.useType(
72 node.selector.typeName, usager.resolveType(node.selector));
73 usager.visit(node.selector.typeArguments);
74 }
75 } else {
76 // Fallback to default processing.
77 node.visitChildren(usager);
78 }
79 }
80 }
81
82 class Usager implements Visitor {
83 final Compiler compiler;
84 final Map<Node, Usage> usages;
85 Element currentElement;
86 TreeElements treeElements;
87
88 Usager(this.compiler) : usages = new Map<Node, Usage>();
89
90 /**
91 * Checks if [:libraryElement:] is a core lib, that is a library
92 * provided by the implementation like dart:core, dart:coreimpl, etc.
93 */
94 bool isDartCoreLib(Compiler compiler, LibraryElement libraryElement) {
95 final libraries = compiler.libraries;
96 for (final uri in libraries.getKeys()) {
97 if (libraryElement === libraries[uri]) {
98 if (uri.startsWith('dart:')) return true;
99 }
100 }
101 return false;
102 }
103
104 void process(Element element, TreeElements elements) {
105 currentElement = element;
106 treeElements = elements;
107 Node elementNode = element.parseNode(compiler);
108 elementNode.accept(this);
109 }
110
111 Type resolveType(TypeAnnotation typeAnnotation) {
112 if (treeElements === null) return null;
113 var result = treeElements.getType(typeAnnotation);
114 if (result == null) {
Anton Muhin 2012/08/07 12:32:11 nit: === null
Roman 2012/08/07 15:44:03 Done.
115 result = compiler.resolveTypeAnnotation(currentElement, typeAnnotation);
116 }
117 return result;
118 }
119
120 void useType(Node node, Type type) {
121 assert(type !== null);
122 usages[node] = new TypeUsage(type);
123 }
124 void useConstructorName(Identifier node, FunctionElement constructor) {
125 assert(constructor !== null);
126 usages[node] = new ConstructorNameUsage(constructor);
127 }
128 void useMethod(Node node, Element method) {
129 assert(method !== null);
130 assert(method is FunctionElement || method is VariableElement);
131 usages[node] = new MethodUsage(method);
132 }
133 void useNull(Node node) {
134 usages[node] = new NullUsage();
135 }
136 void useElement(Node node, Element element) {
137 assert(element !== null);
138 usages[node] = new ElementUsage(element);
139 }
140
141 void internalError(String reason, [Node node]) {
142 compiler.cancel(reason: reason, node: node);
143 }
144
145 R visit(Node node) => (node == null) ? null : node.accept(this);
Anton Muhin 2012/08/07 12:32:11 nit: === null
Roman 2012/08/07 15:44:03 Done.
146
147 R visitBlock(Block node) {
Anton Muhin 2012/08/07 12:32:11 arrow syntax, your variant returns null.
Anton Muhin 2012/08/07 12:32:11 cannot you reuse AbstractVisitor?
148 node.visitChildren(this);
149 }
150 R visitBreakStatement(BreakStatement node) {
151 node.visitChildren(this);
152 }
153 R visitCascade(Cascade node) {
154 node.visitChildren(this);
155 }
156 R visitCascadeReceiver(CascadeReceiver node) {
157 node.visitChildren(this);
158 }
159 R visitCaseMatch(CaseMatch node) {
160 node.visitChildren(this);
161 }
162 R visitCatchBlock(CatchBlock node) {
163 node.visitChildren(this);
164 }
165 R visitClassNode(ClassNode node) {
166 internalError('Should never meet ClassNode', node);
167 }
168 R visitConditional(Conditional node) {
169 node.visitChildren(this);
170 }
171 R visitContinueStatement(ContinueStatement node) {
172 node.visitChildren(this);
173 }
174 R visitDoWhile(DoWhile node) {
175 node.visitChildren(this);
176 }
177 R visitEmptyStatement(EmptyStatement node) {
178 node.visitChildren(this);
179 }
180 R visitExpressionStatement(ExpressionStatement node) {
181 node.visitChildren(this);
182 }
183 R visitFor(For node) {
184 node.visitChildren(this);
185 }
186 R visitForIn(ForIn node) {
187 node.visitChildren(this);
188 }
189 R visitFunctionDeclaration(FunctionDeclaration node) {
190 node.visitChildren(this);
191 }
192 R visitFunctionExpression(FunctionExpression node) {
193 node.visitChildren(this);
194 }
195 R visitIdentifier(Identifier node) {
196 if (currentElement.isGenerativeConstructor()
197 || currentElement.isFactoryConstructor()) {
198 // Two complicated cases for class/interface renaming:
199 // 1) class which implements constructors of other interfaces, but not
200 // implements interfaces themselves:
201 // 0.dart: class C { I(); }
202 // 1.dart and 2.dart: interface I default C { I(); }
203 // now we have to duplicate our I() constructor in C class with
204 // proper names.
205 // 2) (even worse for us):
206 // 0.dart: class C { C(); }
207 // 1.dart: interface C default p0.C { C(); }
208 // the second case is just a bug now.
209 final ClassElement enclosingClass = currentElement.getEnclosingClass();
210 if (node.token.slowToString() == enclosingClass.name.slowToString()) {
211 // TODO: distinguish the case of constructor vs. nested named closure
212 // (see function_syntax_test).
213 // TODO: fix the bugs above and turn if into the assert.
214 useType(node, enclosingClass.type);
215 }
216 } else if (currentElement.isFunction()
217 && currentElement.cachedNode.name == node) {
218 useMethod(node, currentElement);
219 }
220 }
221 R visitIf(If node) {
222 node.visitChildren(this);
223 }
224 R visitLabel(Label node) {
225 node.visitChildren(this);
226 }
227 R visitLabeledStatement(LabeledStatement node) {
228 node.visitChildren(this);
229 }
230 R visitLiteralBool(LiteralBool node) {
231 node.visitChildren(this);
232 }
233 R visitLiteralDouble(LiteralDouble node) {
234 node.visitChildren(this);
235 }
236 R visitLiteralInt(LiteralInt node) {
237 node.visitChildren(this);
238 }
239 R visitLiteralList(LiteralList node) {
240 node.visitChildren(this);
241 }
242 R visitLiteralMap(LiteralMap node) {
243 node.visitChildren(this);
244 }
245 R visitLiteralMapEntry(LiteralMapEntry node) {
246 node.visitChildren(this);
247 }
248 R visitLiteralNull(LiteralNull node) {
249 node.visitChildren(this);
250 }
251 R visitLiteralString(LiteralString node) {
252 node.visitChildren(this);
253 }
254 R visitModifiers(Modifiers node) {
255 node.visitChildren(this);
256 }
257 R visitNamedArgument(NamedArgument node) {
258 node.visitChildren(this);
259 }
260 R visitNewExpression(NewExpression node) {
261 node.visitChildren(this);
262 }
263 R visitNodeList(NodeList node) {
264 node.visitChildren(this);
265 }
266 R visitOperator(Operator node) {
267 node.visitChildren(this);
268 }
269 R visitParenthesizedExpression(ParenthesizedExpression node) {
270 node.visitChildren(this);
271 }
272 R visitReturn(Return node) {
273 node.visitChildren(this);
274 }
275 R visitScriptTag(ScriptTag node) {
276 node.visitChildren(this);
277 }
278 R visitSend(Send send) => new SendVisitor(this, treeElements).visitSend(send);
279 R visitSendSet(SendSet node) {
280 node.visitChildren(this);
281 }
282 R visitStringInterpolation(StringInterpolation node) {
283 node.visitChildren(this);
284 }
285 R visitStringInterpolationPart(StringInterpolationPart node) {
286 node.visitChildren(this);
287 }
288 R visitStringJuxtaposition(StringJuxtaposition node) {
289 node.visitChildren(this);
290 }
291 R visitSwitchCase(SwitchCase node) {
292 node.visitChildren(this);
293 }
294 R visitSwitchStatement(SwitchStatement node) {
295 node.visitChildren(this);
296 }
297 R visitThrow(Throw node) {
298 node.visitChildren(this);
299 }
300 R visitTryStatement(TryStatement node) {
301 node.visitChildren(this);
302 }
303
304 R visitTypeAnnotation(TypeAnnotation node) {
305 Type type = resolveType(node);
306 useType(node.typeName, type);
307 visit(node.typeArguments);
308 }
309
310 R visitTypedef(Typedef node) {
311 node.visitChildren(this);
312 }
313 R visitTypeVariable(TypeVariable node) {
314 node.visitChildren(this);
315 }
316 R visitVariableDefinitions(VariableDefinitions node) {
317 node.visitChildren(this);
318 }
319 R visitWhile(While node) {
320 node.visitChildren(this);
321 }
322 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698