Commit 7f0815a7 authored by Skylot's avatar Skylot

core tests: add option for compile test without debug info

parent 68f5565b
......@@ -3,9 +3,9 @@ package jadx.core.clsp;
import jadx.core.dex.info.ClassInfo;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.RootNode;
import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.DecodeException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.core.utils.files.FileUtils;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
......@@ -102,7 +102,7 @@ public class ClsSet {
}
void save(File output) throws IOException {
Utils.makeDirsForFile(output);
FileUtils.makeDirsForFile(output);
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(output));
try {
......
......@@ -2,7 +2,7 @@ package jadx.core.codegen;
import jadx.api.CodePosition;
import jadx.core.dex.attributes.nodes.LineAttrNode;
import jadx.core.utils.Utils;
import jadx.core.utils.files.FileUtils;
import java.io.File;
import java.io.PrintWriter;
......@@ -288,7 +288,7 @@ public class CodeWriter {
PrintWriter out = null;
try {
Utils.makeDirsForFile(file);
FileUtils.makeDirsForFile(file);
out = new PrintWriter(file, "UTF-8");
String code = buf.toString();
code = removeFirstEmptyLine(code);
......
package jadx.core.utils;
import jadx.core.utils.exceptions.JadxRuntimeException;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Iterator;
......@@ -93,15 +90,4 @@ public class Utils {
throwable.printStackTrace(pw);
return sw.getBuffer().toString();
}
public static void makeDirsForFile(File file) {
File dir = file.getParentFile();
if (dir != null && !dir.exists()) {
// if directory already created in other thread mkdirs will return false,
// so check dir existence again
if (!dir.mkdirs() && !dir.exists()) {
throw new JadxRuntimeException("Can't create directory " + dir);
}
}
}
}
package jadx.core.utils.files;
import jadx.core.utils.exceptions.JadxRuntimeException;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
......@@ -35,4 +37,15 @@ public class FileUtils {
}
}
}
public static void makeDirsForFile(File file) {
File dir = file.getParentFile();
if (dir != null && !dir.exists()) {
// if directory already created in other thread mkdirs will return false,
// so check dir existence again
if (!dir.mkdirs() && !dir.exists()) {
throw new JadxRuntimeException("Can't create directory " + dir);
}
}
}
}
......@@ -13,6 +13,7 @@ import jadx.core.dex.visitors.IDexTreeVisitor;
import jadx.core.utils.exceptions.JadxException;
import jadx.core.utils.files.FileUtils;
import jadx.tests.api.compiler.DynamicCompiler;
import jadx.tests.api.compiler.StaticCompiler;
import jadx.tests.api.utils.TestUtils;
import java.io.File;
......@@ -24,12 +25,15 @@ import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.jar.JarOutputStream;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
......@@ -37,10 +41,15 @@ import static org.junit.Assert.fail;
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;
protected boolean outputCFG = false;
protected boolean isFallback = false;
protected boolean deleteTmpFiles = true;
protected boolean withDebugInfo = true;
protected String outDir = "test-out-tmp";
protected boolean compile = true;
......@@ -183,7 +192,7 @@ public abstract class IntegrationTest extends TestUtils {
try {
dynamicCompiler = new DynamicCompiler(cls);
boolean result = dynamicCompiler.compile();
assertTrue("Compilation failed on code: \n\n" + cls.getCode() + "\n", result);
assertTrue("Compilation failed", result);
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
......@@ -218,7 +227,16 @@ public abstract class IntegrationTest extends TestUtils {
public File getJarForClass(Class<?> cls) throws IOException {
String path = cls.getPackage().getName().replace('.', '/');
List<File> list = getClassFilesWithInners(cls);
List<File> list;
if (!withDebugInfo) {
list = compileClass(cls);
} else {
list = getClassFilesWithInners(cls);
if (list.isEmpty()) {
list = compileClass(cls);
}
}
assertNotEquals("File list is empty", 0, list.size());
File temp = createTempFile(".jar");
JarOutputStream jo = new JarOutputStream(new FileOutputStream(temp));
......@@ -244,6 +262,18 @@ public abstract class IntegrationTest extends TestUtils {
return temp;
}
private static File createTempDir(String prefix) throws IOException {
File baseDir = new File(System.getProperty("java.io.tmpdir"));
String baseName = prefix + "-" + System.nanoTime();
for (int counter = 1; counter < 1000; counter++) {
File tempDir = new File(baseDir, baseName + counter);
if (tempDir.mkdir()) {
return tempDir;
}
}
throw new IOException("Failed to create temp directory");
}
private List<File> getClassFilesWithInners(Class<?> cls) {
List<File> list = new ArrayList<File>();
String pkgName = cls.getPackage().getName();
......@@ -266,6 +296,39 @@ public abstract class IntegrationTest extends TestUtils {
return list;
}
private List<File> compileClass(Class<?> cls) throws IOException {
String fileName = cls.getName();
int end = fileName.indexOf('$');
if (end != -1) {
fileName = fileName.substring(0, end);
}
fileName = fileName.replace('.', '/') + ".java";
File file = new File(TEST_DIRECTORY, fileName);
if (!file.exists()) {
file = new File(TEST_DIRECTORY2, fileName);
}
assertTrue("Test source file not found: " + fileName, file.exists());
File outTmp = createTempDir("jadx-tmp-classes");
outTmp.deleteOnExit();
List<File> files = StaticCompiler.compile(Arrays.asList(file), outTmp, withDebugInfo);
String filter = outTmp.getAbsolutePath() + File.separator + cls.getName().replace('.', '/');
Iterator<File> iterator = files.iterator();
while (iterator.hasNext()) {
File next = iterator.next();
if (!next.getAbsolutePath().startsWith(filter)) {
iterator.remove();
} else {
next.deleteOnExit();
}
}
return files;
}
public void noDebugInfo() {
this.withDebugInfo = false;
}
// Try to make test class compilable
@Deprecated
public void disableCompilation() {
......
package jadx.tests.api.compiler;
import jadx.core.utils.files.FileUtils;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static javax.tools.JavaCompiler.CompilationTask;
public class StaticCompiler {
private static final List<String> COMMON_ARGS = Arrays.asList("-source 1.6 -target 1.6".split(" "));
public static List<File> compile(List<File> files, File outDir, boolean includeDebugInfo) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(files);
StaticFileManager staticFileManager = new StaticFileManager(fileManager, outDir);
List<String> options = new ArrayList<String>();
options.add(includeDebugInfo ? "-g" : "-g:none");
options.addAll(COMMON_ARGS);
CompilationTask task = compiler.getTask(null, staticFileManager, null, options, null, compilationUnits);
Boolean result = task.call();
fileManager.close();
if (Boolean.TRUE.equals(result)) {
return staticFileManager.outputFiles();
}
return Collections.emptyList();
}
private static class StaticFileManager extends ForwardingJavaFileManager<StandardJavaFileManager> {
private List<File> files = new ArrayList<File>();
private File outDir;
protected StaticFileManager(StandardJavaFileManager fileManager, File outDir) {
super(fileManager);
this.outDir = outDir;
}
@Override
public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling) throws IOException {
if (kind == JavaFileObject.Kind.CLASS) {
File file = new File(outDir, className.replace('.', '/') + ".class");
files.add(file);
return new ClassFileObject(file, kind);
}
throw new UnsupportedOperationException("Can't save location with kind: " + kind);
}
public List<File> outputFiles() {
return files;
}
}
private static class ClassFileObject extends SimpleJavaFileObject {
private File file;
protected ClassFileObject(File file, Kind kind) {
super(URI.create("file://" + file.getAbsolutePath()), kind);
this.file = file;
}
@Override
public OutputStream openOutputStream() throws IOException {
FileUtils.makeDirsForFile(file);
return new FileOutputStream(file);
}
}
}
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