Add classPath option to JavaTXCompiler and parse with URLClassLoader

This commit is contained in:
JanUlrich 2019-12-16 00:54:00 +01:00
parent 74622550c2
commit afd2c21ca8
7 changed files with 63 additions and 29 deletions

View File

@ -1,6 +1,7 @@
//PL 2018-12-19: typeInferenceOld nach typeInference uebertragen //PL 2018-12-19: typeInferenceOld nach typeInference uebertragen
package de.dhbwstuttgart.core; package de.dhbwstuttgart.core;
import com.google.common.collect.Lists;
import de.dhbwstuttgart.bytecode.BytecodeGen; import de.dhbwstuttgart.bytecode.BytecodeGen;
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError; import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
import de.dhbwstuttgart.bytecode.genericsGenerator.GeneratedGenericsFinder; import de.dhbwstuttgart.bytecode.genericsGenerator.GeneratedGenericsFinder;
@ -41,6 +42,8 @@ import java.io.FileOutputStream;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -50,24 +53,34 @@ public class JavaTXCompiler {
public static JavaTXCompiler INSTANCE; public static JavaTXCompiler INSTANCE;
final CompilationEnvironment environment; final CompilationEnvironment environment;
Boolean resultmodel = true; Boolean resultmodel = true;
public final Map<File, SourceFile> sourceFiles = new HashMap<>(); public final Map<File, SourceFile> sourceFiles = new HashMap<>();
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden soll? 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 volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
private final ClassLoader classLoader;
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Arrays.asList(sourceFile)); public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
INSTANCE = this; this(Arrays.asList(sourceFile), null);
} INSTANCE = this;
}
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException { public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
this(sourceFile); this(sourceFile);
this.log = log; this.log = log;
INSTANCE = this; INSTANCE = this;
} }
public JavaTXCompiler(List<File> sources) throws IOException, ClassNotFoundException { public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
environment = new CompilationEnvironment(sources); this(sourceFiles, null);
INSTANCE = this;
}
public JavaTXCompiler(List<File> sources, List<URL> 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) { for (File s : sources) {
sourceFiles.put(s, parse(s)); sourceFiles.put(s, parse(s));
} }
@ -708,9 +721,9 @@ public class JavaTXCompiler {
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException { private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
CompilationUnitContext tree = JavaTXParser.parse(sourceFile); CompilationUnitContext tree = JavaTXParser.parse(sourceFile);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile), SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile, classLoader),
new GenericsRegistry(null)); new GenericsRegistry(null));
SourceFile ret = generator.convert(tree, environment.packageCrawler); SourceFile ret = generator.convert(tree, environment.packageCrawler, classLoader);
return ret; return ret;
} }

View File

@ -67,10 +67,10 @@ public class CompilationEnvironment {
this.packageCrawler = new PackageCrawler(librarys); this.packageCrawler = new PackageCrawler(librarys);
} }
public JavaClassRegistry getRegistry(File forSourceFile) throws ClassNotFoundException, IOException { public JavaClassRegistry getRegistry(File forSourceFile, ClassLoader classLoader) throws ClassNotFoundException, IOException {
Map<String, Integer> allNames; Map<String, Integer> allNames;
CompilationUnitContext tree = JavaTXParser.parse(forSourceFile); CompilationUnitContext tree = JavaTXParser.parse(forSourceFile);
allNames = GatherNames.getNames(tree, packageCrawler); allNames = GatherNames.getNames(tree, packageCrawler, classLoader);
return new JavaClassRegistry(allNames); return new JavaClassRegistry(allNames);
} }

View File

