Commit 4a92275a authored by Skylot's avatar Skylot

test: allow use Eclipse compiler in tests (#536)

parent 6fca311d
...@@ -43,6 +43,8 @@ allprojects { ...@@ -43,6 +43,8 @@ allprojects {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.1' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.1'
testCompile 'org.eclipse.jdt.core.compiler:ecj:4.6.1'
} }
test { test {
......
package jadx.tests.api; package jadx.tests.api;
import jadx.api.JadxArgs;
import jadx.api.JadxDecompiler;
import jadx.api.JadxInternalAccess;
import jadx.core.ProcessClass;
import jadx.core.codegen.CodeGen;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.AttrList;
import jadx.core.dex.attributes.IAttributeNode;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.dex.visitors.DepthTraversal;
import jadx.core.dex.visitors.IDexTreeVisitor;
import jadx.core.xmlgen.ResourceStorage;
import jadx.core.xmlgen.entry.ResourceEntry;
import jadx.tests.api.compiler.DynamicCompiler;
import jadx.tests.api.compiler.StaticCompiler;
import jadx.tests.api.utils.TestUtils;
import org.junit.jupiter.api.BeforeEach;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
...@@ -21,26 +42,6 @@ import java.util.concurrent.TimeUnit; ...@@ -21,26 +42,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
import jadx.api.JadxArgs;
import jadx.api.JadxDecompiler;
import jadx.api.JadxInternalAccess;
import jadx.core.ProcessClass;
import jadx.core.codegen.CodeGen;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.AttrList;
import jadx.core.dex.attributes.IAttributeNode;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.dex.visitors.DepthTraversal;
import jadx.core.dex.visitors.IDexTreeVisitor;
import jadx.core.xmlgen.ResourceStorage;
import jadx.core.xmlgen.entry.ResourceEntry;
import jadx.tests.api.compiler.DynamicCompiler;
import jadx.tests.api.compiler.StaticCompiler;
import jadx.tests.api.utils.TestUtils;
import static jadx.core.utils.files.FileUtils.addFileToJar; import static jadx.core.utils.files.FileUtils.addFileToJar;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
...@@ -58,30 +59,38 @@ public abstract class IntegrationTest extends TestUtils { ...@@ -58,30 +59,38 @@ public abstract class IntegrationTest extends TestUtils {
private static final String TEST_DIRECTORY = "src/test/java"; private static final String TEST_DIRECTORY = "src/test/java";
private static final String TEST_DIRECTORY2 = "jadx-core/" + TEST_DIRECTORY; private static final String TEST_DIRECTORY2 = "jadx-core/" + TEST_DIRECTORY;
private static final String OUT_DIR = "test-out-tmp";
/** /**
* Run auto check method if defined: * Run auto check method if defined:
* <pre> * <pre>
* public void check() {} * public void check() {}
* </pre> * </pre>
*/ */
public static final String CHECK_METHOD_NAME = "check"; private static final String CHECK_METHOD_NAME = "check";
protected JadxArgs args; protected JadxArgs args;
protected boolean deleteTmpFiles = true; protected boolean deleteTmpFiles;
protected boolean withDebugInfo = true; protected boolean withDebugInfo;
protected boolean unloadCls = true; protected boolean unloadCls;
protected boolean compile;
protected boolean useEclipseCompiler;
protected Map<Integer, String> resMap = Collections.emptyMap(); protected Map<Integer, String> resMap = Collections.emptyMap();
protected String outDir = "test-out-tmp";
protected boolean compile = true;
private DynamicCompiler dynamicCompiler; private DynamicCompiler dynamicCompiler;
public IntegrationTest() { @BeforeEach
public void init() {
this.deleteTmpFiles = true;
this.unloadCls = true;
this.withDebugInfo = true;
this.compile = true;
this.useEclipseCompiler = false;
this.resMap = Collections.emptyMap();
args = new JadxArgs(); args = new JadxArgs();
args.setOutDir(new File(outDir)); args.setOutDir(new File(OUT_DIR));
args.setShowInconsistentCode(true); args.setShowInconsistentCode(true);
args.setThreadsCount(1); args.setThreadsCount(1);
args.setSkipResources(true); args.setSkipResources(true);
...@@ -377,28 +386,6 @@ public abstract class IntegrationTest extends TestUtils { ...@@ -377,28 +386,6 @@ public abstract class IntegrationTest extends TestUtils {
throw new IOException("Failed to create temp directory"); throw new IOException("Failed to create temp directory");
} }
private List<File> getClassFilesWithInners(Class<?> cls) {
List<File> list = new ArrayList<>();
String pkgName = cls.getPackage().getName();
URL pkgResource = ClassLoader.getSystemClassLoader().getResource(pkgName.replace('.', '/'));
if (pkgResource != null) {
try {
String clsName = cls.getName();
File directory = new File(pkgResource.toURI());
String[] files = directory.list();
for (String file : files) {
String fullName = pkgName + '.' + file;
if (fullName.startsWith(clsName)) {
list.add(new File(directory, file));
}
}
} catch (URISyntaxException e) {
fail(e.getMessage());
}
}
return list;
}
private List<File> compileClass(Class<?> cls) throws IOException { private List<File> compileClass(Class<?> cls) throws IOException {
String clsFullName = cls.getName(); String clsFullName = cls.getName();
String rootClsName; String rootClsName;
...@@ -418,7 +405,7 @@ public abstract class IntegrationTest extends TestUtils { ...@@ -418,7 +405,7 @@ public abstract class IntegrationTest extends TestUtils {
File outTmp = createTempDir("jadx-tmp-classes"); File outTmp = createTempDir("jadx-tmp-classes");
outTmp.deleteOnExit(); outTmp.deleteOnExit();
List<File> files = StaticCompiler.compile(compileFileList, outTmp, withDebugInfo); List<File> files = StaticCompiler.compile(compileFileList, outTmp, withDebugInfo, useEclipseCompiler);
files.forEach(File::deleteOnExit); files.forEach(File::deleteOnExit);
// remove classes which are parents for test class // remove classes which are parents for test class
String clsName = clsFullName.substring(clsFullName.lastIndexOf('.') + 1); String clsName = clsFullName.substring(clsFullName.lastIndexOf('.') + 1);
...@@ -442,6 +429,10 @@ public abstract class IntegrationTest extends TestUtils { ...@@ -442,6 +429,10 @@ public abstract class IntegrationTest extends TestUtils {
this.withDebugInfo = false; this.withDebugInfo = false;
} }
protected void useEclipseCompiler() {
this.useEclipseCompiler = true;
}
protected void setFallback() { protected void setFallback() {
this.args.setFallbackMode(true); this.args.setFallbackMode(true);
} }
......
package jadx.tests.api.compiler; package jadx.tests.api.compiler;
import java.io.File; import jadx.core.utils.files.FileUtils;
import java.io.FileOutputStream; import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.tools.FileObject; import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager; import javax.tools.ForwardingJavaFileManager;
...@@ -17,18 +11,28 @@ import javax.tools.JavaFileObject; ...@@ -17,18 +11,28 @@ import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject; import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager; import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider; import javax.tools.ToolProvider;
import java.io.File;
import jadx.core.utils.files.FileUtils; import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class StaticCompiler { public class StaticCompiler {
private static final List<String> COMMON_ARGS = Arrays.asList("-source 1.8 -target 1.8".split(" ")); private static final List<String> COMMON_ARGS = Arrays.asList("-source 1.8 -target 1.8".split(" "));
public static List<File> compile(List<File> files, File outDir, boolean includeDebugInfo) throws IOException { public static List<File> compile(List<File> files, File outDir, boolean includeDebugInfo, boolean useEclipseCompiler) throws IOException {
JavaCompiler compiler;
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); if (useEclipseCompiler) {
if (compiler == null) { compiler = new EclipseCompiler();
throw new IllegalStateException("Can not find compiler, please use JDK instead"); } else {
compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
throw new IllegalStateException("Can not find compiler, please use JDK instead");
}
} }
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(files); Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(files);
...@@ -48,8 +52,8 @@ public class StaticCompiler { ...@@ -48,8 +52,8 @@ public class StaticCompiler {
} }
private static class StaticFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> { private static class StaticFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
private List<File> files = new ArrayList<>(); private final List<File> files = new ArrayList<>();
private File outDir; private final File outDir;
protected StaticFileManager(StandardJavaFileManager fileManager, File outDir) { protected StaticFileManager(StandardJavaFileManager fileManager, File outDir) {
super(fileManager); super(fileManager);
...@@ -57,8 +61,7 @@ public class StaticCompiler { ...@@ -57,8 +61,7 @@ public class StaticCompiler {
} }
@Override @Override
public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) {
FileObject sibling) throws IOException {
if (kind == JavaFileObject.Kind.CLASS) { if (kind == JavaFileObject.Kind.CLASS) {
File file = new File(outDir, className.replace('.', '/') + ".class"); File file = new File(outDir, className.replace('.', '/') + ".class");
files.add(file); files.add(file);
...@@ -73,7 +76,7 @@ public class StaticCompiler { ...@@ -73,7 +76,7 @@ public class StaticCompiler {
} }
private static class ClassFileObject extends SimpleJavaFileObject { private static class ClassFileObject extends SimpleJavaFileObject {
private File file; private final File file;
protected ClassFileObject(File file, Kind kind) { protected ClassFileObject(File file, Kind kind) {
super(file.toURI(), kind); super(file.toURI(), kind);
......
package jadx.tests.integration.arrays; package jadx.tests.integration.arrays;
import org.junit.jupiter.api.Test; import jadx.NotYetImplemented;
import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest; import jadx.tests.api.IntegrationTest;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
...@@ -18,11 +18,12 @@ public class TestArrayFill3 extends IntegrationTest { ...@@ -18,11 +18,12 @@ public class TestArrayFill3 extends IntegrationTest {
} }
@Test @Test
@NotYetImplemented
public void test() { public void test() {
useEclipseCompiler();
ClassNode cls = getClassNode(TestCls.class); ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString(); String code = cls.getCode().toString();
assertThat(code, containsString("return new byte[]")); assertThat(code, containsString("return new byte[]{0, 1, 2}"));
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment