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

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

Powered by Google App Engine
This is Rietveld 408576698