Commit 4a92275a authored by Skylot's avatar Skylot

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

parent 6fca311d
......@@ -43,6 +43,8 @@ allprojects {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.1'
testCompile 'org.eclipse.jdt.core.compiler:ecj:4.6.1'
}
test {
......
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.FileOutputStream;
import java.io.IOException;
......@@ -21,26 +42,6 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
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 org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
......@@ -58,30 +59,38 @@ public abstract class IntegrationTest extends TestUtils {
private static final String TEST_DIRECTORY = "src/test/java";
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:
* <pre>
* public void check() {}
* </pre>
*/
public static final String CHECK_METHOD_NAME = "check";
private static final String CHECK_METHOD_NAME = "check";
protected JadxArgs args;
protected boolean deleteTmpFiles = true;
protected boolean withDebugInfo = true;
protected boolean unloadCls = true;
protected boolean deleteTmpFiles;
protected boolean withDebugInfo;
protected boolean unloadCls;
protected boolean compile;
protected boolean useEclipseCompiler;
protected Map<Integer, String> resMap = Collections.emptyMap();
protected String outDir = "test-out-tmp";
protected boolean compile = true;
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.setOutDir(new File(outDir));
args.setOutDir(new File(OUT_DIR));
args.setShowInconsistentCode(true);
args.setThreadsCount(1);
args.setSkipResources(true);
......@@ -377,28 +386,6 @@ public abstract class IntegrationTest extends TestUtils {
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 {
String clsFullName = cls.getName();
String rootClsName;
......@@ -418,7 +405,7 @@ public abstract class IntegrationTest extends TestUtils {
File outTmp = createTempDir("jadx-tmp-classes");
outTmp.deleteOnExit();
List<File> files = StaticCompiler.compile(compileFileList, outTmp, withDebugInfo);
List<File> files = StaticCompiler.compile(compileFileList, outTmp, withDebugInfo, useEclipseCompiler);
files.forEach(File::deleteOnExit);
// remove classes which are parents for test class
String clsName = clsFullName.substring(clsFullName.lastIndexOf('.') + 1);
......@@ -442,6 +429,10 @@ public abstract class IntegrationTest extends TestUtils {
this.withDebugInfo = false;
}
protected void useEclipseCompiler() {
this.useEclipseCompiler = true;
}
protected void setFallback() {
this.args.setFallbackMode(true);
}
......
package jadx.tests.api.compiler;
import java.io.File;
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;
import jadx.core.utils.files.FileUtils;
import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
......@@ -17,18 +11,28 @@ import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import jadx.core.utils.files.FileUtils;
import java.io.File;
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 {
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 {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
throw new IllegalStateException("Can not find compiler, please use JDK instead");
public static List<File> compile(List<File> files, File outDir, boolean includeDebugInfo, boolean useEclipseCompiler) throws IOException {
JavaCompiler compiler;
if (useEclipseCompiler) {
compiler = new EclipseCompiler();
} 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);
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(files);
......@@ -48,8 +52,8 @@ public class StaticCompiler {
}
private static class StaticFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
private List<File> files = new ArrayList<>();
private File outDir;
private final List<File> files = new ArrayList<>();
private final File outDir;
protected StaticFileManager(StandardJavaFileManager fileManager, File outDir) {
super(fileManager);
......@@ -57,8 +61,7 @@ public class StaticCompiler {
}
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind,
FileObject sibling) throws IOException {
public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) {
if (kind == JavaFileObject.Kind.CLASS) {
File file = new File(outDir, className.replace('.', '/') + ".class");
files.add(file);
......@@ -73,7 +76,7 @@ public class StaticCompiler {
}
private static class ClassFileObject extends SimpleJavaFileObject {
private File file;
private final File file;
protected ClassFileObject(File file, Kind kind) {
super(file.toURI(), kind);
......
package jadx.tests.integration.arrays;
import org.junit.jupiter.api.Test;
import jadx.NotYetImplemented;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
......@@ -18,11 +18,12 @@ public class TestArrayFill3 extends IntegrationTest {
}
@Test
@NotYetImplemented
public void test() {
useEclipseCompiler();
ClassNode cls = getClassNode(TestCls.class);
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