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

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 visitDynamicSend(Send node) => null;
14 String visitForeignSend(Send node) => null;
15
16 String visitGetterSend(Send node) {
17 final element = elements[node];
18 if (element === null || !element.isTopLevel()) return null;
19 return renamer.renameElement(element);
20 }
21
22 String visitStaticSend(Send node) {
23 final element = elements[node];
24
25 if (element.isTopLevel()) return renamer.renameElement(element);
26
27 if (element.isGenerativeConstructor() || element.isFactoryConstructor()) {
28 // Don't want to rename redirects to :this(args) or super calls.
29 if (Initializers.isConstructorRedirect(node)) return null;
30 if (Initializers.isSuperConstructorCall(node)) return null;
31
32 TypeAnnotation typeAnnotation;
33 if (node.selector is TypeAnnotation) {
34 // <simple class name> case.
35 typeAnnotation = node.selector;
36 } else if (node.selector.receiver is TypeAnnotation) {
37 // <complex generic type> case.
38 typeAnnotation = node.selector.receiver;
39 } else {
40 internalError("Don't know how to deduce type", node: node);
41 }
42 final type = new Unparser(renamer).unparse(typeAnnotation);
43
44 final constructor = element.asFunctionElement().cachedNode;
45 final nameAsSend = constructor.name.asSend();
46 if (nameAsSend !== null) {
47 final name = nameAsSend.selector.asIdentifier().source.slowToString();
48 return '$type.$name';
49 }
50 return '$type';
51 }
52
53 return null;
54 }
55
56 void internalError(String reason, [Node node]) {
57 renamer.compiler.cancel(reason: reason, node: node);
58 }
59 }
60
61 /** 5 /**
62 * 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.
63 * TODO(smok): Make sure that top-level fields are correctly renamed. 7 * TODO(smok): Make sure that top-level fields are correctly renamed.
64 */ 8 */
65 class ConflictingRenamer extends Renamer { 9 class ConflictingRenamer extends Renamer {
Anton Muhin 2012/08/07 16:00:30 conflicting renamer now looks like a bad name. Ov
Roman 2012/08/08 06:46:14 I'm not sure. I think it is even better name that
66 final Compiler compiler; 10 final Compiler compiler;
67 final Map<LibraryElement, Map<String, String>> renamed; 11 final Map<LibraryElement, Map<String, String>> renamed;
68 final Set<String> usedTopLevelIdentifiers; 12 final Set<String> usedTopLevelIdentifiers;
69 final Map<LibraryElement, String> imports; 13 final Map<LibraryElement, String> imports;
70 TreeElements contextElements; 14 final Map<Node, Usage> usages;
71 Element context;
72 15
73 Map<Element, TreeElements> get resolvedElements() => 16 ConflictingRenamer(this.compiler, this.usages) :
74 compiler.enqueuer.resolution.resolvedElements;
75
76 ConflictingRenamer(this.compiler) :
77 renamed = new Map<LibraryElement, Map<String, String>>(), 17 renamed = new Map<LibraryElement, Map<String, String>>(),
78 usedTopLevelIdentifiers = new Set<String>(), 18 usedTopLevelIdentifiers = new Set<String>(),
79 imports = new Map<LibraryElement, String>(); 19 imports = new Map<LibraryElement, String>() {
80 20 // Rename main() right now so that nobody takes its place.
81 void setContext(Element element) { 21 renameElement(compiler.mainApp.find(Compiler.MAIN));
82 this.context = element;
83 contextElements = resolvedElements[element];
84 } 22 }
85 23
86 String renameSendMethod(Send send) => 24 // Renamer impl.
87 new SendRenamer(this, contextElements).visitSend(send); 25 String rename(Node node) {
88 26 Usage usage = usages[node];
89 String renameTypeName(TypeAnnotation typeAnnotation) { 27 if (usage !== null) return usage.rename(this);
90 Type type;
91 if (context.isClass()) {
92 // This only happens if we're unparsing class declaration.
93 type = new TypeResolver(compiler)
94 .resolveTypeAnnotation(typeAnnotation, null, context);
95 } else {
96 type = compiler.resolveTypeAnnotation(context, typeAnnotation);
97 }
98 return renameType(type);
99 }
100
101 String renameType(Type type) => renameElement(type.element);
102
103 String renameIdentifier(Identifier node) {
104 if (context.isGenerativeConstructor() || context.isFactoryConstructor()) {
105 // Two complicated cases for class/interface renaming:
106 // 1) class which implements constructors of other interfaces, but not
107 // implements interfaces themselves:
108 // 0.dart: class C { I(); }
109 // 1.dart and 2.dart: interface I default C { I(); }
110 // now we have to duplicate our I() constructor in C class with
111 // proper names.
112 // 2) (even worse for us):
113 // 0.dart: class C { C(); }
114 // 1.dart: interface C default p0.C { C(); }
115 // the second case is just a bug now.
116 final enclosingClass = context.getEnclosingClass();
117 if (node.token.slowToString() == enclosingClass.name.slowToString()) {
118 // TODO: distinguish the case of constructor vs. nested named closure
119 // (see function_syntax_test).
120 // TODO: fix the bugs above and turn if into the assert.
121 return renameElement(enclosingClass);
122 }
123 }
124 if (context.isFunction() && context.cachedNode.name == node) {
125 return renameElement(context);
126 }
127 return null; 28 return null;
128 } 29 }
129 30
130 String renameElement(Element element) { 31 String renameElement(Element element) {
131 // This comes from currently buggy TypeAnnotation renamer. 32 // This comes from currently buggy TypeAnnotation renamer.
132 // It should be solved in there and it will be solved with 33 // It should be solved in there and it will be solved with
133 // new fancy renamer. TODO: remove this cruft. 34 // new fancy renamer. TODO: remove this cruft.
134 if (element === compiler.types.voidType.element) return null; 35 if (element === compiler.types.voidType.element) return null;
135 36
136 // TODO(smok): Make sure that the new name does not conflict with existing 37 // TODO(smok): Make sure that the new name does not conflict with existing
(...skipping 15 matching lines...) Expand all
152 if (isDartCoreLib(compiler, library)) { 53 if (isDartCoreLib(compiler, library)) {
153 final prefix = 54 final prefix =
154 imports.putIfAbsent(library, () => generateUniqueName('p')); 55 imports.putIfAbsent(library, () => generateUniqueName('p'));
155 return '$prefix.$originalName'; 56 return '$prefix.$originalName';
156 } 57 }
157 58
158 return renamed.putIfAbsent(library, () => <String>{}) 59 return renamed.putIfAbsent(library, () => <String>{})
159 .putIfAbsent(originalName, () => generateUniqueName(originalName)); 60 .putIfAbsent(originalName, () => generateUniqueName(originalName));
160 } 61 }
161 } 62 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698