Work with File instead of Strings when specifying output als classpath

This commit is contained in:
JanUlrich 2020-01-17 16:06:51 +01:00
parent 5500180c6b
commit a6287b1551
11 changed files with 74 additions and 30 deletions

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@ -88,7 +89,7 @@ public class BytecodeGen implements ASTVisitor {
private Collection<ResultSet> listOfResultSets; private Collection<ResultSet> listOfResultSets;
private ResultSet resultSet; private ResultSet resultSet;
private SourceFile sf; private SourceFile sf;
private String path; private File path;
private Optional<Constructor> fieldInitializations; private Optional<Constructor> fieldInitializations;
@ -122,7 +123,7 @@ public class BytecodeGen implements ASTVisitor {
private final ClassLoader classLoader; private final ClassLoader classLoader;
public BytecodeGen(HashMap<JavaClassName, byte[]> classFiles, Collection<ResultSet> listOfResultSets, List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles, SourceFile sf, public BytecodeGen(HashMap<JavaClassName, byte[]> classFiles, Collection<ResultSet> listOfResultSets, List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles, SourceFile sf,
String path, ClassLoader classLoader) { File path, ClassLoader classLoader) {
this.classFiles = classFiles; this.classFiles = classFiles;
this.listOfResultSets = listOfResultSets; this.listOfResultSets = listOfResultSets;
this.simplifyResultsForAllSourceFiles = simplifyResultsForAllSourceFiles; this.simplifyResultsForAllSourceFiles = simplifyResultsForAllSourceFiles;

View File

@ -57,7 +57,7 @@ public class BytecodeGenMethod implements StatementVisitor {
private HashMap<String, String> genericsAndBounds; private HashMap<String, String> genericsAndBounds;
public boolean isBinaryExp = false; public boolean isBinaryExp = false;
private String superClass; private String superClass;
private String path; private File path;
private SourceFile sf; private SourceFile sf;
private IStatement statement = null; private IStatement statement = null;
private boolean isReturnStmt = false; private boolean isReturnStmt = false;
@ -85,7 +85,7 @@ public class BytecodeGenMethod implements StatementVisitor {
public BytecodeGenMethod(JavaClassName className, String superClass, ResultSet resultSet, Method m, MethodVisitor mv, public BytecodeGenMethod(JavaClassName className, String superClass, ResultSet resultSet, Method m, MethodVisitor mv,
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod, HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
HashMap<String, String> genericsAndBounds, boolean isInterface, HashMap<JavaClassName, byte[]> classFiles, HashMap<String, String> genericsAndBounds, boolean isInterface, HashMap<JavaClassName, byte[]> classFiles,
SourceFile sf, String path, Block block, int constructorPos, ClassLoader classLoader) { SourceFile sf, File path, Block block, int constructorPos, ClassLoader classLoader) {
this.className = className; this.className = className;
this.superClass = superClass; this.superClass = superClass;
@ -111,7 +111,7 @@ public class BytecodeGenMethod implements StatementVisitor {
public BytecodeGenMethod(JavaClassName className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv, public BytecodeGenMethod(JavaClassName className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv,
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod, HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
HashMap<String, String> genericsAndBounds, boolean isInterface, HashMap<JavaClassName, byte[]> classFiles, SourceFile sf,String path, ClassLoader classLoader) { HashMap<String, String> genericsAndBounds, boolean isInterface, HashMap<JavaClassName, byte[]> classFiles, SourceFile sf,File path, ClassLoader classLoader) {
this.className = className; this.className = className;
this.superClass = superClass; this.superClass = superClass;
@ -134,7 +134,7 @@ public class BytecodeGenMethod implements StatementVisitor {
} }
public BytecodeGenMethod(JavaClassName className, ClassWriter cw, LambdaExpression lambdaExpression, ArrayList<String> usedVars, ResultSet resultSet, MethodVisitor mv, public BytecodeGenMethod(JavaClassName className, ClassWriter cw, LambdaExpression lambdaExpression, ArrayList<String> usedVars, ResultSet resultSet, MethodVisitor mv,
int indexOfFirstParamLam, boolean isInterface, HashMap<JavaClassName, byte[]> classFiles, String path, int lamCounter, SourceFile sf,HashMap<String, String> genericsAndBoundsMethod, int indexOfFirstParamLam, boolean isInterface, HashMap<JavaClassName, byte[]> classFiles, File path, int lamCounter, SourceFile sf,HashMap<String, String> genericsAndBoundsMethod,
HashMap<String, String> genericsAndBounds, ClassLoader classLoader) { HashMap<String, String> genericsAndBounds, ClassLoader classLoader) {
this.className = className; this.className = className;
this.cw = cw; this.cw = cw;
@ -816,7 +816,7 @@ public class BytecodeGenMethod implements StatementVisitor {
// mDesc = helper.generateBCForFunN(methCallType,typesOfParams); // mDesc = helper.generateBCForFunN(methCallType,typesOfParams);
}else { }else {
try { try {
cLoader2 = new DirectoryClassLoader(new File(path), classLoader); cLoader2 = new DirectoryClassLoader(path, classLoader);
java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods(); java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods();
System.out.println("Methods of " + receiverName + " "); System.out.println("Methods of " + receiverName + " ");
for(int i = 0; i<methods.length; i++) { for(int i = 0; i<methods.length; i++) {

View File

@ -20,7 +20,7 @@ import java.util.Iterator;
public class ByteCodeForFunNGenerator { public class ByteCodeForFunNGenerator {
public static void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc, String path) { public static void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc, File path) {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
SignatureWriter methSig = new SignatureWriter(); SignatureWriter methSig = new SignatureWriter();
@ -46,7 +46,7 @@ public class ByteCodeForFunNGenerator {
writeClassFile(classWriter.toByteArray(), name, path); writeClassFile(classWriter.toByteArray(), name, path);
} }
public static void generateBCForFunN(ArgumentList argumentList, String methDesc, String path) { public static void generateBCForFunN(ArgumentList argumentList, String methDesc, File path) {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
SignatureWriter methSig = new SignatureWriter(); SignatureWriter methSig = new SignatureWriter();
@ -75,12 +75,12 @@ public class ByteCodeForFunNGenerator {
} }
public static void writeClassFile(byte[] bytecode, String name, String path) { public static void writeClassFile(byte[] bytecode, String name, File path) {
FileOutputStream output; FileOutputStream output;
try { try {
System.out.println("generating " + name + ".class file..."); System.out.println("generating " + name + ".class file...");
output = new FileOutputStream( output = new FileOutputStream(
new File(path + name + CONSTANTS.EXTENSIONCLASS)); new File(path , name + CONSTANTS.EXTENSIONCLASS));
output.write(bytecode); output.write(bytecode);
output.close(); output.close();
System.out.println(name + ".class file generated"); System.out.println(name + ".class file generated");

View File

@ -16,6 +16,7 @@ import javassist.NotFoundException;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import java.io.File;
import java.util.*; import java.util.*;
/** /**
@ -26,7 +27,7 @@ public class MethodCallHelper {
private MethodCall methCall; private MethodCall methCall;
private SourceFile sourceFile; private SourceFile sourceFile;
private ResultSet resultSet; private ResultSet resultSet;
private String path; private File path;
/** /**
* @param methCall * @param methCall
@ -34,7 +35,7 @@ public class MethodCallHelper {
* @param resultSet * @param resultSet
* @param path TODO * @param path TODO
*/ */
public MethodCallHelper(MethodCall methCall, SourceFile sourceFile, ResultSet resultSet, String path) { public MethodCallHelper(MethodCall methCall, SourceFile sourceFile, ResultSet resultSet, File path) {
this.methCall = methCall; this.methCall = methCall;
this.sourceFile = sourceFile; this.sourceFile = sourceFile;
this.resultSet = resultSet; this.resultSet = resultSet;

View File

@ -740,7 +740,7 @@ public class JavaTXCompiler {
return ret; return ret;
} }
public void generateBytecodForFile(String path, HashMap<JavaClassName, byte[]> classFiles, SourceFile sf, public void generateBytecodForFile(File path, HashMap<JavaClassName, byte[]> classFiles, SourceFile sf,
List<ResultSet> typeinferenceResult) throws IOException { List<ResultSet> typeinferenceResult) throws IOException {
try { try {
List<GenericGenratorResultForSourceFile> genericResults = getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult); List<GenericGenratorResultForSourceFile> genericResults = getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult);
@ -780,13 +780,23 @@ public class JavaTXCompiler {
} }
public void generateBytecode() throws ClassNotFoundException, IOException, BytecodeGeneratorError { public void generateBytecode() throws ClassNotFoundException, IOException, BytecodeGeneratorError {
generateBytecode(null); generateBytecode((File) null);
} }
/** /**
* @param path - can be null, then class file output is in the same directory as the parsed source files * @param path - can be null, then class file output is in the same directory as the parsed source files
*/ */
public void generateBytecode(String path) throws ClassNotFoundException, IOException, BytecodeGeneratorError { public void generateBytecode(String path) throws ClassNotFoundException, IOException, BytecodeGeneratorError {
if(path != null)
generateBytecode(new File(path));
else
generateBytecode();
}
/**
* @param path - can be null, then class file output is in the same directory as the parsed source files
*/
public void generateBytecode(File path) throws ClassNotFoundException, IOException, BytecodeGeneratorError {
List<ResultSet> typeinferenceResult = this.typeInference(); List<ResultSet> typeinferenceResult = this.typeInference();
List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles = getGeneratedGenericResultsForAllSourceFiles( List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles = getGeneratedGenericResultsForAllSourceFiles(
typeinferenceResult); typeinferenceResult);
@ -799,16 +809,16 @@ public class JavaTXCompiler {
* @param simplifyResultsForAllSourceFiles * @param simplifyResultsForAllSourceFiles
* @throws IOException * @throws IOException
*/ */
public void generateBytecode(String outputPath, List<ResultSet> typeinferenceResult, public void generateBytecode(File outputPath, List<ResultSet> typeinferenceResult,
List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles) throws IOException { List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles) throws IOException {
for (File f : sourceFiles.keySet()) { for (File f : sourceFiles.keySet()) {
HashMap<JavaClassName, byte[]> classFiles = new HashMap<>(); HashMap<JavaClassName, byte[]> classFiles = new HashMap<>();
SourceFile sf = sourceFiles.get(f); SourceFile sf = sourceFiles.get(f);
String path; File path;
if(outputPath == null){ if(outputPath == null){
path = f.getParent(); //Set path to path of the parsed .jav file path = f.getParentFile(); //Set path to path of the parsed .jav file
}else{ }else{
path = outputPath + sf.getPkgName().replace(".","/"); //add package path to root path path = new File(outputPath ,sf.getPkgName().replace(".","/")); //add package path to root path
} }
BytecodeGen bytecodeGen = new BytecodeGen(classFiles, typeinferenceResult, simplifyResultsForAllSourceFiles, BytecodeGen bytecodeGen = new BytecodeGen(classFiles, typeinferenceResult, simplifyResultsForAllSourceFiles,
sf, path, classLoader); sf, path, classLoader);
@ -817,15 +827,15 @@ public class JavaTXCompiler {
} }
} }
private void writeClassFile(HashMap<JavaClassName, byte[]> classFiles, String path) throws IOException { private void writeClassFile(HashMap<JavaClassName, byte[]> classFiles, File path) throws IOException {
FileOutputStream output; FileOutputStream output;
for (JavaClassName name : classFiles.keySet()) { for (JavaClassName name : classFiles.keySet()) {
byte[] bytecode = classFiles.get(name); byte[] bytecode = classFiles.get(name);
System.out.println("generating " + name + ".class file ..."); System.out.println("generating " + name + ".class file ...");
// output = new FileOutputStream(new File(System.getProperty("user.dir") + // output = new FileOutputStream(new File(System.getProperty("user.dir") +
// "/testBytecode/generatedBC/" +name+".class")); // "/testBytecode/generatedBC/" +name+".class"));
File outputFile = new File(path + File.separator + name.getClassName() + ".class"); File outputFile = new File(path, name.getClassName() + ".class");
outputFile.getParentFile().mkdirs(); outputFile.getAbsoluteFile().getParentFile().mkdirs();
output = new FileOutputStream(outputFile); output = new FileOutputStream(outputFile);
output.write(bytecode); output.write(bytecode);
output.close(); output.close();

View File

@ -74,7 +74,7 @@ public class CompilationEnvironment {
List<Class> ret = new ArrayList<>(); List<Class> ret = new ArrayList<>();
String packageName = getPackageName(JavaTXParser.parse(forSourceFile)); String packageName = getPackageName(JavaTXParser.parse(forSourceFile));
//Set classLoader to include default package for this specific source file //Set classLoader to include default package for this specific source file
File dir = new File(forSourceFile.getParent()); File dir = new File(forSourceFile.getAbsoluteFile().getParent());
String dirPath = dir.toString() + "/"; String dirPath = dir.toString() + "/";
if(packageName.length()>0)dirPath = dirPath.substring(0,dirPath.length() - packageName.length()); if(packageName.length()>0)dirPath = dirPath.substring(0,dirPath.length() - packageName.length());
String path = dirPath; String path = dirPath;

View File

@ -35,7 +35,7 @@ public class OLTest {
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"; pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
List<ResultSet> typeinferenceResult = compiler.typeInference(); List<ResultSet> typeinferenceResult = compiler.typeInference();
List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles = compiler.getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult); List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles = compiler.getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult);
compiler.generateBytecode(pathToClassFile,typeinferenceResult,simplifyResultsForAllSourceFiles); compiler.generateBytecode(new File(pathToClassFile),typeinferenceResult,simplifyResultsForAllSourceFiles);
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("OL"); classToTest = loader.loadClass("OL");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); instanceOfClass = classToTest.getDeclaredConstructor().newInstance();

View File

@ -21,7 +21,7 @@ public class Bytecode extends TestCase {
if(f.exists() && !f.isDirectory()) { if(f.exists() && !f.isDirectory()) {
f.delete(); f.delete();
} }
compiler.generateBytecode(null); compiler.generateBytecode();
f = new File(rootDirectory + "de/test/TestClass.class"); f = new File(rootDirectory + "de/test/TestClass.class");
assertTrue(f.exists()); assertTrue(f.exists());

View File

@ -39,6 +39,38 @@ public class ConsoleInterfaceTest extends TestCase {
assertTrue(f.exists()); assertTrue(f.exists());
} }
@Test
public void testCpNotEndsWithSlash() throws Exception {
JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"/de/test/ToImport.jav"));
compiler.typeInference();
compiler.generateBytecode(rootDirectory + "output/");
File f = new File(rootDirectory + "output/de/test/ToImport.class");
assertTrue(f.exists());
f = new File(rootDirectory + "de/test/ImportTest.class");
if(f.exists() && !f.isDirectory()) {
f.delete();
}
ConsoleInterface.main(new String[]{"-cp", rootDirectory + "de/test/output" , rootDirectory + "de/test/ImportTest.jav"});
f = new File(rootDirectory + "de/test/ImportTest.class");
assertTrue(f.exists());
}
@Test
public void testOutputDirNotEndsWithSlash() throws Exception {
File f = new File(rootDirectory + "de/test/output/de/test/TestClass.class");
if(f.exists() && !f.isDirectory()) {
f.delete();
}
ConsoleInterface.main(new String[]{"-d", rootDirectory + "de/test/output" ,rootDirectory + "de/test/TestClass.jav"});
f = new File(rootDirectory + "de/test/output/de/test/TestClass.class");
assertTrue(f.exists());
}
@Test @Test
public void testCompileSingleJavFileWithClassPath() throws Exception { public void testCompileSingleJavFileWithClassPath() throws Exception {
JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"/de/test/ToImport.jav")); JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"/de/test/ToImport.jav"));

View File

@ -27,7 +27,7 @@ public class ImportTest extends TestCase {
compiler = new JavaTXCompiler(new File(rootDirectory+"ToImport.jav")); compiler = new JavaTXCompiler(new File(rootDirectory+"ToImport.jav"));
compiler.typeInference(); compiler.typeInference();
compiler.generateBytecode(null); compiler.generateBytecode();
f = new File(rootDirectory + "ToImport.class"); f = new File(rootDirectory + "ToImport.class");
assertTrue(f.exists()); assertTrue(f.exists());
@ -69,7 +69,7 @@ public class ImportTest extends TestCase {
if(f.exists() && !f.isDirectory()) { if(f.exists() && !f.isDirectory()) {
f.delete(); f.delete();
} }
compiler.generateBytecode(null); compiler.generateBytecode();
f = new File(rootDirectory + "ImportTest.class"); f = new File(rootDirectory + "ImportTest.class");
assertTrue(f.exists()); assertTrue(f.exists());
} }
@ -85,7 +85,7 @@ public class ImportTest extends TestCase {
if(f.exists() && !f.isDirectory()) { if(f.exists() && !f.isDirectory()) {
f.delete(); f.delete();
} }
compiler.generateBytecode(null); compiler.generateBytecode();
f = new File(rootDirectory + "ImportTest2.class"); f = new File(rootDirectory + "ImportTest2.class");
assertTrue(f.exists()); assertTrue(f.exists());
} }
@ -99,7 +99,7 @@ public class ImportTest extends TestCase {
if(f.exists() && !f.isDirectory()) { if(f.exists() && !f.isDirectory()) {
f.delete(); f.delete();
} }
compiler.generateBytecode(null); compiler.generateBytecode();
f = new File(rootDirectory + "ImportTestDefault.class"); f = new File(rootDirectory + "ImportTestDefault.class");
assertTrue(f.exists()); assertTrue(f.exists());
} }

View File

@ -37,5 +37,5 @@ public class VectorAdd {
// var y; // var y;
// x.add(y); // x.add(y);
// z = x; // z = x;
} // }
} }