Skip to content

Commit

Permalink
Fixed classfile translation of parameterized classes.
Browse files Browse the repository at this point in the history
	Change on 2018/07/18 by tball <tball@google.com>

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=205162093
  • Loading branch information
tomball authored and Tom Ball committed Jul 31, 2018
1 parent 401ee7a commit 528f1ed
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 17 deletions.
Expand Up @@ -357,7 +357,8 @@ private TreeNode convertFieldDeclaration(VariableElement element) {
private boolean isEnumSynthetic(Element e, TypeMirror enumType) {
if (e.getKind() == ElementKind.STATIC_INIT) {
return true;
} else if (e.getKind() == ElementKind.METHOD) {
}
if (e.getKind() == ElementKind.METHOD) {
ExecutableElement method = (ExecutableElement) e;
String enumSig = translationEnv.typeUtil().getSignatureName(enumType);
String valueOfDesc = "(Ljava/lang/String;)" + enumSig;
Expand All @@ -375,11 +376,13 @@ private TreeNode convertEnumDeclaration(TypeElement element){
EnumDeclaration enumDecl = new EnumDeclaration(element);
convertBodyDeclaration(enumDecl, element);
for (Element elem : element.getEnclosedElements()) {
TreeNode encElem = convert(elem, enumDecl);
if (encElem.getKind() == TreeNode.Kind.ENUM_CONSTANT_DECLARATION) {
enumDecl.addEnumConstant((EnumConstantDeclaration) encElem);
} else if (!isEnumSynthetic(elem, element.asType())) {
enumDecl.addBodyDeclaration((BodyDeclaration) encElem);
if (!isEnumSynthetic(elem, element.asType())) {
TreeNode encElem = convert(elem, enumDecl);
if (encElem.getKind() == TreeNode.Kind.ENUM_CONSTANT_DECLARATION) {
enumDecl.addEnumConstant((EnumConstantDeclaration) encElem);
} else {
enumDecl.addBodyDeclaration((BodyDeclaration) encElem);
}
}
}
enumDecl.removeModifiers(Modifier.FINAL);
Expand All @@ -389,7 +392,6 @@ private TreeNode convertEnumDeclaration(TypeElement element){
private TreeNode convertEnumConstantDeclaration(VariableElement element) {
EnumConstantDeclaration enumConstDecl = new EnumConstantDeclaration(element);
convertBodyDeclaration(enumConstDecl, element);
/* TODO(user): set ExecutablePair */
return enumConstDecl;
}
}
Expand Up @@ -60,7 +60,7 @@
import com.google.devtools.j2objc.util.TranslationEnvironment;
import com.google.devtools.j2objc.util.TranslationUtil;
import com.google.devtools.j2objc.util.TypeUtil;
import com.strobel.assembler.metadata.MethodDefinition;
import com.strobel.assembler.metadata.MethodReference;
import com.strobel.assembler.metadata.TypeReference;
import com.strobel.core.StringUtilities;
import com.strobel.decompiler.languages.java.ast.AnonymousObjectCreationExpression;
Expand Down Expand Up @@ -121,6 +121,7 @@
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;

/**
Expand Down Expand Up @@ -209,7 +210,7 @@ public TreeNode visitPatternPlaceholder(AstNode node, Pattern pattern, Void data

@Override
public TreeNode visitInvocationExpression(InvocationExpression node, Void data) {
MethodDefinition methodDef = (MethodDefinition) node.getUserData(Keys.MEMBER_REFERENCE);
MethodReference methodDef = (MethodReference) node.getUserData(Keys.MEMBER_REFERENCE);
com.strobel.decompiler.languages.java.ast.Expression target = node.getTarget();
if (target instanceof SuperReferenceExpression) {
return target.acceptVisitor(this, null);
Expand All @@ -227,12 +228,11 @@ public TreeNode visitInvocationExpression(InvocationExpression node, Void data)
return newNode;
}
if (target instanceof MemberReferenceExpression) {
TypeElement declaringType =
(TypeElement) ((DeclaredType) resolve(methodDef.getDeclaringType())).asElement();
TypeMirror type = resolve(methodDef.getDeclaringType());
List<Expression> args = node.getArguments().stream()
.map(e -> (Expression) e.acceptVisitor(this, null))
.collect(Collectors.toList());
ExecutableElement sym = findMethod(methodDef.getName(), declaringType, methodDef);
ExecutableElement sym = findMethod(methodDef.getName(), type, methodDef);
Expression expr = (Expression) target.getFirstChild().acceptVisitor(this, null);
MethodInvocation newNode = new MethodInvocation()
.setExecutablePair(new ExecutablePair(sym))
Expand All @@ -244,22 +244,24 @@ public TreeNode visitInvocationExpression(InvocationExpression node, Void data)
throw new AssertionError("not implemented");
}

private ExecutableElement findMethod(String name, TypeElement type, MethodDefinition methodDef) {
private ExecutableElement findMethod(String name, TypeMirror type, MethodReference methodDef) {
TypeElement typeElement = (TypeElement) (type.getKind() == TypeKind.ARRAY
? ((com.sun.tools.javac.code.Type.ArrayType) type).tsym
: parserEnv.typeUtilities().asElement(type));
String signature = methodDef.getSignature();
String erasedSignature = methodDef.getErasedSignature();
for (Element e : type.getEnclosedElements()) {
for (Element e : typeElement.getEnclosedElements()) {
if (e.getKind() == ElementKind.METHOD && e.getSimpleName().contentEquals(name)) {
String sig = typeUtil.getReferenceSignature((ExecutableElement) e);
if (sig.equals(signature) || sig.equals(erasedSignature)) {
return (ExecutableElement) e;
}
}
}
throw new AssertionError(
"failed method lookup: " + type.getQualifiedName() + " " + name + signature);
throw new AssertionError("failed method lookup: " + type + " " + name + signature);
}

private ExecutableElement findConstructor(TypeElement type, MethodDefinition methodDef) {
private ExecutableElement findConstructor(TypeElement type, MethodReference methodDef) {
String signature = methodDef.getSignature();
String erasedSignature = methodDef.getErasedSignature();
for (Element e : type.getEnclosedElements()) {
Expand Down
Expand Up @@ -282,6 +282,14 @@ public void testFieldMethodModifiers() throws IOException {
assertEqualSrcClassfile(type, source);
}

public void testParameterizedClass() throws IOException {
String source = String.join("\n",
"package foo.bar;",
"class StringList extends java.util.ArrayList<String> {}"
);
assertEqualSrcClassfile("foo.bar.StringList", source);
}

// public void testSimpleEnum() throws IOException {
// String type = "foo.bar.Day";
// String source = String.join("\n",
Expand Down

0 comments on commit 528f1ed

Please sign in to comment.