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

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

Issue 10837186: Rename privates directly, not via visitIdentifier. (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
« no previous file with comments | « no previous file | tests/language/language.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class SendVisitor extends ResolvedVisitor { 5 class SendVisitor extends ResolvedVisitor {
6 final PlaceholderCollector collector; 6 final PlaceholderCollector collector;
7 7
8 SendVisitor(this.collector, TreeElements elements) : super(elements); 8 SendVisitor(this.collector, TreeElements elements) : super(elements);
9 9
10 visitSuperSend(Send node) {} 10 visitSuperSend(Send node) {}
11 visitOperatorSend(Send node) {} 11 visitOperatorSend(Send node) {}
12 visitClosureSend(Send node) {} 12 visitClosureSend(Send node) {}
13 visitForeignSend(Send node) {} 13 visitForeignSend(Send node) {}
14 14
15 visitDynamicSend(Send node) { 15 visitDynamicSend(Send node) {
16 tryRenamePrivateSelector(node); 16 tryRenamePrivateSelector(node);
17 } 17 }
18 18
19 visitGetterSend(Send node) { 19 visitGetterSend(Send node) {
20 final element = elements[node]; 20 final element = elements[node];
21 // element === null means dynamic property access. 21 // element === null means dynamic property access.
22 // We don't want to rename non top-level element access. 22 if (element === null || element.isInstanceMember()) {
23 if (element === null || !element.isTopLevel()) {
24 tryRenamePrivateSelector(node); 23 tryRenamePrivateSelector(node);
25 return; 24 return;
26 } 25 }
26 // We don't want to rename non top-level element access.
27 if (!element.isTopLevel()) return;
27 // Unqualified <class> in static invocation, why it's not a type annotation? 28 // Unqualified <class> in static invocation, why it's not a type annotation?
28 // Another option would be to process in visitStaticSend, NB: 29 // Another option would be to process in visitStaticSend, NB:
29 // those elements are not top-level. 30 // those elements are not top-level.
30 // OR: unqualified top level. 31 // OR: unqualified top level.
31 collector.makeElementPlaceholder(node.selector, element); 32 collector.makeElementPlaceholder(node.selector, element);
32 if (node.receiver !== null) { 33 if (node.receiver !== null) {
33 // <lib prefix>.<top level>. 34 // <lib prefix>.<top level>.
34 collector.makeNullPlaceholder(node.receiver); // Cut library prefix. 35 collector.makeNullPlaceholder(node.receiver); // Cut library prefix.
35 } 36 }
36 } 37 }
37 38
38 visitStaticSend(Send node) { 39 visitStaticSend(Send node) {
39 final element = elements[node]; 40 final element = elements[node];
40 if (!element.isTopLevel()) return; 41 if (!element.isTopLevel()) return;
41 // Another ugly case: <lib prefix>.<top level> is represented as 42 // Another ugly case: <lib prefix>.<top level> is represented as
42 // receiver: lib prefix, selector: top level. 43 // receiver: lib prefix, selector: top level.
43 collector.makeElementPlaceholder(node.selector, element); 44 collector.makeElementPlaceholder(node.selector, element);
44 if (node.receiver !== null) { 45 if (node.receiver !== null) {
45 assert(elements[node.receiver].isPrefix()); 46 assert(elements[node.receiver].isPrefix());
46 // Hack: putting null into map overrides receiver of original node. 47 // Hack: putting null into map overrides receiver of original node.
47 collector.makeNullPlaceholder(node.receiver); 48 collector.makeNullPlaceholder(node.receiver);
48 } 49 }
49 } 50 }
50 51
51 tryRenamePrivateSelector(Send node) { 52 tryRenamePrivateSelector(Send node) {
52 Identifier selector = node.selector.asIdentifier(); 53 collector.tryMakePrivateIdentifier(node.selector.asIdentifier());
53 assert(selector !== null);
54 if (selector.source.isPrivate()) {
55 collector.makePrivateIdentifier(selector);
56 }
57 } 54 }
58 } 55 }
59 56
60 class PlaceholderCollector extends AbstractVisitor { 57 class PlaceholderCollector extends AbstractVisitor {
61 final Compiler compiler; 58 final Compiler compiler;
62 final Map<Node, Placeholder> placeholders; 59 final Map<Node, Placeholder> placeholders;
63 Element currentElement; 60 Element currentElement;
64 TreeElements treeElements; 61 TreeElements treeElements;
65 62
66 PlaceholderCollector(this.compiler) : 63 PlaceholderCollector(this.compiler) :
67 placeholders = new Map<Node, Placeholder>(); 64 placeholders = new Map<Node, Placeholder>();
68 65
69 void collectFunctionDeclarationPlaceholder( 66 void collectFunctionDeclarationPlaceholders(
70 FunctionElement element, Node node) { 67 FunctionElement element, Node node) {
71 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) { 68 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) {
72 // Two complicated cases for class/interface renaming: 69 // Two complicated cases for class/interface renaming:
73 // 1) class which implements constructors of other interfaces, but not 70 // 1) class which implements constructors of other interfaces, but not
74 // implements interfaces themselves: 71 // implements interfaces themselves:
75 // 0.dart: class C { I(); } 72 // 0.dart: class C { I(); }
76 // 1.dart and 2.dart: interface I default C { I(); } 73 // 1.dart and 2.dart: interface I default C { I(); }
77 // now we have to duplicate our I() constructor in C class with 74 // now we have to duplicate our I() constructor in C class with
78 // proper names. 75 // proper names.
79 // 2) (even worse for us): 76 // 2) (even worse for us):
80 // 0.dart: class C { C(); } 77 // 0.dart: class C { C(); }
81 // 1.dart: interface C default p0.C { C(); } 78 // 1.dart: interface C default p0.C { C(); }
82 // the second case is just a bug now. 79 // the second case is just a bug now.
83 final enclosingClass = element.getEnclosingClass(); 80 final enclosingClass = element.getEnclosingClass();
84 Node nameNode = node.name; 81 Node nameNode = node.name;
85 if (nameNode is Send) nameNode = nameNode.receiver; 82 if (nameNode is Send) nameNode = nameNode.receiver;
86 // For cases like class C implements I { I(); } 83 // For cases like class C implements I { I(); }
87 if (nameNode.token.slowToString() == enclosingClass.name.slowToString()) { 84 if (nameNode.token.slowToString() == enclosingClass.name.slowToString()) {
88 makeTypePlaceholder(nameNode, enclosingClass.type); 85 makeTypePlaceholder(nameNode, enclosingClass.type);
89 } 86 }
87 // Process Ctor(this._field) correctly.
88 for (Node parameter in node.parameters) {
89 VariableDefinitions definitions = parameter.asVariableDefinitions();
90 if (definitions !== null) {
91 for (Node definition in definitions.definitions) {
92 Send send = definition.asSend();
93 if (send !== null) {
94 assert(send.receiver.source.slowToString() == 'this');
Roman 2012/08/09 15:28:42 "send.receiver.isThis()" test should work too?
Anton Muhin 2012/08/09 15:42:00 ... and it's definitely better, thanks a lot, Roma
95 tryMakePrivateIdentifier(send.selector.asIdentifier());
96 } else {
97 assert(definition is Identifier);
98 }
99 }
100 } else {
101 assert(parameter is NodeList);
102 // We don't have to rename privates in optionals.
103 }
104 }
90 } else if (element.isTopLevel()) { 105 } else if (element.isTopLevel()) {
106 // Note: this code should only rename private identifiers for class'
107 // fields/getters/setters/methods. Top-level identifiers are renamed
108 // just to escape conflicts and that should be enough as we shouldn't
109 // be able to resolve private identifiers for other libraries.
91 makeElementPlaceholder(node.name, element); 110 makeElementPlaceholder(node.name, element);
111 } else {
112 if (node.name !== null) {
113 Identifier identifier = node.name.asIdentifier();
114 // operator <blah> names shouldn't be renamed.
115 if (identifier !== null) tryMakePrivateIdentifier(identifier);
116 }
117 }
118 }
119
120 void collectFieldDeclarationPlaceholders(Element element, Node node) {
121 if (element.isInstanceMember()) {
122 for (Node definition in node.definitions) {
123 if (definition is Identifier) {
124 tryMakePrivateIdentifier(definition.asIdentifier());
125 } else if (definition is SendSet) {
126 tryMakePrivateIdentifier(
127 definition.asSendSet().selector.asIdentifier());
128 } else {
129 assert(false); // Unreachable.
130 }
131 }
92 } 132 }
93 } 133 }
94 134
95 void collect(Element element, TreeElements elements) { 135 void collect(Element element, TreeElements elements) {
96 // Skip AbstractFieldElement, it has no node. 136 // Skip AbstractFieldElement, it has no node.
97 // Instead getters and setters should be processed explicitly. 137 // Instead getters and setters should be processed explicitly.
98 if (element is AbstractFieldElement) return; 138 if (element is AbstractFieldElement) return;
99 if (element.isField()) { 139 treeElements = elements;
140 Node elementNode;
141 if (element is FunctionElement) {
100 currentElement = element; 142 currentElement = element;
143 elementNode = currentElement.parseNode(compiler);
144 collectFunctionDeclarationPlaceholders(element, elementNode);
145 } else if (element.isField()) {
101 // TODO(smok): In the future make sure we don't process same 146 // TODO(smok): In the future make sure we don't process same
102 // variable list element twice, better merge this with emitter logic. 147 // variable list element twice, better merge this with emitter logic.
103 element = element.variables; 148 currentElement = element.variables;
104 } 149 elementNode = currentElement.parseNode(compiler);
105 currentElement = element; 150 collectFieldDeclarationPlaceholders(element, elementNode);
106 treeElements = elements; 151 } else {
107 Node elementNode = element.parseNode(compiler); 152 assert(false); // Unreachable.
108 if (element is FunctionElement) {
109 collectFunctionDeclarationPlaceholder(element, elementNode);
110 } 153 }
111 elementNode.accept(this); 154 elementNode.accept(this);
112 } 155 }
113 156
114 Type resolveType(TypeAnnotation typeAnnotation) { 157 Type resolveType(TypeAnnotation typeAnnotation) {
115 if (treeElements === null) return null; 158 if (treeElements === null) return null;
116 var result = treeElements.getType(typeAnnotation); 159 var result = treeElements.getType(typeAnnotation);
117 // TODO: Have better type resolution. 160 // TODO: Have better type resolution.
118 if (result === null) { 161 if (result === null) {
119 result = compiler.resolveTypeAnnotation(currentElement, typeAnnotation); 162 result = compiler.resolveTypeAnnotation(currentElement, typeAnnotation);
120 } 163 }
121 return result; 164 return result;
122 } 165 }
123 166
167 tryMakePrivateIdentifier(Identifier identifier) {
168 if (identifier.source.isPrivate()) makePrivateIdentifier(identifier);
169 }
170
124 void makeTypePlaceholder(Node node, Type type) { 171 void makeTypePlaceholder(Node node, Type type) {
125 makeElementPlaceholder(node, type.element); 172 makeElementPlaceholder(node, type.element);
126 } 173 }
127 174
128 void makeNullPlaceholder(Node node) { 175 void makeNullPlaceholder(Node node) {
129 placeholders[node] = new NullPlaceholder(); 176 placeholders[node] = new NullPlaceholder();
130 } 177 }
131 178
132 void makeElementPlaceholder(Node node, Element element) { 179 void makeElementPlaceholder(Node node, Element element) {
133 assert(element !== null); 180 assert(element !== null);
(...skipping 11 matching lines...) Expand all
145 } 192 }
146 193
147 visit(Node node) => (node === null) ? null : node.accept(this); 194 visit(Node node) => (node === null) ? null : node.accept(this);
148 195
149 visitNode(Node node) { node.visitChildren(this); } // We must go deeper. 196 visitNode(Node node) { node.visitChildren(this); } // We must go deeper.
150 197
151 visitClassNode(ClassNode node) { 198 visitClassNode(ClassNode node) {
152 internalError('Should never meet ClassNode', node); 199 internalError('Should never meet ClassNode', node);
153 } 200 }
154 201
155 void visitIdentifier(Identifier node) {
156 if (node.source.isPrivate()) {
157 makePrivateIdentifier(node);
158 }
159 }
160
161 visitSend(Send send) { 202 visitSend(Send send) {
162 new SendVisitor(this, treeElements).visitSend(send); 203 new SendVisitor(this, treeElements).visitSend(send);
163 super.visitSend(send); 204 send.visitChildren(this);
205 }
206
207 visitSendSet(SendSet send) {
208 final element = treeElements[send];
209 if (element !== null && element.isInstanceMember()) {
210 tryMakePrivateIdentifier(send.selector.asIdentifier());
211 }
212 send.visitChildren(this);
164 } 213 }
165 214
166 visitTypeAnnotation(TypeAnnotation node) { 215 visitTypeAnnotation(TypeAnnotation node) {
167 final type = compiler.resolveTypeAnnotation(currentElement, node); 216 final type = compiler.resolveTypeAnnotation(currentElement, node);
168 if (type is !InterfaceType) return null; 217 if (type is !InterfaceType) return null;
169 var target = node.typeName; 218 var target = node.typeName;
170 if (node.typeName is Send) { 219 if (node.typeName is Send) {
171 final element = treeElements[node]; 220 final element = treeElements[node];
172 if (element !== null) { 221 if (element !== null) {
173 final send = node.typeName.asSend(); 222 final send = node.typeName.asSend();
174 final hasPrefix = element.lookupConstructor( 223 final hasPrefix = element.lookupConstructor(
175 send.receiver.source, send.selector.source) === null; 224 send.receiver.source, send.selector.source) === null;
176 if (!hasPrefix) target = send.receiver; 225 if (!hasPrefix) target = send.receiver;
177 } 226 }
178 } 227 }
179 makeTypePlaceholder(target, type); 228 makeTypePlaceholder(target, type);
180 visit(node.typeArguments); 229 node.visitChildren(this);
181 } 230 }
182 } 231 }
OLDNEW
« no previous file with comments | « no previous file | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698