| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |