Chromium Code Reviews| 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 /** | 5 /** |
| 6 * 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. |
| 7 * TODO(smok): Make sure that top-level fields and methods correctly renamed. | 7 * TODO(smok): Make sure that top-level fields are correctly renamed. |
| 8 */ | 8 */ |
| 9 class ConflictingRenamer extends Renamer { | 9 class ConflictingRenamer extends Renamer { |
| 10 final Compiler compiler; | 10 final Compiler compiler; |
| 11 final Map<Element, String> renamed; | 11 final Map<Element, String> renamed; |
| 12 final Set<String> usedTopLevelIdentifiers; | 12 final Set<String> usedTopLevelIdentifiers; |
| 13 TreeElements contextElements; | 13 TreeElements contextElements; |
| 14 Element context; | 14 Element context; |
| 15 | 15 |
| 16 Map<Element, TreeElements> get resolvedElements() => | 16 Map<Element, TreeElements> get resolvedElements() => |
| 17 compiler.enqueuer.resolution.resolvedElements; | 17 compiler.enqueuer.resolution.resolvedElements; |
| 18 | 18 |
| 19 ConflictingRenamer(this.compiler) : | 19 ConflictingRenamer(this.compiler) : |
| 20 renamed = new Map<Element, String>(), | 20 renamed = new Map<Element, String>(), |
| 21 usedTopLevelIdentifiers = new Set<String>(); | 21 usedTopLevelIdentifiers = new Set<String>(); |
| 22 | 22 |
| 23 void setContext(Element element) { | 23 void setContext(Element element) { |
| 24 this.context = element; | 24 this.context = element; |
| 25 contextElements = resolvedElements[element]; | 25 contextElements = resolvedElements[element]; |
| 26 } | 26 } |
| 27 | 27 |
| 28 String getFactoryName(FunctionExpression node) { | |
|
Anton Muhin
2012/07/27 11:15:34
nit: arrow syntax? here and below
Roman
2012/07/27 11:32:45
Done.
| |
| 29 return node.name.asSend().selector.asIdentifier().source.slowToString(); | |
| 30 } | |
| 31 | |
| 32 bool isNamedConstructor(Element element) { | |
| 33 return element.isGenerativeConstructor() | |
| 34 && element.asFunctionElement().cachedNode.name is Send; | |
| 35 } | |
| 36 | |
| 28 String renameSendMethod(Send send) { | 37 String renameSendMethod(Send send) { |
| 29 // Rename only if this Send is a function call. | 38 if (contextElements[send] === null) { |
|
Anton Muhin
2012/07/27 11:15:34
nit: single line
Roman
2012/07/27 11:32:45
Done.
| |
| 30 if (contextElements[send] !== null && contextElements[send].isFunction()) { | 39 return null; |
| 31 return renameElement(contextElements[send]); | |
| 32 } else { | 40 } else { |
| 33 return null; | 41 Element element = contextElements[send]; |
| 42 if (element.isTopLevel()) { | |
| 43 return renameElement(element); | |
| 44 } else if (isNamedConstructor(element) | |
| 45 && !Initializers.isConstructorRedirect(send) | |
|
Anton Muhin
2012/07/27 11:15:34
why those &&! conditions?
Roman
2012/07/27 11:32:45
We don't want to rename redirects to this(arg) in
| |
| 46 && !Initializers.isSuperConstructorCall(send)) { | |
| 47 FunctionExpression constructor = element.asFunctionElement().cachedNode; | |
| 48 return '${renameType(element.getEnclosingClass().type)}' | |
| 49 '.${getFactoryName(constructor)}'; | |
| 50 } else { | |
| 51 return null; | |
| 52 } | |
| 34 } | 53 } |
| 35 } | 54 } |
| 36 | 55 |
| 37 String renameTypeName(TypeAnnotation typeAnnotation) { | 56 String renameTypeName(TypeAnnotation typeAnnotation) { |
| 38 if (contextElements === null | 57 Type type; |
| 39 || contextElements.getType(typeAnnotation) === null) { | 58 if (context.isClass()) { |
| 40 // We have no info about this type from resolver. | 59 // This only happens if we're unparsing class declaration. |
| 41 // This happens for class member fields. | 60 type = new TypeResolver(compiler) |
| 42 // TODO(smok): Maybe resolver should have this information, fix if so. | 61 .resolveTypeAnnotation(typeAnnotation, null, context); |
| 43 if (context.isField() | 62 } else { |
| 44 && context.variables.computeType(compiler) !== null) { | 63 type = compiler.resolveTypeAnnotation(context, typeAnnotation); |
| 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 } | 64 } |
| 62 return renameType(type); | 65 return renameType(type); |
| 63 } | 66 } |
| 64 | 67 |
| 65 String renameType(Type type) => renameElement(type.element); | 68 String renameType(Type type) => renameElement(type.element); |
| 66 | 69 |
| 67 String renameIdentifier(Identifier node) { | 70 String renameIdentifier(Identifier node) { |
| 68 if (context.isGenerativeConstructor()) { | 71 if (context.isGenerativeConstructor()) { |
| 69 // This is either a factory constructor or simple one. | 72 // This is either a named constructor or simple one. |
| 70 // TODO(smok): Check if resolver can help us identifying factory | 73 // TODO(smok): Check if resolver can help us identifying named |
| 71 // constructors. | 74 // constructors. |
| 72 var enclosingClass = context.getEnclosingClass(); | 75 var enclosingClass = context.getEnclosingClass(); |
| 73 if (node.token.slowToString() == context.name.slowToString() | 76 if (node.token.slowToString() == context.name.slowToString() |
| 74 || enclosingClass.name.slowToString() == node.token.slowToString()) { | 77 || enclosingClass.name.slowToString() == node.token.slowToString()) { |
| 75 return renameElement(enclosingClass); | 78 return renameElement(enclosingClass); |
| 76 } | 79 } |
| 77 } | 80 } |
| 78 if (context.isFunction() && context.cachedNode.name == node) { | 81 if (context.isFunction() && context.cachedNode.name == node) { |
| 79 return renameElement(context); | 82 return renameElement(context); |
| 80 } | 83 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 95 // local identifiers. | 98 // local identifiers. |
| 96 String name = originalName; | 99 String name = originalName; |
| 97 while (usedTopLevelIdentifiers.contains(name)) { | 100 while (usedTopLevelIdentifiers.contains(name)) { |
| 98 name = "_$name"; | 101 name = "_$name"; |
| 99 } | 102 } |
| 100 usedTopLevelIdentifiers.add(name); | 103 usedTopLevelIdentifiers.add(name); |
| 101 renamed[element] = name; | 104 renamed[element] = name; |
| 102 return name; | 105 return name; |
| 103 } | 106 } |
| 104 } | 107 } |
| OLD | NEW |