Chromium Code Reviews| Index: lib/compiler/implementation/dart_backend/renamer.dart |
| diff --git a/lib/compiler/implementation/dart_backend/renamer.dart b/lib/compiler/implementation/dart_backend/renamer.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..214b6a6160826094899ff9c531a9c99300af761c |
| --- /dev/null |
| +++ b/lib/compiler/implementation/dart_backend/renamer.dart |
| @@ -0,0 +1,116 @@ |
| +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +/** |
| + * Renames types, identifiers before printing them out. |
| + */ |
| +interface Renamer { |
|
Anton Muhin
2012/07/23 11:23:10
interfaces are going away, let's use just a single
Roman
2012/07/23 15:34:15
As discussed, created Renamer interface and NoRena
|
| + void setContext(Element element); |
| + |
| + /** |
| + * Renames type name for given type annotation. |
| + * Should not touch type arguments. |
| + */ |
| + String renameTypeName(TypeAnnotation type); |
| + |
| + String renameType(Type type); |
| + |
| + /** |
| + * Renames method name. |
| + */ |
| + String renameSendMethod(Send send); |
| + String renameIdentifier(Identifier node); |
| +} |
| + |
| +/** |
| + * Renames only top-level elements that would let to ambiguity if not renamed. |
| + */ |
| +class ConflictingRenamer implements Renamer { |
|
Anton Muhin
2012/07/23 11:23:10
Conflicting sounds weird, what do you try to conve
Roman
2012/07/23 15:34:15
That it renames only conflicting elements. I'm hap
|
| + final Compiler compiler; |
| + Map<Element, String> renamed; |
|
Anton Muhin
2012/07/23 11:23:10
final?
Roman
2012/07/23 15:34:15
Done.
|
| + Set<String> usedTopLevelIdentifiers; |
|
Anton Muhin
2012/07/23 11:23:10
final?
Roman
2012/07/23 15:34:15
Done.
|
| + Map<Element, TreeElements> get resolvedElements() => compiler.enqueuer.resolution.resolvedElements; |
|
Anton Muhin
2012/07/23 11:23:10
nit: please, move getter below the fields proper a
Roman
2012/07/23 15:34:15
Done.
|
| + TreeElements contextElements; |
| + Element context; |
| + |
| + ConflictingRenamer(this.compiler) : |
| + renamed = new Map<Element, String>(), |
| + usedTopLevelIdentifiers = new Set<String>(); |
| + |
| + void setContext(Element element) { |
|
Anton Muhin
2012/07/23 11:23:10
I don't like this setContext thing, cannot we crea
Roman
2012/07/23 15:34:15
Unfortunately not. Renamer should have a state (li
|
| + this.context = element; |
| + contextElements = resolvedElements[element]; |
| + } |
| + |
| + String renameSendMethod(Send send) { |
| + // Rename only if this Send is a function call. |
| + if (contextElements[send] !== null && contextElements[send].isFunction()) { |
|
Anton Muhin
2012/07/23 11:23:10
what about top-level variables?
Roman
2012/07/23 15:34:15
I don't quite understand. What about them?
Anton Muhin
2012/07/23 17:01:27
Shouldn't you rename them as well?
On 2012/07/23
|
| + return renameElement(contextElements[send]); |
| + } else { |
| + return null; |
| + } |
| + } |
| + |
| + String renameTypeName(TypeAnnotation typeAnnotation) { |
| + if (contextElements == null |
|
Anton Muhin
2012/07/23 11:23:10
nit: === null (here and below)
Anton Muhin
2012/07/23 11:23:10
how contextElements can be null?
Roman
2012/07/23 15:34:15
Done.
Roman
2012/07/23 15:34:15
this happens for class member fields.
Anton Muhin
2012/07/23 17:01:27
why? and, please, assert.
Roman
2012/07/23 17:38:32
I'm not sure why. Maybe resolver needs some fixes.
|
| + || contextElements.getType(typeAnnotation) == null) { |
| + // We have no info about this type from resolver. |
|
Anton Muhin
2012/07/23 11:23:10
when does it happen?
Roman
2012/07/23 15:34:15
this happens for class member fields. Maybe it's a
|
| + if (context.isField() && context.variables.computeType(compiler) !== null) { |
| + // A field. |
| + return renameType(context.variables.type); |
| + } else { |
| + return typeAnnotation.typeName.unparse(); |
| + } |
| + } |
| + |
| + Type type = contextElements.getType(typeAnnotation); |
| + if (typeAnnotation.typeName is Send |
|
Anton Muhin
2012/07/23 11:23:10
what about generic types?
Roman
2012/07/23 15:34:15
Generics are in type arguments. Here we care only
Anton Muhin
2012/07/23 17:01:27
Sorry, do you process generics correctly or not?
Roman
2012/07/23 17:38:33
Yes.
|
| + && typeAnnotation.typeName.receiver.source.slowToString() == type.name.slowToString()) { |
|
Anton Muhin
2012/07/23 11:23:10
what's the case when typeName is Send, but receive
Roman
2012/07/23 15:34:15
For example when we have a method that returns "my
|
| + // Got factory invocation. Need to rename first part. |
| + return "${renameType(type)}.${typeAnnotation.typeName.selector.source.slowToString()}"; |
| + } |
| + String newName = renameType(type); |
|
Anton Muhin
2012/07/23 11:23:10
nit: no need in newName local.
Roman
2012/07/23 15:34:15
Done.
|
| + return newName; |
| + } |
| + |
| + String renameType(Type type) { |
|
Anton Muhin
2012/07/23 11:23:10
nit: => renameElement(type.element);
Roman
2012/07/23 15:34:15
Done.
|
| + Element typeElement = type.element; |
| + return renameElement(typeElement); |
| + } |
| + |
| + String renameIdentifier(Identifier node) { |
| + if (context.isGenerativeConstructor()) { |
| + // This is either a factory constructor or simple one. |
| + var enclosingClass = context.getEnclosingClass(); |
| + if (node.token.slowToString() == context.name.slowToString() |
|
Anton Muhin
2012/07/23 11:23:10
it looks like you duplicate a work of a resolver:
Roman
2012/07/23 15:34:15
Added TODO as above. I'll try to investigate if re
|
| + || enclosingClass.name.slowToString() == node.token.slowToString()) { |
| + return renameElement(enclosingClass); |
| + } |
| + } |
| + if (context.isFunction() && context.cachedNode.name == node) { |
| + return renameElement(context); |
| + } |
| + return null; |
|
Anton Muhin
2012/07/23 11:23:10
again, what about top-level fields and privates?
Roman
2012/07/23 15:34:15
Again please elaborate :)
Anton Muhin
2012/07/23 17:01:27
:) I think we should rename both top level vars an
|
| + } |
| + |
| + String renameElement(Element element) { |
| + String originalName = element.name.slowToString(); |
| + if (element == null || element.getLibrary() == compiler.coreLibrary |
| + || !element.isTopLevel()) { |
| + return originalName; |
| + } |
| + if (renamed[element] !== null) { |
| + return renamed[element]; |
| + } |
| + |
| + // Not renamed and top element. |
| + String name = originalName; |
| + while (usedTopLevelIdentifiers.contains(name)) { |
| + name = "_$name"; |
| + } |
| + usedTopLevelIdentifiers.add(name); |
| + renamed[element] = name; |
| + return name; |
| + } |
| +} |