@ -279,9 +279,21 @@ public class StatementGenerator {
} }
private Statement convert(Java8Parser.ClassInstanceCreationExpressionContext stmt) { private Statement convert(Java8Parser.ClassInstanceCreationExpressionContext newExpression) {
//TODO Java8Parser.TypeArgumentsContext genericArgs = null;
throw new NotImplementedException(); 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) { private Statement convert(Java8Parser.PreIncrementExpressionContext stmt) {

View File

@ -19,6 +19,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.net.URL;
import java.sql.Ref; import java.sql.Ref;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -74,10 +75,10 @@ public class SyntaxTreeGenerator{
return ret; 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()); if(ctx.packageDeclaration()!=null)this.pkgName = convert(ctx.packageDeclaration());
List<ClassOrInterface> classes = new ArrayList<>(); List<ClassOrInterface> classes = new ArrayList<>();
Map<String, Integer> imports = GatherNames.getImports(ctx, packageCrawler); Map<String, Integer> imports = GatherNames.getImports(ctx, packageCrawler, classLoader);
this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet()); this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet());
for(Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){ for(Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){
ClassOrInterface newClass; ClassOrInterface newClass;

View File

@ -1,9 +1,8 @@
package de.dhbwstuttgart.parser.scope; package de.dhbwstuttgart.parser.scope;
import java.util.ArrayList; import java.net.URL;
import java.util.HashMap; import java.net.URLClassLoader;
import java.util.List; import java.util.*;
import java.util.Map;
import de.dhbwstuttgart.parser.antlr.Java8BaseListener; import de.dhbwstuttgart.parser.antlr.Java8BaseListener;
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
@ -15,7 +14,7 @@ import de.dhbwstuttgart.parser.antlr.Java8Parser;
public class GatherNames { public class GatherNames {
public static Map<String, Integer> getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException{ public static Map<String, Integer> getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException{
Map<String, Integer> ret = new HashMap<>(); Map<String, Integer> ret = new HashMap<>();
String pkgName = getPackageName(ctx); String pkgName = getPackageName(ctx);
String nameString = ""; String nameString = "";
@ -64,14 +63,13 @@ public class GatherNames {
} }
} }
} }
ret.putAll(getImports(ctx, packages)); ret.putAll(getImports(ctx, packages, classLoader));
return ret; return ret;
} }
public static Map<String, Integer> getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException { public static Map<String, Integer> getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
Map<String, Integer> ret = new HashMap<>(); Map<String, Integer> ret = new HashMap<>();
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
//ret.putAll(packages.getClassNames("java.lang")); //ret.putAll(packages.getClassNames("java.lang"));
for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){ for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){
if(importDeclCtx.singleTypeImportDeclaration() != null){ if(importDeclCtx.singleTypeImportDeclaration() != null){

View File

@ -1,5 +1,6 @@
package packages; package packages;
import com.google.common.collect.Lists;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.junit.Before; import org.junit.Before;
@ -7,6 +8,7 @@ import org.junit.Test;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URL;
public class ImportTest extends TestCase { public class ImportTest extends TestCase {
@ -31,7 +33,9 @@ public class ImportTest extends TestCase {
@Test @Test
public void testSetPackageNameInBytecodeAndOutputFolder() throws IOException, ClassNotFoundException { 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(); compiler.typeInference();
File f = new File(rootDirectory + "output/de/test/ImportTest.class"); File f = new File(rootDirectory + "output/de/test/ImportTest.class");
if(f.exists() && !f.isDirectory()) { if(f.exists() && !f.isDirectory()) {

View File

@ -15,10 +15,13 @@
* Java kompiliert in den gleichen Ordner wie die source file * Java kompiliert in den gleichen Ordner wie die source file
* Java erhält eine liste von Source Files, die es kompilieren soll * 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 * 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 * -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 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 * Compiler kontrolliert nicht, ob package im korrekten Ordner ist
* auch keine Warnung * auch keine Warnung
@ -46,8 +49,11 @@
* Für die Tests muss korrekter Classpath gesetzt werden * Für die Tests muss korrekter Classpath gesetzt werden
### Stand ### ### 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 ## Class files mit packageNamen versehen
* In die Class file muss noch der korrekte name geschrieben werden * In die Class file muss noch der korrekte name geschrieben werden
* kann möglicherweise ASM * kann möglicherweise ASM
* wurde bereits erledigt -> TODO: Testen