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

Side by Side Diff: lib/compiler/implementation/dart_backend/renamer.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
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 SendRenamer extends ResolvedVisitor<String> {
6 final ConflictingRenamer renamer;
7
8 SendRenamer(this.renamer, elements) : super(elements);
9
10 String visitSuperSend(Send node) => null;
11 String visitOperatorSend(Send node) => null;
12 String visitClosureSend(Send node) => null;
13 String visitForeignSend(Send node) => null;
14
15 String tryRenamePrivateId(Send node) {
16 Identifier selector = node.selector.asIdentifier();
17 assert(selector !== null);
18 String originalName = selector.source.slowToString();
19 if (originalName.startsWith('_')) {
20 String newName = renamer.renamePrivateId(
21 renamer.context.getLibrary(), originalName);
22 if (node.receiver !== null) {
23 // TODO: ugly, should be fixed with new renamer infrastructure.
24 String receiver = new Unparser(renamer).unparse(node.receiver);
25 newName = '$receiver.$newName';
26 }
27 return newName;
28 }
29
30 return null;
31 }
32
33 String visitDynamicSend(Send node) => tryRenamePrivateId(node);
34
35 String visitGetterSend(Send node) {
36 final element = elements[node];
37 if (element === null || !element.isTopLevel()) {
38 return tryRenamePrivateId(node);
39 }
40 return renamer.renameElement(element);
41 }
42
43 String visitStaticSend(Send node) {
44 final element = elements[node];
45
46 if (element.isTopLevel()) return renamer.renameElement(element);
47
48 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) {
49 // Don't want to rename redirects to :this(args) or super calls.
50 if (Initializers.isConstructorRedirect(node)) return null;
51 if (Initializers.isSuperConstructorCall(node)) return null;
52
53 TypeAnnotation typeAnnotation;
54 if (node.selector is TypeAnnotation) {
55 // <simple class name> case.
56 typeAnnotation = node.selector;
57 } else if (node.selector.receiver is TypeAnnotation) {
58 // <complex generic type> case.
59 typeAnnotation = node.selector.receiver;
60 } else {
61 internalError("Don't know how to deduce type", node: node);
62 }
63 final type = new Unparser(renamer).unparse(typeAnnotation);
64
65 final constructor = element.asFunctionElement().cachedNode;
66 final nameAsSend = constructor.name.asSend();
67 if (nameAsSend !== null) {
68 final name = nameAsSend.selector.asIdentifier().source.slowToString();
69 return '$type.$name';
70 }
71 return '$type';
72 }
73
74 return null;
75 }
76
77 void internalError(String reason, [Node node]) {
78 renamer.compiler.cancel(reason: reason, node: node);
79 }
80 }
81
82 /** 5 /**
83 * Renames only top-level elements that would let to ambiguity if not renamed. 6 * Renames only top-level elements that would let to ambiguity if not renamed.
84 * TODO(smok): Make sure that top-level fields are correctly renamed. 7 * TODO(smok): Make sure that top-level fields are correctly renamed.
85 */ 8 */
86 class ConflictingRenamer extends Renamer { 9 class ConflictingRenamer {
87 final Compiler compiler; 10 final Compiler compiler;
88 final Map<LibraryElement, Map<String, String>> renamed; 11 final Map<LibraryElement, Map<String, String>> renamed;
89 final Set<String> usedTopLevelIdentifiers; 12 final Set<String> usedTopLevelIdentifiers;
90 final Map<LibraryElement, String> imports; 13 final Map<LibraryElement, String> imports;
14 final Map<Node, Placeholder> placeholders;
91 int privateNameCounter = 0; 15 int privateNameCounter = 0;
92 TreeElements contextElements;
93 Element context;
94 16
95 Map<Element, TreeElements> get resolvedElements() => 17 ConflictingRenamer(this.compiler, this.placeholders) :
96 compiler.enqueuer.resolution.resolvedElements;
97
98 ConflictingRenamer(this.compiler) :
99 renamed = new Map<LibraryElement, Map<String, String>>(), 18 renamed = new Map<LibraryElement, Map<String, String>>(),
100 usedTopLevelIdentifiers = new Set<String>(), 19 usedTopLevelIdentifiers = new Set<String>(),
101 imports = new Map<LibraryElement, String>(); 20 imports = new Map<LibraryElement, String>() {
102 21 // Rename main() right now so that nobody takes its place.
103 void setContext(Element element) { 22 renameElement(compiler.mainApp.find(Compiler.MAIN));
104 this.context = element;
105 contextElements = resolvedElements[element];
106 } 23 }
107 24
108 String renameSendMethod(Send send) => 25 // Renamer implementation.
109 new SendRenamer(this, contextElements).visitSend(send); 26 String rename(Node node) {
110 27 Placeholder placeholder = placeholders[node];
111 String renameTypeName(TypeAnnotation typeAnnotation) { 28 return (placeholder !== null) ? placeholder.rename(this) : null;
112 Type type;
113 if (context.isClass()) {
114 // This only happens if we're unparsing class declaration.
115 type = new TypeResolver(compiler)
116 .resolveTypeAnnotation(typeAnnotation, null, context);
117 } else {
118 type = compiler.resolveTypeAnnotation(context, typeAnnotation);
119 }
120 return renameType(type);
121 }
122
123 String renameType(Type type) => renameElement(type.element);
124
125 String renameIdentifier(Identifier node) {
126 if (context.isGenerativeConstructor() || context.isFactoryConstructor()) {
127 // Two complicated cases for class/interface renaming:
128 // 1) class which implements constructors of other interfaces, but not
129 // implements interfaces themselves:
130 // 0.dart: class C { I(); }
131 // 1.dart and 2.dart: interface I default C { I(); }
132 // now we have to duplicate our I() constructor in C class with
133 // proper names.
134 // 2) (even worse for us):
135 // 0.dart: class C { C(); }
136 // 1.dart: interface C default p0.C { C(); }
137 // the second case is just a bug now.
138 final enclosingClass = context.getEnclosingClass();
139 if (node.token.slowToString() == enclosingClass.name.slowToString()) {
140 // TODO: distinguish the case of constructor vs. nested named closure
141 // (see function_syntax_test).
142 // TODO: fix the bugs above and turn if into the assert.
143 return renameElement(enclosingClass);
144 }
145 }
146 if (context.isFunction() && context.isTopLevel() &&
147 context.cachedNode.name == node) {
148 return renameElement(context);
149 }
150 // TODO: as the rest of renameIdentifier should go closer to
151 // Emitter.outputElement.
152 // Note: this code should only rename private identifiers for class'
153 // fields/getters/setters/methods. Top-level identifiers are renamed
154 // just to escape conflicts and that should be enough as we shouldn't
155 // be able to resolve private identifiers for other libraries.
156 final originalName = node.source.slowToString();
157 if (originalName.startsWith('_')) {
158 return '${renamePrivateId(context.getLibrary(), originalName)}';
159 }
160 return null;
161 } 29 }
162 30
163 String getName(LibraryElement library, String originalName, renamer) => 31 String getName(LibraryElement library, String originalName, renamer) =>
164 renamed.putIfAbsent(library, () => <String>{}) 32 renamed.putIfAbsent(library, () => <String>{})
165 .putIfAbsent(originalName, renamer); 33 .putIfAbsent(originalName, renamer);
166 34
167 String renamePrivateId(LibraryElement library, String originalName) => 35 String renamePrivateIdentifier(LibraryElement library, String id) =>
168 getName(library, originalName, 36 getName(library, id, () => '_${privateNameCounter++}${id}');
169 () => '_${privateNameCounter++}${originalName}');
170 37
171 String renameElement(Element element) { 38 String renameElement(Element element) {
172 // TODO: investigate what went wrong here. 39 assert(element.isTopLevel());
173 if (!element.isTopLevel()) return null;
174
175 // This comes from currently buggy TypeAnnotation renamer.
176 // It should be solved in there and it will be solved with
177 // new fancy renamer. TODO: remove this cruft.
178 if (element === compiler.types.voidType.element) return null;
179
180 // TODO(smok): Make sure that the new name does not conflict with existing 40 // TODO(smok): Make sure that the new name does not conflict with existing
181 // local identifiers. 41 // local identifiers.
182 generateUniqueName(name) { 42 generateUniqueName(name) {
183 while (usedTopLevelIdentifiers.contains(name)) name = 'p_$name'; 43 while (usedTopLevelIdentifiers.contains(name)) name = 'p_$name';
184 usedTopLevelIdentifiers.add(name); 44 usedTopLevelIdentifiers.add(name);
185 return name; 45 return name;
186 } 46 }
187 47
188 String originalName = element.name.slowToString(); 48 String originalName = element.name.slowToString();
189 LibraryElement library = element.getLibrary(); 49 LibraryElement library = element.getLibrary();
190 if (library === compiler.coreLibrary) return originalName; 50 if (library === compiler.coreLibrary) return originalName;
191 if (isDartCoreLib(compiler, library)) { 51 if (isDartCoreLib(compiler, library)) {
192 final prefix = 52 final prefix =
193 imports.putIfAbsent(library, () => generateUniqueName('p')); 53 imports.putIfAbsent(library, () => generateUniqueName('p'));
194 return '$prefix.$originalName'; 54 return '$prefix.$originalName';
195 } 55 }
196 56
197 return getName(library, originalName, 57 return getName(library, originalName,
198 () => generateUniqueName(originalName)); 58 () => generateUniqueName(originalName));
199 } 59 }
200 } 60 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/dart_backend/placeholder_collector.dart ('k') | lib/compiler/implementation/tree/renamer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698