Skip to content

Commit

Permalink
Simplify and move anonymous class renaming logic into NameTable.
Browse files Browse the repository at this point in the history
	Change on 2015/04/08 by kstanger <kstanger@google.com>
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=90621175
  • Loading branch information
kstanger committed Apr 9, 2015
1 parent f1684d4 commit b8cf615
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 344 deletions.
Expand Up @@ -16,15 +16,12 @@

package com.google.devtools.j2objc.translate;

import com.google.common.annotations.VisibleForTesting;
import com.google.devtools.j2objc.ast.AbstractTypeDeclaration;
import com.google.devtools.j2objc.ast.AnonymousClassDeclaration;
import com.google.devtools.j2objc.ast.Block;
import com.google.devtools.j2objc.ast.BodyDeclaration;
import com.google.devtools.j2objc.ast.ClassInstanceCreation;
import com.google.devtools.j2objc.ast.CompilationUnit;
import com.google.devtools.j2objc.ast.EnumConstantDeclaration;
import com.google.devtools.j2objc.ast.EnumDeclaration;
import com.google.devtools.j2objc.ast.Expression;
import com.google.devtools.j2objc.ast.MethodDeclaration;
import com.google.devtools.j2objc.ast.SimpleName;
Expand All @@ -37,14 +34,11 @@
import com.google.devtools.j2objc.ast.TypeDeclaration;
import com.google.devtools.j2objc.types.GeneratedMethodBinding;
import com.google.devtools.j2objc.types.GeneratedVariableBinding;
import com.google.devtools.j2objc.types.Types;
import com.google.devtools.j2objc.util.NameTable;

import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;

import java.lang.reflect.Modifier;
import java.util.Stack;

/**
* Converts anonymous classes into inner classes. This includes creating
Expand All @@ -57,17 +51,6 @@
*/
public class AnonymousClassConverter extends TreeVisitor {

@Override
public boolean visit(CompilationUnit node) {
preProcessUnit(node);
return true;
}

@VisibleForTesting
void preProcessUnit(CompilationUnit node) {
node.accept(new AnonymousClassRenamer());
}

/**
* Convert the anonymous class into an inner class. Fields are added for
* final variables that are referenced, and a constructor is added.
Expand Down Expand Up @@ -195,69 +178,4 @@ private IMethodBinding findSuperConstructorBinding(IMethodBinding constructorBin
}
throw new AssertionError("could not find constructor");
}

/**
* Rename anonymous classes to class file-like $n names, where n is the
* index of the number of anonymous classes for the parent type. A stack
* is used to ensure that anonymous classes defined inside of other
* anonymous classes are numbered correctly.
*/
static class AnonymousClassRenamer extends TreeVisitor {

private static class Frame {
int classCount = 0;
}
final Stack<Frame> classIndex = new Stack<Frame>();

@Override
public boolean visit(TypeDeclaration node) {
return processType();
}

@Override
public boolean visit(EnumDeclaration node) {
return processType();
}

private boolean processType() {
classIndex.push(new Frame());
return true;
}

@Override
public boolean visit(AnonymousClassDeclaration node) {
Frame parentFrame = classIndex.peek();

String className = "$" + ++parentFrame.classCount;
ITypeBinding innerType = renameClass(className, node.getTypeBinding());
node.setTypeBinding(innerType);
NameTable.rename(node.getTypeBinding(), className);

classIndex.push(new Frame());
return true;
}

private ITypeBinding renameClass(String name, ITypeBinding oldBinding) {
ITypeBinding outerType = Types.getRenamedBinding(oldBinding.getDeclaringClass());
NameTable.rename(oldBinding, name);
ITypeBinding newBinding = Types.renameTypeBinding(name, outerType, oldBinding);
assert newBinding.getName().equals(name);
return newBinding;
}

@Override
public void endVisit(TypeDeclaration node) {
classIndex.pop();
}

@Override
public void endVisit(EnumDeclaration node) {
classIndex.pop();
}

@Override
public void endVisit(AnonymousClassDeclaration node) {
classIndex.pop();
}
}
}

This file was deleted.

Expand Up @@ -37,7 +37,6 @@
public class Types {
private final AST ast;
private final Map<ITypeBinding, ITypeBinding> typeMap = Maps.newHashMap();
private final Map<ITypeBinding, ITypeBinding> renamedTypeMap = Maps.newHashMap();
private final Map<ITypeBinding, ITypeBinding> primitiveToWrapperTypes =
new HashMap<ITypeBinding, ITypeBinding>();
private final Map<ITypeBinding, ITypeBinding> wrapperToPrimitiveTypes =
Expand Down Expand Up @@ -280,19 +279,6 @@ public static IOSTypeBinding resolveArrayType(ITypeBinding binding) {
return arrayBinding != null ? arrayBinding : instance.IOSObjectArray;
}

public static ITypeBinding renameTypeBinding(String newName, ITypeBinding newDeclaringClass,
ITypeBinding originalBinding) {
ITypeBinding renamedBinding =
RenamedTypeBinding.rename(newName, newDeclaringClass, originalBinding);
instance.renamedTypeMap.put(originalBinding, renamedBinding);
return renamedBinding;
}

public static ITypeBinding getRenamedBinding(ITypeBinding original) {
return original != null && instance.renamedTypeMap.containsKey(original)
? instance.renamedTypeMap.get(original) : original;
}

public static boolean isVoidType(ITypeBinding type) {
return type.isEqualTo(instance.voidType);
}
Expand Down
Expand Up @@ -323,6 +323,7 @@ public static void cleanup() {
public static String getName(IBinding binding) {
assert binding != null;
assert !(binding instanceof IMethodBinding);
assert !(binding instanceof ITypeBinding);
binding = getBindingDeclaration(binding);
String newName = instance.renamings.get(binding);
if (newName != null) {
Expand Down Expand Up @@ -808,16 +809,8 @@ public static String getFullName(ITypeBinding binding) {
private static String getFullNameInner(ITypeBinding binding) {
binding = Types.mapType(binding.getErasure()); // Make sure type variables aren't included.
ITypeBinding outerBinding = binding.getDeclaringClass();
if (binding.isLocal() && !binding.isAnonymous()) {
String binaryName = binding.getBinaryName();
int innerClassIndex = binaryName.lastIndexOf(binding.getName());
while (innerClassIndex > 0 && binaryName.charAt(innerClassIndex - 1) != '$') {
--innerClassIndex;
}
return getFullNameInner(outerBinding) + '_' + binaryName.substring(innerClassIndex);
}
if (outerBinding != null) {
String baseName = getFullNameInner(outerBinding) + '_' + getName(binding);
String baseName = getFullNameInner(outerBinding) + '_' + getTypeSubName(binding);
return (outerBinding.isEnum() && binding.isAnonymous()) ? baseName : baseName;
}
String name = binding.getQualifiedName();
Expand All @@ -839,6 +832,21 @@ private static String getFullNameInner(ITypeBinding binding) {
return pkgName + binding.getName();
}

private static String getTypeSubName(ITypeBinding binding) {
if (binding.isAnonymous()) {
String binaryName = binding.getBinaryName();
return binaryName.substring(binaryName.lastIndexOf("$"));
} else if (binding.isLocal()) {
String binaryName = binding.getBinaryName();
int innerClassIndex = binaryName.lastIndexOf(binding.getName());
while (innerClassIndex > 0 && binaryName.charAt(innerClassIndex - 1) != '$') {
--innerClassIndex;
}
return binaryName.substring(innerClassIndex);
}
return binding.getName();
}

private static boolean isReservedName(String name) {
return reservedNames.contains(name) || nsObjectMessages.contains(name);
}
Expand Down
Expand Up @@ -62,7 +62,6 @@
import com.google.devtools.j2objc.types.BindingMapBuilderTest;
import com.google.devtools.j2objc.types.HeaderImportCollectorTest;
import com.google.devtools.j2objc.types.ImplementationImportCollectorTest;
import com.google.devtools.j2objc.types.RenamedTypeBindingTest;
import com.google.devtools.j2objc.util.BindingUtilTest;
import com.google.devtools.j2objc.util.DeadCodeMapTest;
import com.google.devtools.j2objc.util.ErrorUtilTest;
Expand Down Expand Up @@ -122,7 +121,6 @@ public class SmallTests {
PrimitiveArrayTest.class,
PrivateDeclarationResolverTest.class,
ProGuardUsageParserTest.class,
RenamedTypeBindingTest.class,
RewriterTest.class,
SignatureGeneratorTest.class,
StatementGeneratorTest.class,
Expand Down
Expand Up @@ -90,7 +90,7 @@ public void testAnonymousClassExtracted() {
assertEquals(2, types.size());

TypeDeclaration type = types.get(1);
assertEquals("$1", type.getName().getIdentifier());
assertEquals("Test$1", type.getTypeBinding().getBinaryName());
}

/**
Expand Down

0 comments on commit b8cf615

Please sign in to comment.