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

Side by Side Diff: lib/compiler/implementation/dart_backend/placeholder_collector.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 {
6 final PlaceholderCollector collector;
7
8 SendVisitor(this.collector, TreeElements elements) : super(elements);
9
10 visitSuperSend(Send node) {}
11 visitOperatorSend(Send node) {}
12 visitClosureSend(Send node) {}
13 visitForeignSend(Send node) {}
14
15 String visitDynamicSend(Send node) => tryRenamePrivateId(node);
Anton Muhin 2012/08/09 06:34:52 nit: this method doesn't return String any more, p
Roman 2012/08/09 07:34:03 Done. I don't know why, probably returning nothing
16
17 String tryRenamePrivateId(Send node) {
Anton Muhin 2012/08/09 06:34:52 ditto for return type.
Roman 2012/08/09 07:34:03 Done.
18 Node selector = node.selector;
19 assert(selector !== null);
20 if (selector.source.isPrivate()) {
21 collector.makePrivateIdentifier(selector);
22 }
23 }
24
25 visitGetterSend(Send node) {
26 final element = elements[node];
27 // element === null means dynamic property access.
28 // We don't want to rename non top-level element access.
29 if (element === null || !element.isTopLevel()) {
30 tryRenamePrivateId(node);
31 return;
32 }
33 // Unqualified <class> in static invocation, why it's not a type annotation?
34 // Another option would be to process in visitStaticSend, NB:
35 // those elements are not top-level.
36 // OR: unqualified top level.
37 collector.makeElementPlaceholder(node.selector, element);
38 if (node.receiver !== null) {
39 // <lib prefix>.<top level>.
40 collector.makeNullPlaceholder(node.receiver); // Cut library prefix.
41 }
42 }
43
44 visitStaticSend(Send node) {
45 final element = elements[node];
46 if (!element.isTopLevel()) return;
47 // Another ugly case: <lib prefix>.<top level> is represented as
48 // receiver: lib prefix, selector: top level.
49 collector.makeElementPlaceholder(node.selector, element);
50 if (node.receiver !== null) {
51 assert(elements[node.receiver].isPrefix());
52 // Hack: putting null into map overrides receiver of original node.
53 collector.makeNullPlaceholder(node.receiver);
54 }
55 }
56 }
57
58 class PlaceholderCollector extends AbstractVisitor {
59 final Compiler compiler;
60 final Map<Node, Placeholder> placeholders;
61 Element currentElement;
62 TreeElements treeElements;
63
64 PlaceholderCollector(this.compiler) :
65 placeholders = new Map<Node, Placeholder>();
66
67 void collectFunctionDeclarationPlaceholder(
68 FunctionElement element, Node node) {
69 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) {
70 // Two complicated cases for class/interface renaming:
71 // 1) class which implements constructors of other interfaces, but not
72 // implements interfaces themselves:
73 // 0.dart: class C { I(); }
74 // 1.dart and 2.dart: interface I default C { I(); }
75 // now we have to duplicate our I() constructor in C class with
76 // proper names.
77 // 2) (even worse for us):
78 // 0.dart: class C { C(); }
79 // 1.dart: interface C default p0.C { C(); }
80 // the second case is just a bug now.
81 final enclosingClass = element.getEnclosingClass();
82 Node nameNode = node.name;
83 if (nameNode is Send) nameNode = nameNode.receiver;
84 // For cases like class C implements I { I(); }
85 if (nameNode.token.slowToString() == enclosingClass.name.slowToString()) {
86 makeTypePlaceholder(nameNode, enclosingClass.type);
87 }
88 } else if (element.isTopLevel()) {
89 makeElementPlaceholder(node.name, element);
90 }
91 }
92
93 void collect(Element element, TreeElements elements) {
94 // Skip AbstractFieldElement, it has no node.
95 // Instead getters and setters should be processed explicitly.
96 if (element is AbstractFieldElement) return;
97 if (element.isField()) {
98 currentElement = element;
99 // TODO(smok): In the future make sure we don't process same
100 // variable list element twice, better merge this with emitter logic.
101 element = element.variables;
102 }
103 currentElement = element;
104 treeElements = elements;
105 Node elementNode = element.parseNode(compiler);
106 if (element is FunctionElement) {
107 collectFunctionDeclarationPlaceholder(element, elementNode);
108 }
109 elementNode.accept(this);
110 }
111
112 Type resolveType(TypeAnnotation typeAnnotation) {
113 if (treeElements === null) return null;
114 var result = treeElements.getType(typeAnnotation);
115 // TODO: Have better type resolution.
116 if (result === null) {
117 result = compiler.resolveTypeAnnotation(currentElement, typeAnnotation);
118 }
119 return result;
120 }
121
122 void makeTypePlaceholder(Node node, Type type) {
123 makeElementPlaceholder(node, type.element);
124 }
125
126 void makeNullPlaceholder(Node node) {
127 placeholders[node] = new NullPlaceholder();
128 }
129
130 void makeElementPlaceholder(Node node, Element element) {
131 assert(element !== null);
132 placeholders[node] = new ElementPlaceholder(element);
133 }
134
135 void makePrivateIdentifier(Identifier node) {
136 assert(node !== null);
137 placeholders[node] =
138 new PrivatePlaceholder(currentElement.getLibrary(), node);
139 }
140
141 void internalError(String reason, [Node node]) {
142 compiler.cancel(reason: reason, node: node);
143 }
144
145 visit(Node node) => (node === null) ? null : node.accept(this);
146
147 visitNode(Node node) { node.visitChildren(this); } // We must go deeper.
148
149 visitClassNode(ClassNode node) {
150 internalError('Should never meet ClassNode', node);
151 }
152
153 void visitIdentifier(Identifier node) {
154 if (node.source.isPrivate()) {
155 makePrivateIdentifier(node);
156 }
157 }
158
159 visitSend(Send send) {
160 new SendVisitor(this, treeElements).visitSend(send);
161 super.visitSend(send);
162 }
163
164 visitTypeAnnotation(TypeAnnotation node) {
165 final type = compiler.resolveTypeAnnotation(currentElement, node);
166 if (type is !InterfaceType) return null;
167 var target = node.typeName;
168 if (node.typeName is Send) {
169 final element = treeElements[node];
170 if (element !== null) {
171 final send = node.typeName.asSend();
172 final hasPrefix = element.lookupConstructor(
173 send.receiver.source, send.selector.source) === null;
174 if (!hasPrefix) target = send.receiver;
175 }
176 }
177 makeTypePlaceholder(target, type);
178 visit(node.typeArguments);
Anton Muhin 2012/08/09 06:34:52 super.visit?
Roman 2012/08/09 07:34:03 I can't! If I use super.visit, we will get into id
179 }
180 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698