From afd2c21ca8f9b7aaef31364cb12c82d9d0f58c9a Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Mon, 16 Dec 2019 00:54:00 +0100 Subject: [PATCH] Add classPath option to JavaTXCompiler and parse with URLClassLoader --- .../de/dhbwstuttgart/core/JavaTXCompiler.java | 35 +++++++++++++------ .../environment/CompilationEnvironment.java | 4 +-- .../StatementGenerator.java | 18 ++++++++-- .../SyntaxTreeGenerator.java | 5 +-- .../parser/scope/GatherNames.java | 14 ++++---- src/test/java/packages/ImportTest.java | 6 +++- vorgehen.md | 10 ++++-- 7 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index b1bb04ca..61f90e42 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)); } @@ -708,9 +721,9 @@ 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; } diff --git a/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java index 3d450183..7b759e27 100644 --- a/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java +++ b/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java @@ -67,10 +67,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/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/test/java/packages/ImportTest.java b/src/test/java/packages/ImportTest.java index a6fbc075..6487c9ab 100644 --- a/src/test/java/packages/ImportTest.java +++ b/src/test/java/packages/ImportTest.java @@ -1,5 +1,6 @@ package packages; +import com.google.common.collect.Lists; import de.dhbwstuttgart.core.JavaTXCompiler; import junit.framework.TestCase; import org.junit.Before; @@ -7,6 +8,7 @@ import org.junit.Test; import java.io.File; import java.io.IOException; +import java.net.URL; public class ImportTest extends TestCase { @@ -31,7 +33,9 @@ public class ImportTest extends TestCase { @Test public void testSetPackageNameInBytecodeAndOutputFolder() throws IOException, ClassNotFoundException { - JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"ImportTest.jav")); + 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()) { diff --git a/vorgehen.md b/vorgehen.md index 834c49e7..b9af4d76 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 @@ -46,8 +49,11 @@ * Für die Tests muss korrekter Classpath gesetzt werden ### Stand ### -TODO +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 + * wurde bereits erledigt -> TODO: Testen