diff --git a/translator/src/main/java/com/google/devtools/j2objc/javac/ClassFileConverter.java b/translator/src/main/java/com/google/devtools/j2objc/javac/ClassFileConverter.java index c8464a3a3f..97629e9ccf 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/javac/ClassFileConverter.java +++ b/translator/src/main/java/com/google/devtools/j2objc/javac/ClassFileConverter.java @@ -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; @@ -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); @@ -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; } } diff --git a/translator/src/main/java/com/google/devtools/j2objc/javac/MethodTranslator.java b/translator/src/main/java/com/google/devtools/j2objc/javac/MethodTranslator.java index 0f1cf68e70..8af8df70b4 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/javac/MethodTranslator.java +++ b/translator/src/main/java/com/google/devtools/j2objc/javac/MethodTranslator.java @@ -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; @@ -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; /** @@ -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); @@ -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 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)) @@ -244,10 +244,13 @@ 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)) { @@ -255,11 +258,10 @@ private ExecutableElement findMethod(String name, TypeElement type, MethodDefini } } } - 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()) { diff --git a/translator/src/test/java/com/google/devtools/j2objc/javac/ClassFileConverterTest.java b/translator/src/test/java/com/google/devtools/j2objc/javac/ClassFileConverterTest.java index 94405ac6b6..c34be4d8b8 100644 --- a/translator/src/test/java/com/google/devtools/j2objc/javac/ClassFileConverterTest.java +++ b/translator/src/test/java/com/google/devtools/j2objc/javac/ClassFileConverterTest.java @@ -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 {}" + ); + assertEqualSrcClassfile("foo.bar.StringList", source); + } + // public void testSimpleEnum() throws IOException { // String type = "foo.bar.Day"; // String source = String.join("\n",