| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 /** |
| 6 * Renames only top-level elements that would let to ambiguity if not renamed. |
| 7 * TODO(smok): Make sure that top-level fields and methods correctly renamed. |
| 8 */ |
| 9 class ConflictingRenamer extends Renamer { |
| 10 final Compiler compiler; |
| 11 final Map<Element, String> renamed; |
| 12 final Set<String> usedTopLevelIdentifiers; |
| 13 TreeElements contextElements; |
| 14 Element context; |
| 15 |
| 16 Map<Element, TreeElements> get resolvedElements() => |
| 17 compiler.enqueuer.resolution.resolvedElements; |
| 18 |
| 19 ConflictingRenamer(this.compiler) : |
| 20 renamed = new Map<Element, String>(), |
| 21 usedTopLevelIdentifiers = new Set<String>(); |
| 22 |
| 23 void setContext(Element element) { |
| 24 this.context = element; |
| 25 contextElements = resolvedElements[element]; |
| 26 } |
| 27 |
| 28 String renameSendMethod(Send send) { |
| 29 // Rename only if this Send is a function call. |
| 30 if (contextElements[send] !== null && contextElements[send].isFunction()) { |
| 31 return renameElement(contextElements[send]); |
| 32 } else { |
| 33 return null; |
| 34 } |
| 35 } |
| 36 |
| 37 String renameTypeName(TypeAnnotation typeAnnotation) { |
| 38 if (contextElements === null |
| 39 || contextElements.getType(typeAnnotation) === null) { |
| 40 // We have no info about this type from resolver. |
| 41 // This happens for class member fields. |
| 42 // TODO(smok): Maybe resolver should have this information, fix if so. |
| 43 if (context.isField() |
| 44 && context.variables.computeType(compiler) !== null) { |
| 45 // A field. |
| 46 return renameType(context.variables.type); |
| 47 } else { |
| 48 return typeAnnotation.typeName.unparse(); |
| 49 } |
| 50 } |
| 51 |
| 52 // TODO(smok): Check if resolver can help us identifying factory |
| 53 // constructors. |
| 54 Type type = contextElements.getType(typeAnnotation); |
| 55 if (typeAnnotation.typeName is Send |
| 56 && typeAnnotation.typeName.receiver.source.slowToString() |
| 57 == type.name.slowToString()) { |
| 58 // Got factory invocation. Need to rename first part. |
| 59 return "${renameType(type)}." |
| 60 "${typeAnnotation.typeName.selector.source.slowToString()}"; |
| 61 } |
| 62 return renameType(type); |
| 63 } |
| 64 |
| 65 String renameType(Type type) => renameElement(type.element); |
| 66 |
| 67 String renameIdentifier(Identifier node) { |
| 68 if (context.isGenerativeConstructor()) { |
| 69 // This is either a factory constructor or simple one. |
| 70 // TODO(smok): Check if resolver can help us identifying factory |
| 71 // constructors. |
| 72 var enclosingClass = context.getEnclosingClass(); |
| 73 if (node.token.slowToString() == context.name.slowToString() |
| 74 || enclosingClass.name.slowToString() == node.token.slowToString()) { |
| 75 return renameElement(enclosingClass); |
| 76 } |
| 77 } |
| 78 if (context.isFunction() && context.cachedNode.name == node) { |
| 79 return renameElement(context); |
| 80 } |
| 81 return null; |
| 82 } |
| 83 |
| 84 String renameElement(Element element) { |
| 85 String originalName = element.name.slowToString(); |
| 86 if (element.getLibrary() == compiler.coreLibrary || !element.isTopLevel()) { |
| 87 return originalName; |
| 88 } |
| 89 if (renamed[element] !== null) { |
| 90 return renamed[element]; |
| 91 } |
| 92 |
| 93 // Not renamed and top element. |
| 94 // TODO(smok): Make sure that the new name does not conflict with existing |
| 95 // local identifiers. |
| 96 String name = originalName; |
| 97 while (usedTopLevelIdentifiers.contains(name)) { |
| 98 name = "_$name"; |
| 99 } |
| 100 usedTopLevelIdentifiers.add(name); |
| 101 renamed[element] = name; |
| 102 return name; |
| 103 } |
| 104 } |
| OLD | NEW |