diff --git a/.gitignore b/.gitignore index a897efd8..fe551a27 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,6 @@ bin # manually/ + +logFiles/** +!logFiles/.gitkeep diff --git a/abgabeprotokoll.md b/abgabeprotokoll.md new file mode 100644 index 00000000..db079dab --- /dev/null +++ b/abgabeprotokoll.md @@ -0,0 +1,19 @@ +# JavaTXCompiler Klasse +* Konstruktor hat einen weiteren Parameter +* contextPath + * Arrays aus URLs (file-urls) +* Parameter ist Optional +* wird er gesetzt, so werden Classfiles aus den übergebenen Pfaden geladen + * die übergebenen Pfade müssen dabei die Source-Roots sein + * Beispiel: + `import de.test.Klasse;` + * `Klasse.class` liegt in `output/de/test/Klasse.class` + * dann muss contextpath auf `output` gesetzt werden +* wird der Parameter nicht übergeben, so wird der Sourceroot auf das Verzeichnis gesetzt, in dem der Compiler ausgeführt wird +* dies ist das Verhalten vom javac Compiler + +* generateBytecode - Methode hat neuen Parameter: path +* wird hier null übergeben, so wird die class-File in den gleichen Ordner wie die übergebene .jav File geschrieben +* wird hier ein Pfad übergeben, so gilt dieser als output root. + * Klassen werden in outputRoot/package/name/KlassenName.class geschrieben + diff --git a/logFiles/.gitkeep b/logFiles/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java index 508bd520..5091af5e 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -7,6 +7,7 @@ import java.util.Iterator; import java.util.List; import java.util.Optional; +import de.dhbwstuttgart.parser.scope.JavaClassName; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; @@ -81,7 +82,7 @@ public class BytecodeGen implements ASTVisitor { String type; public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null; - private String className; + private JavaClassName className; private String pkgName; private boolean isInterface; private Collection listOfResultSets; @@ -107,7 +108,7 @@ public class BytecodeGen implements ASTVisitor { HashMap methodParamsAndTypes = new HashMap<>(); byte[] bytecode; - HashMap classFiles; + HashMap classFiles; private final ArrayList methodNameAndParamsT = new ArrayList<>(); private final ArrayList fieldNameAndParamsT = new ArrayList<>(); @@ -118,24 +119,26 @@ public class BytecodeGen implements ASTVisitor { private GenericsGeneratorResultForClass generatedGenerics; private Resolver resolver; + private final ClassLoader classLoader; - public BytecodeGen(HashMap classFiles, Collection listOfResultSets, List simplifyResultsForAllSourceFiles, SourceFile sf, - String path) { + public BytecodeGen(HashMap classFiles, Collection listOfResultSets, List simplifyResultsForAllSourceFiles, SourceFile sf, + String path, ClassLoader classLoader) { this.classFiles = classFiles; this.listOfResultSets = listOfResultSets; this.simplifyResultsForAllSourceFiles = simplifyResultsForAllSourceFiles; this.sf = sf; this.path = path; this.pkgName = sf.getPkgName(); + this.classLoader = classLoader; } @Override public void visit(SourceFile sourceFile) { for (ClassOrInterface cl : sourceFile.getClasses()) { System.out.println("in Class: " + cl.getClassName().toString()); - BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, simplifyResultsForAllSourceFiles, sf, path); + BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, simplifyResultsForAllSourceFiles, sf, path, classLoader); cl.accept(classGen); - classGen.writeClass(cl.getClassName().toString()); + classGen.writeClass(cl.getClassName()); } } @@ -145,22 +148,22 @@ public class BytecodeGen implements ASTVisitor { * * @param name name of the class with which the bytecode is to be associated */ - private void writeClass(String name) { + private void writeClass(JavaClassName name) { bytecode = cw.toByteArray(); classFiles.put(name, bytecode); } - public HashMap getClassFiles() { + public HashMap getClassFiles() { return classFiles; } @Override public void visit(ClassOrInterface classOrInterface) { - className = classOrInterface.getClassName().toString(); + className = classOrInterface.getClassName(); - cw.visitSource(className + ".jav", null); + cw.visitSource(className.getClassName() + ".jav", null); isInterface = (classOrInterface.getModifiers() & 512) == 512; @@ -172,7 +175,7 @@ public class BytecodeGen implements ASTVisitor { // resultSet = listOfResultSets.get(0); boolean isVisited = false; List listOfResultSetsList = new ArrayList<>(listOfResultSets); - generatedGenerics = simplifyResultsForAllSourceFiles.stream().map(sr->sr.getSimplifyResultsByName(pkgName, className)).findFirst().get(); + generatedGenerics = simplifyResultsForAllSourceFiles.stream().map(sr->sr.getSimplifyResultsByName(className)).findFirst().get(); for (int i = 0; i < listOfResultSetsList.size(); i++) { //for (ResultSet rs : listOfResultSets) { superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()); @@ -199,7 +202,7 @@ public class BytecodeGen implements ASTVisitor { System.out.println("Signature: => " + sig); } - cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString(), sig, + cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString().replace(".", "/"), sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null); isVisited = true; @@ -269,7 +272,7 @@ public class BytecodeGen implements ASTVisitor { constructorPos += 1; BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, field, mv, paramsAndLocals, cw, - genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path, block, constructorPos); + genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path, block, constructorPos, classLoader); if (!field.getParameterList().iterator().hasNext() && !(field.block.statements.get(field.block.statements.size() - 1) instanceof ReturnVoid)) { mv.visitInsn(Opcodes.RETURN); @@ -350,7 +353,7 @@ public class BytecodeGen implements ASTVisitor { mv.visitCode(); BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, method, mv, paramsAndLocals, cw, - genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path); + genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path, classLoader); mv.visitMaxs(0, 0); mv.visitEnd(); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index 46caa52b..136dec53 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -15,6 +15,7 @@ import java.util.List; import de.dhbwstuttgart.bytecode.utilities.*; import de.dhbwstuttgart.exceptions.NotImplementedException; +import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr.Operator; import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr.Operation; @@ -45,7 +46,7 @@ public class BytecodeGenMethod implements StatementVisitor { private Method m; private MethodVisitor mv; private HashMap paramsAndLocals = new HashMap<>(); - private String className; + private JavaClassName className; private int lamCounter; private ClassWriter cw; private ResultSet resultSet; @@ -71,16 +72,18 @@ public class BytecodeGenMethod implements StatementVisitor { private boolean isRightSideALambda = false; private KindOfLambda kindOfLambda; - private HashMap classFiles; + private HashMap classFiles; private int constructorPos = 0; private ArrayList varsFunInterface = new ArrayList<>();; + private final ClassLoader classLoader; + // generate bytecode for constructor - public BytecodeGenMethod(String className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv, - HashMap paramsAndLocals, ClassWriter cw, HashMap genericsAndBoundsMethod, - HashMap genericsAndBounds, boolean isInterface, HashMap classFiles, - SourceFile sf,String path, Block block, int constructorPos) { + public BytecodeGenMethod(JavaClassName className, String superClass, ResultSet resultSet, Method m, MethodVisitor mv, + HashMap paramsAndLocals, ClassWriter cw, HashMap genericsAndBoundsMethod, + HashMap genericsAndBounds, boolean isInterface, HashMap classFiles, + SourceFile sf, String path, Block block, int constructorPos, ClassLoader classLoader) { this.className = className; this.superClass = superClass; @@ -98,16 +101,15 @@ public class BytecodeGenMethod implements StatementVisitor { this.path = path; this.lamCounter = -1; this.constructorPos = constructorPos; + this.classLoader = classLoader; if(block != null) this.blockFieldInit = block; this.m.block.accept(this); - - } - public BytecodeGenMethod(String className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv, + public BytecodeGenMethod(JavaClassName className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv, HashMap paramsAndLocals, ClassWriter cw, HashMap genericsAndBoundsMethod, - HashMap genericsAndBounds, boolean isInterface, HashMap classFiles, SourceFile sf,String path) { + HashMap genericsAndBounds, boolean isInterface, HashMap classFiles, SourceFile sf,String path, ClassLoader classLoader) { this.className = className; this.superClass = superClass; @@ -124,14 +126,14 @@ public class BytecodeGenMethod implements StatementVisitor { this.sf = sf; this.path = path; this.lamCounter = -1; + this.classLoader = classLoader; if (!isInterface) this.m.block.accept(this); - } - public BytecodeGenMethod(String className, ClassWriter cw, LambdaExpression lambdaExpression, ArrayList usedVars, ResultSet resultSet, MethodVisitor mv, - int indexOfFirstParamLam, boolean isInterface, HashMap classFiles, String path, int lamCounter, SourceFile sf,HashMap genericsAndBoundsMethod, - HashMap genericsAndBounds) { + public BytecodeGenMethod(JavaClassName className, ClassWriter cw, LambdaExpression lambdaExpression, ArrayList usedVars, ResultSet resultSet, MethodVisitor mv, + int indexOfFirstParamLam, boolean isInterface, HashMap classFiles, String path, int lamCounter, SourceFile sf,HashMap genericsAndBoundsMethod, + HashMap genericsAndBounds, ClassLoader classLoader) { this.className = className; this.cw = cw; this.resultSet = resultSet; @@ -144,6 +146,7 @@ public class BytecodeGenMethod implements StatementVisitor { this.sf = sf; this.genericsAndBoundsMethod = genericsAndBoundsMethod; this.genericsAndBounds = genericsAndBounds; + this.classLoader = classLoader; Iterator itr = lambdaExpression.params.iterator(); int i = indexOfFirstParamLam; @@ -622,7 +625,7 @@ public class BytecodeGenMethod implements StatementVisitor { } String newDesc = addUsedVarsToDesugaredMethodDescriptor(lamDesc); // first check if capturing lambda then invokestatic or invokespecial - Handle arg2 = new Handle(staticOrSpecial, this.className, desugaredMethodName, newDesc, false); + Handle arg2 = new Handle(staticOrSpecial, this.className.getClassName(), desugaredMethodName, newDesc, false); // Descriptor of functional interface methode SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType()); // Desc: (this/nothing)TargetType @@ -636,7 +639,7 @@ public class BytecodeGenMethod implements StatementVisitor { new BytecodeGenMethod(className, cw,lambdaExpression, usedVars,this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface, classFiles,this.path, lamCounter, sf, genericsAndBoundsMethod, - genericsAndBounds); + genericsAndBounds, classLoader); mvLambdaBody.visitMaxs(0, 0); mvLambdaBody.visitEnd(); @@ -756,7 +759,7 @@ public class BytecodeGenMethod implements StatementVisitor { MethodCallHelper helper = new MethodCallHelper(methodCall, sf, resultSet, path); - ClassLoader cLoader = ClassLoader.getSystemClassLoader(); + ClassLoader cLoader = this.classLoader; // This will be used if the class is not standard class (not in API) ClassLoader cLoader2; @@ -797,7 +800,7 @@ public class BytecodeGenMethod implements StatementVisitor { } if(methodRefl == null) { - boolean toCreate = !receiverName.equals(className) && helper.isInCurrPkg(clazz); + boolean toCreate = !receiverName.equals(className.getClassName()) && helper.isInCurrPkg(clazz); if(toCreate) { try { mDesc = helper.getDesc(clazz); @@ -811,7 +814,7 @@ public class BytecodeGenMethod implements StatementVisitor { // mDesc = helper.generateBCForFunN(methCallType,typesOfParams); }else { try { - cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)}); + cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)}, classLoader); java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods(); System.out.println("Methods of " + receiverName + " "); for(int i = 0; i argListMethCall = new LinkedList<>(); String receiverRefl=""; - if(methodRefl == null && receiverName.equals(className)) { + if(methodRefl == null && receiverName.equals(className.getClassName())) { MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(), receiverName, genericsAndBoundsMethod, genericsAndBounds); mDesc = method.accept(new DescriptorToString(resultSet)); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/genericsGenerator/GeneratedGenericsFinder.java b/src/main/java/de/dhbwstuttgart/bytecode/genericsGenerator/GeneratedGenericsFinder.java index 5e473ebe..ba55c4c7 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/genericsGenerator/GeneratedGenericsFinder.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/genericsGenerator/GeneratedGenericsFinder.java @@ -16,6 +16,7 @@ import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; import de.dhbwstuttgart.bytecode.utilities.MethodUtility; import de.dhbwstuttgart.bytecode.utilities.Resolver; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.ASTVisitor; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.Constructor; @@ -75,7 +76,7 @@ public class GeneratedGenericsFinder implements ASTVisitor { private final List methodNameAndParamsT = new ArrayList<>(); private String pkgName; - private String className; + private JavaClassName className; private Resolver resolver; /** @@ -117,7 +118,7 @@ public class GeneratedGenericsFinder implements ASTVisitor { */ @Override public void visit(ClassOrInterface classOrInterface) { - className = classOrInterface.getClassName().toString(); + className = classOrInterface.getClassName(); List listOfResultSetsList = new ArrayList<>(listOfResultSets); boolean isVisited = false; diff --git a/src/main/java/de/dhbwstuttgart/bytecode/genericsGenerator/GenericsGenerator.java b/src/main/java/de/dhbwstuttgart/bytecode/genericsGenerator/GenericsGenerator.java index a541025c..8e5bd481 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/genericsGenerator/GenericsGenerator.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/genericsGenerator/GenericsGenerator.java @@ -12,6 +12,7 @@ import java.util.Set; import java.util.stream.Collectors; import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.*; +import de.dhbwstuttgart.parser.scope.JavaClassName; import org.objectweb.asm.Type; import de.dhbwstuttgart.bytecode.TPHExtractor; @@ -30,7 +31,7 @@ public class GenericsGenerator { class constraints: tphClass < tphMeth1, tphMeth1 < tphMeth2, tphMeth2 < Object */ - public static GenericsGeneratorResultForClass generateConstraints(final String className, final TPHExtractor tphExtractor, + public static GenericsGeneratorResultForClass generateConstraints(final JavaClassName className, final TPHExtractor tphExtractor, final List tphsClass, final ConstraintsSimplierResult simplifiedConstraints) { List classConstraints = generateConstraintsForClass(tphExtractor, diff --git a/src/main/java/de/dhbwstuttgart/bytecode/genericsGeneratorTypes/GenericGenratorResultForSourceFile.java b/src/main/java/de/dhbwstuttgart/bytecode/genericsGeneratorTypes/GenericGenratorResultForSourceFile.java index 85d0bcbf..f0d11473 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/genericsGeneratorTypes/GenericGenratorResultForSourceFile.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/genericsGeneratorTypes/GenericGenratorResultForSourceFile.java @@ -3,6 +3,8 @@ */ package de.dhbwstuttgart.bytecode.genericsGeneratorTypes; +import de.dhbwstuttgart.parser.scope.JavaClassName; + import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; @@ -37,9 +39,9 @@ public class GenericGenratorResultForSourceFile { genericGeneratorResultForAllClasses.add(sResClass); } - public GenericsGeneratorResultForClass getSimplifyResultsByName(String pkgName, String name) { + public GenericsGeneratorResultForClass getSimplifyResultsByName(JavaClassName name) { - if (this.pkgName.equals(pkgName)) { + if (this.pkgName.equals(name.getPackageName())) { return genericGeneratorResultForAllClasses.stream() .filter(sr -> sr.getClassName().equals(name)) .findAny() diff --git a/src/main/java/de/dhbwstuttgart/bytecode/genericsGeneratorTypes/GenericsGeneratorResultForClass.java b/src/main/java/de/dhbwstuttgart/bytecode/genericsGeneratorTypes/GenericsGeneratorResultForClass.java index d6532ecb..eaeb1f3a 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/genericsGeneratorTypes/GenericsGeneratorResultForClass.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/genericsGeneratorTypes/GenericsGeneratorResultForClass.java @@ -3,6 +3,8 @@ */ package de.dhbwstuttgart.bytecode.genericsGeneratorTypes; +import de.dhbwstuttgart.parser.scope.JavaClassName; + import java.util.Collections; import java.util.List; @@ -11,11 +13,11 @@ import java.util.List; * */ public class GenericsGeneratorResultForClass { - private final String className; + private final JavaClassName className; private final List classConstraints; private final GenericGeneratorResultsForAllMethods methodsAndTheirConstraints; - public GenericsGeneratorResultForClass(String className) { + public GenericsGeneratorResultForClass(JavaClassName className) { this(className, Collections.emptyList(), new GenericGeneratorResultsForAllMethods()); } /** @@ -23,8 +25,8 @@ public class GenericsGeneratorResultForClass { * @param classConstraints * @param methodsAndTheirConstraints */ - public GenericsGeneratorResultForClass(String className, List classConstraints, - GenericGeneratorResultsForAllMethods methodsAndTheirConstraints) { + public GenericsGeneratorResultForClass(JavaClassName className, List classConstraints, + GenericGeneratorResultsForAllMethods methodsAndTheirConstraints) { this.className = className; this.classConstraints = classConstraints; this.methodsAndTheirConstraints = methodsAndTheirConstraints; @@ -33,7 +35,7 @@ public class GenericsGeneratorResultForClass { /** * @return the className */ - public String getClassName() { + public JavaClassName getClassName() { return className; } diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index 5f107ed0..98626fde 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -1,6 +1,7 @@ //PL 2018-12-19: typeInferenceOld nach typeInference uebertragen package de.dhbwstuttgart.core; +import com.google.common.collect.Lists; import de.dhbwstuttgart.bytecode.BytecodeGen; import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError; import de.dhbwstuttgart.bytecode.genericsGenerator.GeneratedGenericsFinder; @@ -41,6 +42,8 @@ import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; +import java.net.URL; +import java.net.URLClassLoader; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -50,24 +53,34 @@ public class JavaTXCompiler { public static JavaTXCompiler INSTANCE; final CompilationEnvironment environment; - Boolean resultmodel = true; + Boolean resultmodel = true; public final Map sourceFiles = new HashMap<>(); Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden soll? public volatile UnifyTaskModel usedTasks = new UnifyTaskModel(); - - public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException { - this(Arrays.asList(sourceFile)); - INSTANCE = this; - } + private final ClassLoader classLoader; + + public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException { + this(Arrays.asList(sourceFile), null); + INSTANCE = this; + } public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException { this(sourceFile); this.log = log; INSTANCE = this; } - - public JavaTXCompiler(List sources) throws IOException, ClassNotFoundException { - environment = new CompilationEnvironment(sources); + + public JavaTXCompiler(List sourceFiles) throws IOException, ClassNotFoundException { + this(sourceFiles, null); + INSTANCE = this; + } + public JavaTXCompiler(List sources, List contextPath) throws IOException, ClassNotFoundException { + if(contextPath == null || contextPath.isEmpty()){ + //When no contextPaths are given, the working directory is the sources root + contextPath = Lists.newArrayList(new URL("file://" + System.getProperty("user.dir"))); + } + classLoader = new URLClassLoader(contextPath.toArray(new URL[0]), ClassLoader.getSystemClassLoader()); + environment = new CompilationEnvironment(sources); for (File s : sources) { sourceFiles.put(s, parse(s)); } @@ -85,7 +98,7 @@ public class JavaTXCompiler { for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) { //TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet ClassOrInterface importedClass = ASTFactory.createClass( - ClassLoader.getSystemClassLoader().loadClass(name.toString())); + classLoader.loadClass(name.toString())); importedClasses.add(importedClass); } allClasses.addAll(importedClasses); @@ -122,7 +135,7 @@ public class JavaTXCompiler { for (JavaClassName name : forSourceFile.getImports()) { // TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet ClassOrInterface importedClass = ASTFactory - .createClass(ClassLoader.getSystemClassLoader().loadClass(name.toString())); + .createClass(classLoader.loadClass(name.toString())); importedClasses.add(importedClass); allClasses.addAll(importedClasses); } @@ -291,7 +304,7 @@ public class JavaTXCompiler { logFile = logFile == null ? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName())) : logFile; - IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile); + IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, classLoader); System.out.println(finiteClosure); urm = new UnifyResultModel(cons, finiteClosure); urm.addUnifyResultListener(resultListener); @@ -459,7 +472,7 @@ public class JavaTXCompiler { // File(System.getProperty("user.dir")+"/src/test/resources/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName())); new FileWriter(new File(System.getProperty("user.dir") + "/logFiles/" + "log_" + sourceFiles.keySet().iterator().next().getName())); - IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile); + IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile, classLoader); System.out.println(finiteClosure); ConstraintSet unifyCons = UnifyTypeFactory.convert(cons); @@ -708,17 +721,17 @@ public class JavaTXCompiler { private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException { CompilationUnitContext tree = JavaTXParser.parse(sourceFile); - SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile), + SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile, classLoader), new GenericsRegistry(null)); - SourceFile ret = generator.convert(tree, environment.packageCrawler); + SourceFile ret = generator.convert(tree, environment.packageCrawler, classLoader); return ret; } - public void generateBytecodForFile(String path, HashMap classFiles, SourceFile sf, + public void generateBytecodForFile(String path, HashMap classFiles, SourceFile sf, List typeinferenceResult) throws IOException { try { List genericResults = getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult); - BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult, genericResults, sf,path); + BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult, genericResults, sf,path, classLoader); bytecodeGen.visit(sf); this.writeClassFile(bytecodeGen.getClassFiles(), path); } catch (ClassNotFoundException e) { @@ -753,7 +766,13 @@ public class JavaTXCompiler { return result; } - // um pfad erweitern + public void generateBytecode() throws ClassNotFoundException, IOException, BytecodeGeneratorError { + generateBytecode(null); + } + + /** + * @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 { List typeinferenceResult = this.typeInference(); List simplifyResultsForAllSourceFiles = getGeneratedGenericResultsForAllSourceFiles( @@ -770,27 +789,30 @@ public class JavaTXCompiler { public void generateBytecode(String path, List typeinferenceResult, List simplifyResultsForAllSourceFiles) throws IOException { for (File f : sourceFiles.keySet()) { - HashMap classFiles = new HashMap<>(); + HashMap classFiles = new HashMap<>(); SourceFile sf = sourceFiles.get(f); BytecodeGen bytecodeGen = new BytecodeGen(classFiles, typeinferenceResult, simplifyResultsForAllSourceFiles, - sf, path); + sf, path, classLoader); bytecodeGen.visit(sf); - String packagePath = sf.getPkgName().replace(".","/"); if(path == null){ - path = f.getPath(); + path = f.getParent(); //Set path to path of the parsed .jav file + }else{ + path += sf.getPkgName().replace(".","/"); //add package path to root path } - writeClassFile(bytecodeGen.getClassFiles(), path + packagePath); + writeClassFile(bytecodeGen.getClassFiles(), path); } } - private void writeClassFile(HashMap classFiles, String path) throws IOException { + private void writeClassFile(HashMap classFiles, String path) throws IOException { FileOutputStream output; - for (String name : classFiles.keySet()) { + for (JavaClassName name : classFiles.keySet()) { byte[] bytecode = classFiles.get(name); System.out.println("generating " + name + ".class file ..."); // output = new FileOutputStream(new File(System.getProperty("user.dir") + // "/testBytecode/generatedBC/" +name+".class")); - output = new FileOutputStream(new File(path + name + ".class")); + File outputFile = new File(path + File.separator + name.getClassName() + ".class"); + outputFile.getParentFile().mkdirs(); + output = new FileOutputStream(outputFile); output.write(bytecode); output.close(); System.out.println(name + ".class file generated"); diff --git a/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java index 3d450183..43196b6f 100644 --- a/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java +++ b/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java @@ -50,7 +50,6 @@ public class CompilationEnvironment { */ //String bootClassPath = System.getProperty("sun.boot.class.path"); // ClassLoader cl = ClassLoader.getPlatformClassLoader(); - ClassLoader cl = ClassLoader.getSystemClassLoader(); String bootClassPath = System.getProperty("java.class.path"); librarys = new ArrayList<>(); for(String path : bootClassPath.split(File.pathSeparator)) { @@ -67,10 +66,10 @@ public class CompilationEnvironment { this.packageCrawler = new PackageCrawler(librarys); } - public JavaClassRegistry getRegistry(File forSourceFile) throws ClassNotFoundException, IOException { + public JavaClassRegistry getRegistry(File forSourceFile, ClassLoader classLoader) throws ClassNotFoundException, IOException { Map allNames; CompilationUnitContext tree = JavaTXParser.parse(forSourceFile); - allNames = GatherNames.getNames(tree, packageCrawler); + allNames = GatherNames.getNames(tree, packageCrawler, classLoader); return new JavaClassRegistry(allNames); } diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java index 29c53981..71dcef52 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java @@ -22,16 +22,16 @@ public class FCGenerator { * * @param availableClasses - Alle geparsten Klassen */ - public static Set toUnifyFC(Collection availableClasses) throws ClassNotFoundException { - return toFC(availableClasses).stream().map(t -> UnifyTypeFactory.convert(t)).collect(Collectors.toSet()); + public static Set toUnifyFC(Collection availableClasses, ClassLoader classLoader) throws ClassNotFoundException { + return toFC(availableClasses, classLoader).stream().map(t -> UnifyTypeFactory.convert(t)).collect(Collectors.toSet()); } - public static Set toFC(Collection availableClasses) throws ClassNotFoundException { + public static Set toFC(Collection availableClasses, ClassLoader classLoader) throws ClassNotFoundException { HashSet pairs = new HashSet<>(); //PL 2018-09-18: gtvs vor die for-Schleife gezogen, damit immer die gleichen Typeplaceholder eingesetzt werden. HashMap gtvs = new HashMap<>(); for(ClassOrInterface cly : availableClasses){ - pairs.addAll(getSuperTypes(cly, availableClasses, gtvs)); + pairs.addAll(getSuperTypes(cly, availableClasses, gtvs, classLoader)); } return pairs; } @@ -48,8 +48,8 @@ public class FCGenerator { * @param forType * @return */ - private static List getSuperTypes(ClassOrInterface forType, Collection availableClasses) throws ClassNotFoundException { - return getSuperTypes(forType, availableClasses, new HashMap<>()); + private static List getSuperTypes(ClassOrInterface forType, Collection availableClasses, ClassLoader classLoader) throws ClassNotFoundException { + return getSuperTypes(forType, availableClasses, new HashMap<>(), classLoader); } /** @@ -61,7 +61,7 @@ public class FCGenerator { * @throws ClassNotFoundException */ private static List getSuperTypes(ClassOrInterface forType, Collection availableClasses, - HashMap gtvs) throws ClassNotFoundException { + HashMap gtvs, ClassLoader classLoader) throws ClassNotFoundException { List params = new ArrayList<>(); //Die GTVs, die in forType hinzukommen: HashMap newGTVs = new HashMap<>(); @@ -86,7 +86,7 @@ public class FCGenerator { ClassOrInterface superClass; if(!hasSuperclass.isPresent()) //Wenn es die Klasse in den available Klasses nicht gibt wird sie im Classpath gesucht. Ansonsten Exception { - superClass = ASTFactory.createClass(ClassLoader.getSystemClassLoader().loadClass(superType.getName().toString())); + superClass = ASTFactory.createClass(classLoader.loadClass(superType.getName().toString())); }else{ superClass = hasSuperclass.get(); } @@ -120,7 +120,7 @@ public class FCGenerator { if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){ superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER)); }else{ - superTypes = getSuperTypes(superClass, availableClasses, newGTVs); + superTypes = getSuperTypes(superClass, availableClasses, newGTVs, classLoader); } retList.add(ret); diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index 067430e2..9305310d 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -279,9 +279,21 @@ public class StatementGenerator { } - private Statement convert(Java8Parser.ClassInstanceCreationExpressionContext stmt) { - //TODO - throw new NotImplementedException(); + private Statement convert(Java8Parser.ClassInstanceCreationExpressionContext newExpression) { + Java8Parser.TypeArgumentsContext genericArgs = null; + if(newExpression.expressionName()!= null)throw new NotImplementedException(); + if(newExpression.typeArgumentsOrDiamond()!= null){ + if(newExpression.typeArgumentsOrDiamond().typeArguments()!=null){ + genericArgs = newExpression.typeArgumentsOrDiamond().typeArguments(); + } + } + if(newExpression.typeArguments()!= null)throw new NotImplementedException(); + + TerminalNode identifier = newExpression.Identifier(0); + RefType newClass = (RefType) TypeGenerator.convertTypeName(identifier.getText(),genericArgs,identifier.getSymbol(),reg,generics); + + ArgumentList args = convert(newExpression.argumentList()); + return new NewClass(newClass, args, newExpression.getStart()); } private Statement convert(Java8Parser.PreIncrementExpressionContext stmt) { diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 140b3432..c374dd06 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -19,6 +19,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import java.lang.reflect.Modifier; +import java.net.URL; import java.sql.Ref; import java.util.*; import java.util.stream.Collectors; @@ -74,10 +75,10 @@ public class SyntaxTreeGenerator{ return ret; } - public SourceFile convert(Java8Parser.CompilationUnitContext ctx, PackageCrawler packageCrawler) throws ClassNotFoundException{ + public SourceFile convert(Java8Parser.CompilationUnitContext ctx, PackageCrawler packageCrawler, ClassLoader classLoader) throws ClassNotFoundException{ if(ctx.packageDeclaration()!=null)this.pkgName = convert(ctx.packageDeclaration()); List classes = new ArrayList<>(); - Map imports = GatherNames.getImports(ctx, packageCrawler); + Map imports = GatherNames.getImports(ctx, packageCrawler, classLoader); this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet()); for(Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){ ClassOrInterface newClass; diff --git a/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java b/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java index 69481508..31c6d375 100644 --- a/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java +++ b/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java @@ -1,9 +1,8 @@ package de.dhbwstuttgart.parser.scope; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; import de.dhbwstuttgart.parser.antlr.Java8BaseListener; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; @@ -15,7 +14,7 @@ import de.dhbwstuttgart.parser.antlr.Java8Parser; public class GatherNames { - public static Map getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException{ + public static Map getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException{ Map ret = new HashMap<>(); String pkgName = getPackageName(ctx); String nameString = ""; @@ -64,14 +63,13 @@ public class GatherNames { } } } - ret.putAll(getImports(ctx, packages)); + ret.putAll(getImports(ctx, packages, classLoader)); return ret; } - public static Map getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException { + public static Map getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException { Map ret = new HashMap<>(); - ClassLoader classLoader = ClassLoader.getSystemClassLoader(); //ret.putAll(packages.getClassNames("java.lang")); for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){ if(importDeclCtx.singleTypeImportDeclaration() != null){ diff --git a/src/main/java/de/dhbwstuttgart/parser/scope/JavaClassName.java b/src/main/java/de/dhbwstuttgart/parser/scope/JavaClassName.java index b87ff719..534d0916 100644 --- a/src/main/java/de/dhbwstuttgart/parser/scope/JavaClassName.java +++ b/src/main/java/de/dhbwstuttgart/parser/scope/JavaClassName.java @@ -84,7 +84,15 @@ public class JavaClassName { @Override public String toString() { - return (packageName!=null ? packageName.toString() : "") + name; + return (packageName!=null ? packageName.toString() + "." : "") + name; + } + + public String getPackageName() { + return (packageName!=null ? packageName.toString() : ""); + } + + public String getClassName(){ + return name; } } @@ -130,6 +138,9 @@ class PackageName{ String ret = ""; if(names == null)return ""; for(String n : names)ret+=n+"."; + if (ret != null && ret.length() > 0 && ret.charAt(ret.length() - 1) == '.') { + ret = ret.substring(0, ret.length() - 1); + } return ret; } } diff --git a/src/main/java/de/dhbwstuttgart/sat/asp/writer/ASPFactory.java b/src/main/java/de/dhbwstuttgart/sat/asp/writer/ASPFactory.java index 1777eabd..8cb61fee 100644 --- a/src/main/java/de/dhbwstuttgart/sat/asp/writer/ASPFactory.java +++ b/src/main/java/de/dhbwstuttgart/sat/asp/writer/ASPFactory.java @@ -16,9 +16,9 @@ import java.util.*; public class ASPFactory implements TypeVisitor{ - public static String generateASP(ConstraintSet constraints, Collection fcClasses) throws ClassNotFoundException{ + public static String generateASP(ConstraintSet constraints, Collection fcClasses, ClassLoader classLoader) throws ClassNotFoundException{ ASPFactory factory = new ASPFactory(); - factory.convertFC(fcClasses); + factory.convertFC(fcClasses, classLoader); List> constraints1 = constraints.cartesianProduct().iterator().next(); for(Constraint constraint : constraints1){ for(Pair p : constraint){ @@ -32,8 +32,8 @@ public class ASPFactory implements TypeVisitor{ ASPWriter writer = new ASPWriter(); boolean isFCType = false; - private void convertFC(Collection classes) throws ClassNotFoundException { - Set fc = FCGenerator.toFC(classes); + private void convertFC(Collection classes, ClassLoader classLoader) throws ClassNotFoundException { + Set fc = FCGenerator.toFC(classes, classLoader); isFCType = true; for(Pair fcp : fc){ convertPair(fcp); diff --git a/src/main/java/de/dhbwstuttgart/sat/asp/writer/ASPGencayFactory.java b/src/main/java/de/dhbwstuttgart/sat/asp/writer/ASPGencayFactory.java index 11408c25..242c63e6 100644 --- a/src/main/java/de/dhbwstuttgart/sat/asp/writer/ASPGencayFactory.java +++ b/src/main/java/de/dhbwstuttgart/sat/asp/writer/ASPGencayFactory.java @@ -55,9 +55,9 @@ public class ASPGencayFactory implements TypeVisitor { return ret; } - public static String generateASP(ConstraintSet constraints, Collection fcClasses) throws ClassNotFoundException{ + public static String generateASP(ConstraintSet constraints, Collection fcClasses, ClassLoader classLoader) throws ClassNotFoundException{ ASPGencayFactory factory = new ASPGencayFactory(); - factory.convertFC(fcClasses); + factory.convertFC(fcClasses, classLoader); List> constraints1 = constraints.cartesianProduct().iterator().next(); for(Constraint constraint : constraints1){ for(Pair p : constraint){ @@ -69,8 +69,8 @@ public class ASPGencayFactory implements TypeVisitor { return factory.writer.getASPFile(); } - private void convertFC(Collection classes) throws ClassNotFoundException { - Set fc = FCGenerator.toFC(classes); + private void convertFC(Collection classes, ClassLoader classLoader) throws ClassNotFoundException { + Set fc = FCGenerator.toFC(classes, classLoader); isFCType = true; for(Pair fcp : fc){ generateTheta((RefType) fcp.TA1); diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index 4241af34..33d137eb 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -31,7 +31,7 @@ public class UnifyTypeFactory { private static ArrayList PLACEHOLDERS = new ArrayList<>(); - public static FiniteClosure generateFC(List fromClasses, Writer logFile) throws ClassNotFoundException { + public static FiniteClosure generateFC(List fromClasses, Writer logFile, ClassLoader classLoader) throws ClassNotFoundException { /* Die transitive Hülle muss funktionieren. Man darf schreiben List extends AL @@ -42,7 +42,7 @@ public class UnifyTypeFactory { Generell dürfen sie immer die gleichen Namen haben. TODO: die transitive Hülle bilden */ - return new FiniteClosure(FCGenerator.toUnifyFC(fromClasses), logFile); + return new FiniteClosure(FCGenerator.toUnifyFC(fromClasses, classLoader), logFile); } public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){ diff --git a/src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java b/src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java index 44bfd2ff..ebef5263 100644 --- a/src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java +++ b/src/main/java/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java @@ -47,7 +47,7 @@ public class TypeInsertFactory { new TypeToInsertString(resolvedType.resolvedType).insert); List simplifyResults = JavaTXCompiler.INSTANCE.getGeneratedGenericResultsForAllSourceFiles(newResults); for (GenericGenratorResultForSourceFile simplifyResultsEntries : simplifyResults) { - GenericsGeneratorResultForClass genericResultsForClass = simplifyResultsEntries.getSimplifyResultsByName("", cl.getClassName().toString()); + GenericsGeneratorResultForClass genericResultsForClass = simplifyResultsEntries.getSimplifyResultsByName(cl.getClassName()); return new TypeInsert(insertPoint, createGenericInsert(genericResultsForClass, cl, m, resultSet, offset), resolvedType.getResultPair()); } diff --git a/src/test/java/asp/ClingoTest.java b/src/test/java/asp/ClingoTest.java index 90635bde..ea09add3 100644 --- a/src/test/java/asp/ClingoTest.java +++ b/src/test/java/asp/ClingoTest.java @@ -25,7 +25,7 @@ public class ClingoTest { @Test public void test() throws IOException, InterruptedException, ClassNotFoundException { String content = ""; - content = ASPFactory.generateASP(this.getPairs(), this.getFC()); + content = ASPFactory.generateASP(this.getPairs(), this.getFC(), ClassLoader.getSystemClassLoader()); PrintWriter writer = new PrintWriter(tempDirectory + "test.lp", "UTF-8"); writer.println(content); diff --git a/src/test/java/asp/UnifyWithoutWildcards.java b/src/test/java/asp/UnifyWithoutWildcards.java index 6f69d639..c1a84702 100644 --- a/src/test/java/asp/UnifyWithoutWildcards.java +++ b/src/test/java/asp/UnifyWithoutWildcards.java @@ -40,7 +40,7 @@ public class UnifyWithoutWildcards { public ResultSet run(ConstraintSet toTest) throws IOException, InterruptedException, ClassNotFoundException { String content = ""; - content = ASPFactory.generateASP(toTest, this.getFC()); + content = ASPFactory.generateASP(toTest, this.getFC(), ClassLoader.getSystemClassLoader()); PrintWriter writer = new PrintWriter(tempDirectory + "test.lp", "UTF-8"); writer.println(content); diff --git a/src/test/java/asp/gencay/GeneratorTest.java b/src/test/java/asp/gencay/GeneratorTest.java index 2c9fc46f..36a74bde 100644 --- a/src/test/java/asp/gencay/GeneratorTest.java +++ b/src/test/java/asp/gencay/GeneratorTest.java @@ -35,7 +35,7 @@ public class GeneratorTest extends UnifyWithoutWildcards{ RefType t2 = new RefType(new JavaClassName("java.util.List"), list2, new NullToken()); testSet.addUndConstraint(new Pair(t1, t2, PairOperator.SMALLERDOT)); String resultSet = ASPGencayFactory.generateASP(testSet, - new HashSet<>(Arrays.asList(ASTFactory.createClass(List.class)))); + new HashSet<>(Arrays.asList(ASTFactory.createClass(List.class))), ClassLoader.getSystemClassLoader()); System.out.println(resultSet); } @@ -47,7 +47,7 @@ public class GeneratorTest extends UnifyWithoutWildcards{ RefType t1 = new RefType(new JavaClassName("asp.UnifyWithoutWildcards$Matrix"), list1, new NullToken()); RefType t2 = new RefType(new JavaClassName("java.util.HashMap"), list2, new NullToken()); testSet.addUndConstraint(new Pair(t1, t2, PairOperator.SMALLERDOT)); - String resultSet = ASPGencayFactory.generateASP(testSet, this.getFC()); + String resultSet = ASPGencayFactory.generateASP(testSet, this.getFC(), ClassLoader.getSystemClassLoader()); System.out.println(resultSet); } diff --git a/src/test/java/asp/typeinference/ASPTest.java b/src/test/java/asp/typeinference/ASPTest.java index 5a43b6a9..989e1233 100644 --- a/src/test/java/asp/typeinference/ASPTest.java +++ b/src/test/java/asp/typeinference/ASPTest.java @@ -55,7 +55,7 @@ public class ASPTest { } final ConstraintSet cons = compiler.getConstraints(); - String asp = ASPFactory.generateASP(cons, allClasses); + String asp = ASPFactory.generateASP(cons, allClasses, ClassLoader.getSystemClassLoader()); System.out.println(asp); } diff --git a/src/test/java/finiteClosure/SuperInterfacesTest.java b/src/test/java/finiteClosure/SuperInterfacesTest.java index 0e1368c3..d74215b7 100644 --- a/src/test/java/finiteClosure/SuperInterfacesTest.java +++ b/src/test/java/finiteClosure/SuperInterfacesTest.java @@ -14,14 +14,14 @@ public class SuperInterfacesTest { public void test() throws ClassNotFoundException { Collection classes = new ArrayList<>(); classes.add(ASTFactory.createClass(TestClass.class)); - System.out.println(FCGenerator.toFC(classes)); + System.out.println(FCGenerator.toFC(classes, ClassLoader.getSystemClassLoader())); } @Test public void testGeneric() throws ClassNotFoundException { Collection classes = new ArrayList<>(); classes.add(ASTFactory.createClass(TestClassGeneric.class)); - System.out.println(FCGenerator.toFC(classes)); + System.out.println(FCGenerator.toFC(classes, ClassLoader.getSystemClassLoader())); } } diff --git a/src/test/java/packages/Bytecode.java b/src/test/java/packages/Bytecode.java index f02c83fa..3fabed05 100644 --- a/src/test/java/packages/Bytecode.java +++ b/src/test/java/packages/Bytecode.java @@ -6,20 +6,47 @@ import org.junit.Test; import java.io.File; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.net.URLClassLoader; public class Bytecode extends TestCase { - public static final String rootDirectory = System.getProperty("user.dir")+"/src/test/resources/javFiles/packageTest/de/test/"; + public static final String rootDirectory = System.getProperty("user.dir")+"/src/test/resources/javFiles/packageTest/"; @Test - public void testSetPackageNameInBytecode() throws IOException, ClassNotFoundException { - JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"packageNameTest.jav")); + public void testSetPackageNameInBytecode() throws Exception { + JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"de/test/TestClass.jav")); compiler.typeInference(); - File f = new File(rootDirectory + "Test.class"); + File f = new File(rootDirectory + "de/test/TestClass.class"); if(f.exists() && !f.isDirectory()) { f.delete(); } compiler.generateBytecode(null); - f = new File(rootDirectory + "Test.class"); + f = new File(rootDirectory + "de/test/TestClass.class"); assertTrue(f.exists()); + + + URLClassLoader loader = new URLClassLoader(new URL[]{new URL("file://" + rootDirectory)}); + Class classToTest = loader.loadClass("de.test.TestClass"); + Object instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); } + + @Test + public void testSetPackageNameInBytecodeAndOutputFolder() throws Exception { + JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"de/test/TestClass.jav")); + compiler.typeInference(); + File f = new File(rootDirectory + "de/test/output/de/test/TestClass.class"); + if(f.exists() && !f.isDirectory()) { + f.delete(); + } + compiler.generateBytecode(rootDirectory + "de/test/output/"); + f = new File(rootDirectory + "de/test/output/de/test/TestClass.class"); + assertTrue(f.exists()); + + URLClassLoader loader = new URLClassLoader(new URL[]{new URL("file://" + rootDirectory + "de/test/output/")}); + Class classToTest = loader.loadClass("de.test.TestClass"); + Object instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + + } diff --git a/src/test/java/packages/CheckPackageFolder.java b/src/test/java/packages/CheckPackageFolder.java index 9644d5da..b0cfbb8e 100644 --- a/src/test/java/packages/CheckPackageFolder.java +++ b/src/test/java/packages/CheckPackageFolder.java @@ -7,14 +7,73 @@ import org.junit.Test; import java.io.File; import java.io.IOException; +import java.util.Arrays; public class CheckPackageFolder extends TestCase { public static final String rootDirectory = System.getProperty("user.dir")+"/src/test/resources/javFiles/packageTest/de/test/"; @Test - public void testCorrectFolder1File() throws IOException, ClassNotFoundException { + public void testCorrectFolder1FileWithWrongPackageName() throws IOException, ClassNotFoundException { JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"packageNameTestWrongPackage.jav")); - assertTrue(true); //Es ist erlaubt falsche package Namen zu verwenden. Warnung wäre optional + compiler.typeInference(); + File f = new File(rootDirectory + "TestClass.class"); + if(f.exists() && !f.isDirectory()) { + f.delete(); + } + compiler.generateBytecode(); + f = new File(rootDirectory + "TestClass.class"); + assertTrue(f.exists()); //Es ist erlaubt falsche package Namen zu verwenden. Warnung wäre optional } + + @Test + public void testCorrectFolder1File() throws IOException, ClassNotFoundException { + JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"TestClass.jav")); + compiler.typeInference(); + File f = new File(rootDirectory + "TestClass.class"); + if(f.exists() && !f.isDirectory()) { + f.delete(); + } + compiler.generateBytecode(); + f = new File(rootDirectory + "TestClass.class"); + assertTrue(f.exists()); //Es ist erlaubt falsche package Namen zu verwenden. Warnung wäre optional + } + + @Test + public void testCorrectFolder1FileAndOutputDirectory() throws IOException, ClassNotFoundException { + JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"TestClass.jav")); + compiler.typeInference(); + File f = new File(rootDirectory + "output/de/test/TestClass.class"); + if(f.exists() && !f.isDirectory()) { + f.delete(); + } + compiler.generateBytecode(rootDirectory+"output/"); + f = new File(rootDirectory + "output/de/test/TestClass.class"); + assertTrue(f.exists()); //Es ist erlaubt falsche package Namen zu verwenden. Warnung wäre optional + } + + /* + * Dieser Test wird übersprungen, da der Bytecode-Generator nicht mit zwei Eingabedateien gleichzeitig umgehen kann + @Test + public void testCorrectFolder2Files() throws IOException, ClassNotFoundException { + JavaTXCompiler compiler = new JavaTXCompiler(Arrays.asList( + new File(rootDirectory+"subpackage1/Test1.jav"), + new File(rootDirectory+"subpackage2/Test2.jav") + )); + compiler.typeInference(); + File f = new File(rootDirectory + "subpackage1/Test1.class"); + if(f.exists() && !f.isDirectory()) { + f.delete(); + } + File f2 = new File(rootDirectory + "subpackage2/Test2.class"); + if(f.exists() && !f.isDirectory()) { + f.delete(); + } + compiler.generateBytecode(); + f = new File(rootDirectory + "subpackage1/Test1.class"); + f2 = new File(rootDirectory + "subpackage2/Test2.class"); + assertTrue(f.exists()); + assertTrue(f2.exists()); + } + */ } diff --git a/src/test/java/packages/ImportTest.java b/src/test/java/packages/ImportTest.java new file mode 100644 index 00000000..b13918c6 --- /dev/null +++ b/src/test/java/packages/ImportTest.java @@ -0,0 +1,86 @@ +package packages; + +import com.google.common.collect.Lists; +import de.dhbwstuttgart.core.JavaTXCompiler; +import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +public class ImportTest extends TestCase { + + public static final String rootDirectory = System.getProperty("user.dir")+"/src/test/resources/javFiles/packageTest/de/test/"; + + + public ImportTest() throws ClassNotFoundException, IOException { + /* + Generate ToImport class in rootDirectory and in output-Directory + */ + JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"ToImport.jav")); + compiler.typeInference(); + compiler.generateBytecode(rootDirectory + "output/"); + File f = new File(rootDirectory + "output/de/test/ToImport.class"); + assertTrue(f.exists()); + + compiler = new JavaTXCompiler(new File(rootDirectory+"subpackage1/ToImport2.jav")); + compiler.typeInference(); + compiler.generateBytecode(rootDirectory + "output/"); + f = new File(rootDirectory + "output/de/test/subpackage1/ToImport2.class"); + assertTrue(f.exists()); + + compiler = new JavaTXCompiler(new File(rootDirectory+"subpackage2/ToImport3.jav")); + compiler.typeInference(); + compiler.generateBytecode(rootDirectory + "output/"); + f = new File(rootDirectory + "output/de/test/subpackage2/ToImport3.class"); + assertTrue(f.exists()); + } + + @Test + public void testSetPackageNameInBytecodeAndOutputFolder() throws IOException, ClassNotFoundException { + JavaTXCompiler compiler = new JavaTXCompiler( + Lists.newArrayList(new File(rootDirectory+"ImportTest.jav")), + Lists.newArrayList(new URL("file://"+rootDirectory+"output/"))); + compiler.typeInference(); + File f = new File(rootDirectory + "output/de/test/ImportTest.class"); + if(f.exists() && !f.isDirectory()) { + f.delete(); + } + compiler.generateBytecode(rootDirectory + "output/"); + f = new File(rootDirectory + "output/de/test/ImportTest.class"); + assertTrue(f.exists()); + } + + @Test + public void testSetPackageNameInBytecodeAndStandardOutputFolder() throws IOException, ClassNotFoundException { + JavaTXCompiler compiler = new JavaTXCompiler( + Lists.newArrayList(new File(rootDirectory+"ImportTest.jav")), + Lists.newArrayList(new URL("file://"+rootDirectory+"output/"))); + compiler.typeInference(); + File f = new File(rootDirectory + "ImportTest.class"); + if(f.exists() && !f.isDirectory()) { + f.delete(); + } + compiler.generateBytecode(null); + f = new File(rootDirectory + "ImportTest.class"); + assertTrue(f.exists()); + } + + + @Test + public void testImportTwoClasses() throws IOException, ClassNotFoundException { + JavaTXCompiler compiler = new JavaTXCompiler( + Lists.newArrayList(new File(rootDirectory+"ImportTest2.jav")), + Lists.newArrayList(new URL("file://"+rootDirectory+"output/"))); + compiler.typeInference(); + File f = new File(rootDirectory + "ImportTest2.class"); + if(f.exists() && !f.isDirectory()) { + f.delete(); + } + compiler.generateBytecode(null); + f = new File(rootDirectory + "ImportTest2.class"); + assertTrue(f.exists()); + } +} diff --git a/src/test/java/packages/ParsePackageName.java b/src/test/java/packages/ParsePackageName.java index b54cf90e..9dc0ea9a 100644 --- a/src/test/java/packages/ParsePackageName.java +++ b/src/test/java/packages/ParsePackageName.java @@ -12,7 +12,7 @@ public class ParsePackageName { public static final String rootDirectory = System.getProperty("user.dir")+"/src/test/resources/javFiles/packageTest/de/test/"; @Test public void parsePackage() throws IOException, ClassNotFoundException { - JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"packageNameTest.jav")); + JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"TestClass.jav")); for(File f : compiler.sourceFiles.keySet()){ SourceFile sf = compiler.sourceFiles.get(f); assert sf.getPkgName().equals("de.test"); diff --git a/src/test/java/typeinference/JavaTXCompilerTest.java b/src/test/java/typeinference/JavaTXCompilerTest.java index 87ae477d..ac724771 100644 --- a/src/test/java/typeinference/JavaTXCompilerTest.java +++ b/src/test/java/typeinference/JavaTXCompilerTest.java @@ -28,6 +28,10 @@ public class JavaTXCompilerTest { execute(new File(rootDirectory+"fc.jav")); } @Test + public void importTest() throws IOException, ClassNotFoundException { + execute(new File(rootDirectory+"Import.jav")); + } + @Test public void lambda() throws IOException, ClassNotFoundException { execute(new File(rootDirectory+"Lambda.jav")); } diff --git a/src/test/resources/javFiles/Import.jav b/src/test/resources/javFiles/Import.jav index c48082ba..2fc3a8b3 100644 --- a/src/test/resources/javFiles/Import.jav +++ b/src/test/resources/javFiles/Import.jav @@ -2,7 +2,7 @@ import java.util.Vector; class Import { void methode(){ - Vector v; + var v; v.add(v); } } \ No newline at end of file diff --git a/src/test/resources/javFiles/packageTest/de/test/ImportTest.jav b/src/test/resources/javFiles/packageTest/de/test/ImportTest.jav new file mode 100644 index 00000000..58b6fc0b --- /dev/null +++ b/src/test/resources/javFiles/packageTest/de/test/ImportTest.jav @@ -0,0 +1,9 @@ +package de.test; + +import de.test.ToImport; + +class ImportTest{ + void methode(){ + new ToImport(); + } +} \ No newline at end of file diff --git a/src/test/resources/javFiles/packageTest/de/test/ImportTest2.jav b/src/test/resources/javFiles/packageTest/de/test/ImportTest2.jav new file mode 100644 index 00000000..3526abc8 --- /dev/null +++ b/src/test/resources/javFiles/packageTest/de/test/ImportTest2.jav @@ -0,0 +1,11 @@ +package de.test; + +import de.test.subpackage1.ToImport2; +import de.test.subpackage2.ToImport3; + +class ImportTest2{ + void methode(){ + new ToImport2().m1(); + new ToImport3().m2(); + } +} \ No newline at end of file diff --git a/src/test/resources/javFiles/packageTest/de/test/TestClass.jav b/src/test/resources/javFiles/packageTest/de/test/TestClass.jav new file mode 100644 index 00000000..6681b36a --- /dev/null +++ b/src/test/resources/javFiles/packageTest/de/test/TestClass.jav @@ -0,0 +1,3 @@ +package de.test; + +public class TestClass{} \ No newline at end of file diff --git a/src/test/resources/javFiles/packageTest/de/test/packageNameTest.jav b/src/test/resources/javFiles/packageTest/de/test/ToImport.jav similarity index 51% rename from src/test/resources/javFiles/packageTest/de/test/packageNameTest.jav rename to src/test/resources/javFiles/packageTest/de/test/ToImport.jav index ad5b9f63..3afdba54 100644 --- a/src/test/resources/javFiles/packageTest/de/test/packageNameTest.jav +++ b/src/test/resources/javFiles/packageTest/de/test/ToImport.jav @@ -1,3 +1,4 @@ package de.test; -class TestClass{} \ No newline at end of file +class ToImport{ +} \ No newline at end of file diff --git a/src/test/resources/javFiles/packageTest/de/test/subpackage1/Test1.jav b/src/test/resources/javFiles/packageTest/de/test/subpackage1/Test1.jav new file mode 100644 index 00000000..a7011169 --- /dev/null +++ b/src/test/resources/javFiles/packageTest/de/test/subpackage1/Test1.jav @@ -0,0 +1,4 @@ +package de.test.subpackage1; + +class Test1{ +} \ No newline at end of file diff --git a/src/test/resources/javFiles/packageTest/de/test/subpackage1/ToImport2.jav b/src/test/resources/javFiles/packageTest/de/test/subpackage1/ToImport2.jav new file mode 100644 index 00000000..bcc67b95 --- /dev/null +++ b/src/test/resources/javFiles/packageTest/de/test/subpackage1/ToImport2.jav @@ -0,0 +1,5 @@ +package de.test.subpackage1; + +class ToImport2{ +void m1(){} +} \ No newline at end of file diff --git a/src/test/resources/javFiles/packageTest/de/test/subpackage2/Test2.jav b/src/test/resources/javFiles/packageTest/de/test/subpackage2/Test2.jav new file mode 100644 index 00000000..750f7612 --- /dev/null +++ b/src/test/resources/javFiles/packageTest/de/test/subpackage2/Test2.jav @@ -0,0 +1,4 @@ +package de.test.subpackage2; + +class Test2{ +} \ No newline at end of file diff --git a/src/test/resources/javFiles/packageTest/de/test/subpackage2/ToImport3.jav b/src/test/resources/javFiles/packageTest/de/test/subpackage2/ToImport3.jav new file mode 100644 index 00000000..3efd8fff --- /dev/null +++ b/src/test/resources/javFiles/packageTest/de/test/subpackage2/ToImport3.jav @@ -0,0 +1,5 @@ +package de.test.subpackage2; + +class ToImport3{ +void m2(){} +} \ No newline at end of file diff --git a/vorgehen.md b/vorgehen.md index 61b62c4f..0854c152 100644 --- a/vorgehen.md +++ b/vorgehen.md @@ -15,10 +15,13 @@ * Java kompiliert in den gleichen Ordner wie die source file * Java erhält eine liste von Source Files, die es kompilieren soll * anhand von deren Standort lassen sich relativ die Position von kompilierten Class-files bestimmen + * macht der javac Compiler allerdings nicht + * er nimmt sein Running Directory als classPath standardmäßig, falls keiner angegeben + * javac geht davon aus, dass CP richtig gesetzt wird, oder javac im Source-Root ausgeführt wird * -cp path or -classpath path Specifies where to find user class files, and (optionally) annotation processors and source files. This class path overrides the user class path in the CLASSPATH environment variable. If neither CLASSPATH, -cp nor -classpath is specified, then the - user class path is the current directory. See Setting the Class Path. + user class path is the current directory. See Setting the Class Path. * Compiler kontrolliert nicht, ob package im korrekten Ordner ist * auch keine Warnung @@ -28,3 +31,33 @@ * Optional * damit lässt sich ein andere ort zur Ausgabe der Class-files bestimmen +# Tasks +## Class files in richtigen Ordner legen ## +* Wenn Pfad übergeben, dann in Pfad + packageName +* Ohne Pfad, direkt neben die Source File legen +* wenn Source File nicht in richtigem Ordner -> Warnung ausgeben + +### Stand ### +* Beinahe abgeschlossen +* TODO: Tests schreiben + +## Class files einlesen +* Wenn Classpath übergeben + * Suchen in Classpath + packageName + * Müsste eigentlich UTLClassLoader automatisch machen (also packageNamen anfügen) +* Wenn nichts übergeben + * dann currentDirectory + packageName +* Für die Tests muss korrekter Classpath gesetzt werden + +### Stand ### +TODO: +* es muss überall wo im Quellcode ClassLoader.getSystemClassLoader() oder ein andere Classloader verwendet wird, + * dieser ausgetauscht werden mit dem classLaoder, welcher bei der Instanzierung von JavaTXCompiler erstellt wird + +## Class files mit packageNamen versehen +* In die Class file muss noch der korrekte name geschrieben werden + * kann möglicherweise ASM + * Kann ASM mittesl `cw.visit("name/mit/slashe/Getrennt"..` + * wurde bereits erledigt -> TODO: Testen + +## Console Interface um Parameter -classpath und -output directory erweitern