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

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

Issue 10826186: First take on support of library private names. (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 | lib/compiler/implementation/tree/unparser.dart » ('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 SendRenamer extends ResolvedVisitor<String> { 5 class SendRenamer extends ResolvedVisitor<String> {
6 final ConflictingRenamer renamer; 6 final ConflictingRenamer renamer;
7 7
8 SendRenamer(this.renamer, elements) : super(elements); 8 SendRenamer(this.renamer, elements) : super(elements);
9 9
10 String visitSuperSend(Send node) => null; 10 String visitSuperSend(Send node) => null;
11 String visitOperatorSend(Send node) => null; 11 String visitOperatorSend(Send node) => null;
12 String visitClosureSend(Send node) => null; 12 String visitClosureSend(Send node) => null;
13 String visitDynamicSend(Send node) => null;
14 String visitForeignSend(Send node) => null; 13 String visitForeignSend(Send node) => null;
15 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
16 String visitGetterSend(Send node) { 35 String visitGetterSend(Send node) {
17 final element = elements[node]; 36 final element = elements[node];
18 if (element === null || !element.isTopLevel()) return null; 37 if (element === null || !element.isTopLevel()) {
38 return tryRenamePrivateId(node);
39 }
19 return renamer.renameElement(element); 40 return renamer.renameElement(element);
20 } 41 }
21 42
22 String visitStaticSend(Send node) { 43 String visitStaticSend(Send node) {
23 final element = elements[node]; 44 final element = elements[node];
24 45
25 if (element.isTopLevel()) return renamer.renameElement(element); 46 if (element.isTopLevel()) return renamer.renameElement(element);
26 47
27 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) { 48 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) {
28 // Don't want to rename redirects to :this(args) or super calls. 49 // Don't want to rename redirects to :this(args) or super calls.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 81
61 /** 82 /**
62 * Renames only top-level elements that would let to ambiguity if not renamed. 83 * Renames only top-level elements that would let to ambiguity if not renamed.
63 * TODO(smok): Make sure that top-level fields are correctly renamed. 84 * TODO(smok): Make sure that top-level fields are correctly renamed.
64 */ 85 */
65 class ConflictingRenamer extends Renamer { 86 class ConflictingRenamer extends Renamer {
66 final Compiler compiler; 87 final Compiler compiler;
67 final Map<LibraryElement, Map<String, String>> renamed; 88 final Map<LibraryElement, Map<String, String>> renamed;
68 final Set<String> usedTopLevelIdentifiers; 89 final Set<String> usedTopLevelIdentifiers;
69 final Map<LibraryElement, String> imports; 90 final Map<LibraryElement, String> imports;
91 int privateNameCounter = 0;
70 TreeElements contextElements; 92 TreeElements contextElements;
71 Element context; 93 Element context;
72 94
73 Map<Element, TreeElements> get resolvedElements() => 95 Map<Element, TreeElements> get resolvedElements() =>
74 compiler.enqueuer.resolution.resolvedElements; 96 compiler.enqueuer.resolution.resolvedElements;
75 97
76 ConflictingRenamer(this.compiler) : 98 ConflictingRenamer(this.compiler) :
77 renamed = new Map<LibraryElement, Map<String, String>>(), 99 renamed = new Map<LibraryElement, Map<String, String>>(),
78 usedTopLevelIdentifiers = new Set<String>(), 100 usedTopLevelIdentifiers = new Set<String>(),
79 imports = new Map<LibraryElement, String>(); 101 imports = new Map<LibraryElement, String>();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 // 1.dart: interface C default p0.C { C(); } 136 // 1.dart: interface C default p0.C { C(); }
115 // the second case is just a bug now. 137 // the second case is just a bug now.
116 final enclosingClass = context.getEnclosingClass(); 138 final enclosingClass = context.getEnclosingClass();
117 if (node.token.slowToString() == enclosingClass.name.slowToString()) { 139 if (node.token.slowToString() == enclosingClass.name.slowToString()) {
118 // TODO: distinguish the case of constructor vs. nested named closure 140 // TODO: distinguish the case of constructor vs. nested named closure
119 // (see function_syntax_test). 141 // (see function_syntax_test).
120 // TODO: fix the bugs above and turn if into the assert. 142 // TODO: fix the bugs above and turn if into the assert.
121 return renameElement(enclosingClass); 143 return renameElement(enclosingClass);
122 } 144 }
123 } 145 }
124 if (context.isFunction() && context.cachedNode.name == node) { 146 if (context.isFunction() && context.isTopLevel() &&
147 context.cachedNode.name == node) {
125 return renameElement(context); 148 return renameElement(context);
126 } 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 }
127 return null; 160 return null;
128 } 161 }
129 162
163 String getName(LibraryElement library, String originalName, renamer) =>
164 renamed.putIfAbsent(library, () => <String>{})
165 .putIfAbsent(originalName, renamer);
166
167 String renamePrivateId(LibraryElement library, String originalName) =>
168 getName(library, originalName,
169 () => '_${privateNameCounter++}${originalName}');
170
130 String renameElement(Element element) { 171 String renameElement(Element element) {
172 assert(element.isTopLevel());
173
131 // This comes from currently buggy TypeAnnotation renamer. 174 // This comes from currently buggy TypeAnnotation renamer.
132 // It should be solved in there and it will be solved with 175 // It should be solved in there and it will be solved with
133 // new fancy renamer. TODO: remove this cruft. 176 // new fancy renamer. TODO: remove this cruft.
134 if (element === compiler.types.voidType.element) return null; 177 if (element === compiler.types.voidType.element) return null;
135 178
136 // TODO(smok): Make sure that the new name does not conflict with existing 179 // TODO(smok): Make sure that the new name does not conflict with existing
137 // local identifiers. 180 // local identifiers.
138 generateUniqueName(name) { 181 generateUniqueName(name) {
139 while (usedTopLevelIdentifiers.contains(name)) { 182 while (usedTopLevelIdentifiers.contains(name)) name = 'p_$name';
140 name = "p_$name";
141 }
142 usedTopLevelIdentifiers.add(name); 183 usedTopLevelIdentifiers.add(name);
143 return name; 184 return name;
144 } 185 }
145 186
146 String originalName = element.name.slowToString(); 187 String originalName = element.name.slowToString();
147 188 LibraryElement library = element.getLibrary();
148 // TODO(antonm): we should rename lib private names as well.
149 if (!element.isTopLevel()) return originalName;
150 final library = element.getLibrary();
151 if (library === compiler.coreLibrary) return originalName; 189 if (library === compiler.coreLibrary) return originalName;
152 if (isDartCoreLib(compiler, library)) { 190 if (isDartCoreLib(compiler, library)) {
153 final prefix = 191 final prefix =
154 imports.putIfAbsent(library, () => generateUniqueName('p')); 192 imports.putIfAbsent(library, () => generateUniqueName('p'));
155 return '$prefix.$originalName'; 193 return '$prefix.$originalName';
156 } 194 }
157 195
158 return renamed.putIfAbsent(library, () => <String>{}) 196 return getName(library, originalName,
159 .putIfAbsent(originalName, () => generateUniqueName(originalName)); 197 () => generateUniqueName(originalName));
160 } 198 }
161 } 199 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/tree/unparser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698