未验证 提交 6016b902 编写于 作者: S Skylot

test: fix usage of Eclipse compiler

上级 5852da1e
......@@ -38,7 +38,6 @@ allprojects {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
testImplementation 'org.eclipse.jdt.core.compiler:ecj:4.6.1'
testCompileOnly 'org.jetbrains:annotations:23.0.0'
}
......
......@@ -20,7 +20,8 @@ dependencies {
testRuntimeOnly(project(':jadx-plugins:jadx-java-input'))
testRuntimeOnly(project(':jadx-plugins:jadx-raung-input'))
testImplementation('tools.profiler:async-profiler:1.8.3')
testImplementation 'org.eclipse.jdt:ecj:3.28.0'
testImplementation 'tools.profiler:async-profiler:1.8.3'
}
test {
......
......@@ -65,7 +65,6 @@ import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
public abstract class IntegrationTest extends TestUtils {
......@@ -436,9 +435,10 @@ public abstract class IntegrationTest extends TestUtils {
return;
}
try {
// TODO: eclipse uses files or compilation units providers added in Java 9
compilerOptions.setUseEclipseCompiler(false);
decompiledCompiler = new TestCompiler(compilerOptions);
boolean result = decompiledCompiler.compileNodes(clsList);
assertTrue(result, "Compilation failed");
decompiledCompiler.compileNodes(clsList);
System.out.println("Compilation: PASSED");
} catch (Exception e) {
fail(e);
......@@ -514,7 +514,8 @@ public abstract class IntegrationTest extends TestUtils {
this.compilerOptions.setIncludeDebugInfo(false);
}
protected void useEclipseCompiler() {
public void useEclipseCompiler() {
Assumptions.assumeTrue(JavaUtils.checkJavaVersion(11), "eclipse compiler library using Java 11");
this.compilerOptions.setUseEclipseCompiler(true);
}
......
package jadx.tests.api.compiler;
import javax.tools.JavaCompiler;
public class EclipseCompilerUtils {
public static JavaCompiler newInstance() {
if (!JavaUtils.checkJavaVersion(11)) {
throw new IllegalArgumentException("Eclipse compiler build with Java 11");
}
try {
Class<?> ecjCls = Class.forName("org.eclipse.jdt.internal.compiler.tool.EclipseCompiler");
return (JavaCompiler) ecjCls.getConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException("Failed to init Eclipse compiler", e);
}
}
}
......@@ -3,20 +3,22 @@ package jadx.tests.api.compiler;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import javax.tools.DiagnosticListener;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
import org.jetbrains.annotations.NotNull;
import jadx.core.dex.nodes.ClassNode;
......@@ -38,7 +40,7 @@ public class TestCompiler implements Closeable {
+ "current: " + JavaUtils.JAVA_VERSION_INT + ", required: " + javaVersion);
}
if (options.isUseEclipseCompiler()) {
compiler = new EclipseCompiler();
compiler = EclipseCompilerUtils.newInstance();
} else {
compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
......@@ -49,11 +51,7 @@ public class TestCompiler implements Closeable {
}
public List<File> compileFiles(List<File> sourceFiles, Path outTmp) throws IOException {
List<JavaFileObject> jfObjects = fileManager.getJavaFileObjectsFromFiles(sourceFiles);
boolean success = compile(jfObjects);
if (!success) {
return Collections.emptyList();
}
compile(fileManager.getJavaFileObjectsFromFiles(sourceFiles));
List<File> files = new ArrayList<>();
for (JavaClassObject classObject : fileManager.getClassLoader().getClassObjects()) {
Path path = outTmp.resolve(classObject.getName().replace('.', '/') + ".class");
......@@ -64,15 +62,15 @@ public class TestCompiler implements Closeable {
return files;
}
public boolean compileNodes(List<ClassNode> clsNodeList) {
public void compileNodes(List<ClassNode> clsNodeList) {
List<JavaFileObject> jfObjects = new ArrayList<>(clsNodeList.size());
for (ClassNode clsNode : clsNodeList) {
jfObjects.add(new StringJavaFileObject(clsNode.getFullName(), clsNode.getCode().getCodeStr()));
}
return compile(jfObjects);
compile(jfObjects);
}
private boolean compile(List<JavaFileObject> jfObjects) {
private void compile(List<JavaFileObject> jfObjects) {
List<String> arguments = new ArrayList<>();
arguments.add(options.isIncludeDebugInfo() ? "-g" : "-g:none");
int javaVersion = options.getJavaVersion();
......@@ -83,8 +81,13 @@ public class TestCompiler implements Closeable {
arguments.add(javaVerStr);
arguments.addAll(options.getArguments());
CompilationTask compilerTask = compiler.getTask(null, fileManager, null, arguments, null, jfObjects);
return Boolean.TRUE.equals(compilerTask.call());
DiagnosticListener<? super JavaFileObject> diagnostic =
diagObj -> System.out.println("Compiler diagnostic: " + diagObj.getMessage(Locale.ROOT));
Writer out = new PrintWriter(System.out);
CompilationTask compilerTask = compiler.getTask(out, fileManager, diagnostic, arguments, null, jfObjects);
if (Boolean.FALSE.equals(compilerTask.call())) {
throw new RuntimeException("Compilation failed");
}
}
private ClassLoader getClassLoader() {
......
......@@ -2,6 +2,7 @@ package jadx.tests.api.extensions.profiles;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.stream.Stream;
......@@ -35,7 +36,13 @@ public class JadxTestProfilesExtension implements TestTemplateInvocationContextP
Preconditions.condition(!testAnnAdded, "@Test annotation should be removed");
TestWithProfiles profilesAnn = AnnotationUtils.findAnnotation(testMethod, TestWithProfiles.class).get();
return Stream.of(profilesAnn.value())
EnumSet<TestProfile> profilesSet = EnumSet.noneOf(TestProfile.class);
Collections.addAll(profilesSet, profilesAnn.value());
if (profilesSet.contains(TestProfile.ALL)) {
Collections.addAll(profilesSet, TestProfile.values());
}
profilesSet.remove(TestProfile.ALL);
return profilesSet.stream()
.sorted()
.map(RunWithProfile::new);
}
......
......@@ -20,7 +20,18 @@ public enum TestProfile implements Consumer<IntegrationTest> {
JAVA11("java-11", test -> {
test.useTargetJavaVersion(11);
test.useJavaInput();
});
}),
ECJ_DX_J8("ecj-dx-j8", test -> {
test.useEclipseCompiler();
test.useTargetJavaVersion(8);
test.useDexInput();
}),
ECJ_J8("ecj-j8", test -> {
test.useEclipseCompiler();
test.useTargetJavaVersion(8);
test.useJavaInput();
}),
ALL("all", null);
private final String description;
private final Consumer<IntegrationTest> setup;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册