From d148638094aa6d4e3d6259040c362f33d8ede4e0 Mon Sep 17 00:00:00 2001 From: tball Date: Fri, 28 Jul 2017 15:25:47 -0700 Subject: [PATCH] Updated PackageInfoLookup to use Procyon instead of ASM5, combined createClassFile methods. Change on 2017/07/28 by tball ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=163526498 --- .../j2objc/javac/ClassFileConverter.java | 3 +- .../devtools/j2objc/util/ClassFile.java | 4 ++ .../j2objc/util/PackageInfoLookup.java | 65 +++++++++---------- .../devtools/j2objc/GenerationTest.java | 50 +++++++------- .../j2objc/util/PackageInfoLookupTest.java | 5 ++ 5 files changed, 70 insertions(+), 57 deletions(-) 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 70e494d349..dbdf39f1ff 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 @@ -120,7 +120,8 @@ private ClassFileConverter(JavacEnvironment parserEnv, TranslationEnvironment tr */ private void setClassPath() throws IOException { String fullPath = file.getAbsolutePath(); - String rootPath = fullPath.substring(0, fullPath.lastIndexOf(classFile.getName() + ".class")); + String relativePath = classFile.getFullName().replace('.', '/') + ".class"; + String rootPath = fullPath.substring(0, fullPath.lastIndexOf(relativePath)); List classPath = new ArrayList<>(); classPath.add(new File(rootPath)); parserEnv.fileManager().setLocation(StandardLocation.CLASS_PATH, classPath); diff --git a/translator/src/main/java/com/google/devtools/j2objc/util/ClassFile.java b/translator/src/main/java/com/google/devtools/j2objc/util/ClassFile.java index e2cbe4f5cb..a67bc0798b 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/util/ClassFile.java +++ b/translator/src/main/java/com/google/devtools/j2objc/util/ClassFile.java @@ -160,6 +160,10 @@ public ConstructorDeclaration getConstructor(String signature) { return null; } + public TypeDeclaration getType() { + return type; + } + private String signature(MethodDeclaration method) { StringBuilder sb = new StringBuilder(); signature(method.getParameters(), sb); diff --git a/translator/src/main/java/com/google/devtools/j2objc/util/PackageInfoLookup.java b/translator/src/main/java/com/google/devtools/j2objc/util/PackageInfoLookup.java index b8cd191e37..9a1be5f8e8 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/util/PackageInfoLookup.java +++ b/translator/src/main/java/com/google/devtools/j2objc/util/PackageInfoLookup.java @@ -16,15 +16,16 @@ import com.google.devtools.j2objc.file.InputFile; import com.google.j2objc.annotations.ReflectionSupport; +import com.strobel.decompiler.languages.java.ast.Annotation; +import com.strobel.decompiler.languages.java.ast.Expression; +import com.strobel.decompiler.languages.java.ast.MemberReferenceExpression; +import com.strobel.decompiler.languages.java.ast.PrimitiveExpression; +import com.strobel.decompiler.languages.java.ast.TypeDeclaration; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.Opcodes; /** * Looks up package specific attributes by looking up and parsing package-info java or class files. @@ -107,14 +108,14 @@ private PackageData getPackageData(String packageName) { private PackageData findPackageData(String packageName) { try { - String fileName = packageName + ".package-info"; + String typeName = packageName + ".package-info"; // First look on the sourcepath. - InputFile sourceFile = fileUtil.findOnSourcePath(fileName); + InputFile sourceFile = fileUtil.findOnSourcePath(typeName); if (sourceFile != null) { return parseDataFromSourceFile(sourceFile); } // Then look on the classpath. - InputFile classFile = fileUtil.findOnClassPath(fileName); + InputFile classFile = fileUtil.findOnClassPath(typeName); if (classFile != null) { return parseDataFromClassFile(classFile); } @@ -194,35 +195,31 @@ private PackageData parseDataFromSourceFile(InputFile file) throws IOException { private PackageData parseDataFromClassFile(InputFile file) throws IOException { PackageDataBuilder builder = new PackageDataBuilder(); - ClassReader classReader = new ClassReader(file.getInputStream()); - classReader.accept(new ClassVisitor(Opcodes.ASM5) { - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - if (desc.equals("Lcom/google/j2objc/annotations/ObjectiveCName;")) { - return new AnnotationVisitor(Opcodes.ASM5) { - @Override - public void visit(String name, Object value) { - if (name.equals("value")) { - builder.setObjectiveCName(value.toString()); - } - } - }; - } else if (desc.equals("Ljavax/annotation/ParametersAreNonnullByDefault;")) { - builder.setParametersAreNonnullByDefault(); - } else if (desc.equals("Lcom/google/j2objc/annotations/ReflectionSupport;")) { - return new AnnotationVisitor(Opcodes.ASM5) { - @Override - public void visitEnum(String name, String desc, String value) { - if (desc.equals("Lcom/google/j2objc/annotations/ReflectionSupport$Level;") - && name.equals("value")) { - builder.setReflectionSupportLevel(ReflectionSupport.Level.valueOf(value)); - } - } - }; + ClassFile classFile = ClassFile.create(file); + TypeDeclaration typeDecl = classFile.getType(); + for (Annotation annotation : typeDecl.getAnnotations()) { + String signature = annotation.getType().toTypeReference().getErasedSignature(); + if (signature.equals("Lcom/google/j2objc/annotations/ObjectiveCName;")) { + for (Expression expr : annotation.getArguments()) { + if (expr instanceof MemberReferenceExpression) { + String value = ((MemberReferenceExpression) expr).getMemberName(); + builder.setObjectiveCName(value); + } else if (expr instanceof PrimitiveExpression) { + Object value = ((PrimitiveExpression) expr).getValue(); + builder.setObjectiveCName((String) value); + } + } + } else if (signature.equals("Ljavax/annotation/ParametersAreNonnullByDefault;")) { + builder.setParametersAreNonnullByDefault(); + } else if (signature.equals("Lcom/google/j2objc/annotations/ReflectionSupport;")) { + for (Expression expr : annotation.getArguments()) { + if (expr instanceof MemberReferenceExpression) { + String value = ((MemberReferenceExpression) expr).getMemberName(); + builder.setReflectionSupportLevel(ReflectionSupport.Level.valueOf(value)); + } } - return null; } - }, 0); + } return builder.build(); } } diff --git a/translator/src/test/java/com/google/devtools/j2objc/GenerationTest.java b/translator/src/test/java/com/google/devtools/j2objc/GenerationTest.java index 02b78e10b7..d70f9acd5f 100644 --- a/translator/src/test/java/com/google/devtools/j2objc/GenerationTest.java +++ b/translator/src/test/java/com/google/devtools/j2objc/GenerationTest.java @@ -107,10 +107,11 @@ protected void tearDown() throws Exception { protected void loadOptions() throws IOException { options = new Options(); - + String tempPath = tempDir.getAbsolutePath(); options.load(new String[]{ - "-d", tempDir.getAbsolutePath(), - "-sourcepath", tempDir.getAbsolutePath(), + "-d", tempPath, + "-sourcepath", tempPath, + "-classpath", tempPath, "-q", // Suppress console output. "-encoding", "UTF-8" // Translate strings correctly when encodings are nonstandard. }); @@ -206,7 +207,7 @@ protected CompilationUnit compileType(String name, String source) { * @return the parsed compilation unit */ protected CompilationUnit compileAsClassFile(String name, String source) throws IOException { - return compileAsClassFile(name, source, "-parameters", "-cp", tempDir.getAbsolutePath()); + return compileAsClassFile(name, source, "-parameters"); } /** @@ -236,20 +237,6 @@ protected CompilationUnit compileAsClassFile(String name, String source, return unit; } - /** - * Compiles Java source to a JVM class file. - * - * @param typeName the name of the type being declared - * @param source the source code - * @return the InputFile defining the class file - */ - protected InputFile createClassFile(String typeName, String source) throws IOException { - String tempPath = tempDir.getAbsolutePath(); - List classpath = getComGoogleDevtoolsJ2objcPath(); - classpath.add(0, tempPath); - return createClassFile(typeName, source, "-d", tempPath, "-cp", String.join(":", classpath)); - } - /** * Compiles Java source to a JVM class file. * @@ -267,13 +254,23 @@ protected InputFile createClassFile(String typeName, String source, String... fl fw.write(source); } - String[] args = new String[flags.length + 1]; - System.arraycopy(flags, 0, args, 0, flags.length); - args[flags.length] = srcFile.getPath(); + List args = new ArrayList<>(Arrays.asList(flags)); + String tempPath = tempDir.getAbsolutePath(); + if (!args.contains("-d")) { + args.add("-d"); + args.add(tempPath); + } + if (!args.contains("-classpath") && !args.contains("-cp")) { + args.add("-classpath"); + List classpath = getComGoogleDevtoolsJ2objcPath(); + classpath.add(0, tempPath); + args.add(String.join(":", classpath)); + } + args.add(srcFile.getPath()); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); ByteArrayOutputStream errOut = new ByteArrayOutputStream(); - int numErrors = compiler.run(null, null, errOut, args); + int numErrors = compiler.run(null, null, errOut, args.toArray(new String[0])); if (numErrors > 0) { String errMsg = errOut.toString(); ErrorUtil.error(errMsg); @@ -560,6 +557,15 @@ protected String addSourceFile(String source, String fileName) throws IOExceptio return file.getPath(); } + /** + * Removes a file from the tmp directory, + */ + protected void removeFile(String relativePath) { + if (!new File(tempDir, relativePath).delete()) { + + } + } + /** * Return the contents of a previously translated file, made by a call to * {@link #translateMethod} above. diff --git a/translator/src/test/java/com/google/devtools/j2objc/util/PackageInfoLookupTest.java b/translator/src/test/java/com/google/devtools/j2objc/util/PackageInfoLookupTest.java index bced82e231..418f37d6dd 100644 --- a/translator/src/test/java/com/google/devtools/j2objc/util/PackageInfoLookupTest.java +++ b/translator/src/test/java/com/google/devtools/j2objc/util/PackageInfoLookupTest.java @@ -67,6 +67,7 @@ public void testFullReflectionSupportSetValueCompiled() throws IOException { createClassFile("foo.package-info", "@ReflectionSupport(value = ReflectionSupport.Level.FULL) package foo;" + "import com.google.j2objc.annotations.ReflectionSupport;"); + removeFile("foo/package-info.java"); CompilationUnit unit = translateType("foo.A", "package foo; public class A {}"); PackageInfoLookup packageInfoLookup = unit.getEnv().options().getPackageInfoLookup(); assertSame(ReflectionSupport.Level.FULL, packageInfoLookup.getReflectionSupportLevel("foo")); @@ -76,6 +77,7 @@ public void testFullReflectionSupportCompiled() throws IOException { createClassFile("bar.package-info", "@ReflectionSupport(ReflectionSupport.Level.FULL) package bar;" + "import com.google.j2objc.annotations.ReflectionSupport;"); + removeFile("bar/package-info.java"); CompilationUnit unit = translateType("bar.A", "package bar; public class A {}"); PackageInfoLookup packageInfoLookup = unit.getEnv().options().getPackageInfoLookup(); assertSame(ReflectionSupport.Level.FULL, packageInfoLookup.getReflectionSupportLevel("bar")); @@ -85,6 +87,7 @@ public void testNativeOnlyReflectionSupportCompiled() throws IOException { createClassFile("baz.package-info", "@com.google.j2objc.annotations.ReflectionSupport" + "(com.google.j2objc.annotations.ReflectionSupport.Level.NATIVE_ONLY) package baz;"); + removeFile("baz/package-info.java"); CompilationUnit unit = translateType("baz.A", "package baz; public class A {}"); PackageInfoLookup packageInfoLookup = unit.getEnv().options().getPackageInfoLookup(); assertSame(ReflectionSupport.Level.NATIVE_ONLY, @@ -95,6 +98,7 @@ public void testPackageRenameCompiled() throws IOException { createClassFile("foo.package-info", "@ObjectiveCName(\"XYZ\") package foo; " + "import com.google.j2objc.annotations.ObjectiveCName;"); + removeFile("foo/package-info.java"); String translation = translateSourceFile("package foo; public class A {}", "foo.A", "foo/A.h"); assertTranslation(translation, "@interface XYZA"); } @@ -110,6 +114,7 @@ public void testParametersAreNonnullByDefault() throws IOException { createClassFile("bar.package-info", "@ParametersAreNonnullByDefault package bar;" + "import javax.annotation.ParametersAreNonnullByDefault;"); + removeFile("bar/package-info.java"); CompilationUnit unit = translateType("bar.A", "package bar; public class A {}"); PackageInfoLookup packageInfoLookup = unit.getEnv().options().getPackageInfoLookup(); assertTrue(packageInfoLookup.hasParametersAreNonnullByDefault("bar"));