forked from JavaTX/JavaCompilerCore
Anpassungen der Grammatikregeln übernommen
This commit is contained in:
parent
b0bec83900
commit
6d52949215
@ -14,7 +14,7 @@ import de.dhbwstuttgart.parser.JavaTXParser;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.CompilationUnitContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||
@ -69,147 +69,137 @@ import java.util.stream.Collectors;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.apache.commons.io.output.NullOutputStream;
|
||||
|
||||
|
||||
public class JavaTXCompiler {
|
||||
|
||||
//public static JavaTXCompiler INSTANCE;
|
||||
final CompilationEnvironment environment;
|
||||
// public static JavaTXCompiler INSTANCE;
|
||||
final CompilationEnvironment environment;
|
||||
Boolean resultmodel = true;
|
||||
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?
|
||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
//nur fuer Testzwecke of Generated Generics
|
||||
//wieder loeschen PL 2021-03-22
|
||||
public FamilyOfGeneratedGenerics fogg;
|
||||
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?
|
||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
// nur fuer Testzwecke of Generated Generics wieder loeschen PL 2021-03-22
|
||||
public FamilyOfGeneratedGenerics fogg;
|
||||
|
||||
|
||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||
this(Arrays.asList(sourceFile), null);
|
||||
}
|
||||
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
|
||||
this(sourceFile);
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
|
||||
this(sourceFile);
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
|
||||
this(sourceFiles, null);
|
||||
}
|
||||
public JavaTXCompiler(List<File> sources, List<File> contextPath) throws IOException, ClassNotFoundException {
|
||||
if(contextPath == null || contextPath.isEmpty()){
|
||||
//When no contextPaths are given, the working directory is the sources root
|
||||
|
||||
public JavaTXCompiler(List<File> sources, List<File> 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 File(System.getProperty("user.dir")));
|
||||
}
|
||||
classLoader = new DirectoryClassLoader(contextPath, ClassLoader.getSystemClassLoader());
|
||||
classLoader = new DirectoryClassLoader(contextPath, ClassLoader.getSystemClassLoader());
|
||||
environment = new CompilationEnvironment(sources);
|
||||
for (File s : sources) {
|
||||
sourceFiles.put(s, parse(s));
|
||||
}
|
||||
//INSTANCE = this;
|
||||
}
|
||||
for (File s : sources) {
|
||||
sourceFiles.put(s, parse(s));
|
||||
}
|
||||
// INSTANCE = this;
|
||||
}
|
||||
|
||||
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException {
|
||||
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
|
||||
List<ClassOrInterface> importedClasses = new ArrayList<>();
|
||||
ClassOrInterface objectClass = ASTFactory.createClass(
|
||||
classLoader.loadClass(new JavaClassName("java.lang.Object").toString()));
|
||||
//Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
|
||||
for (File forSourceFile : sourceFiles.keySet()){
|
||||
for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) {
|
||||
//TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(
|
||||
classLoader.loadClass(name.toString()));
|
||||
importedClasses.add(importedClass);
|
||||
}
|
||||
for(Class c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)){
|
||||
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException {
|
||||
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
|
||||
List<ClassOrInterface> importedClasses = new ArrayList<>();
|
||||
ClassOrInterface objectClass = ASTFactory.createClass(
|
||||
classLoader.loadClass(new JavaClassName("java.lang.Object").toString()));
|
||||
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
|
||||
for (File forSourceFile : sourceFiles.keySet()) {
|
||||
for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) {
|
||||
// TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(
|
||||
classLoader.loadClass(name.toString()));
|
||||
importedClasses.add(importedClass);
|
||||
}
|
||||
for (Class c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)) {
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(c);
|
||||
importedClasses.add(importedClass);
|
||||
}
|
||||
}
|
||||
for (File f : this.sourceFiles.keySet()) {
|
||||
}
|
||||
for (File f : this.sourceFiles.keySet()) {
|
||||
SourceFile sf = sourceFiles.get(f);
|
||||
sf = new SourceFile(sf.getPkgName(),
|
||||
sf.KlassenVektor.stream()
|
||||
.map(cl -> new ClassOrInterface(cl))
|
||||
.collect(Collectors.toCollection(ArrayList::new)),
|
||||
sf.imports);
|
||||
//sf enthaelt neues Source-File, neue Klassen-Objekte und neue
|
||||
//ArrayListen-Objekte fuer Fields, Construktoren und Methoden
|
||||
//Alle anderen Objekte werden nur kopiert.
|
||||
sf.KlassenVektor.stream()
|
||||
.map(cl -> new ClassOrInterface(cl))
|
||||
.collect(Collectors.toCollection(ArrayList::new)),
|
||||
sf.imports);
|
||||
// sf enthaelt neues Source-File, neue Klassen-Objekte und neue
|
||||
// ArrayListen-Objekte fuer Fields, Construktoren und Methoden
|
||||
// Alle anderen Objekte werden nur kopiert.
|
||||
SourceFile sf_new = sf;
|
||||
sf.KlassenVektor.forEach(cl -> addMethods(sf_new, cl, importedClasses, objectClass));
|
||||
allClasses.addAll(sf.getClasses());
|
||||
}
|
||||
allClasses.addAll(importedClasses);
|
||||
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
|
||||
}
|
||||
|
||||
void addMethods(SourceFile sf, ClassOrInterface cl, List<ClassOrInterface> importedClasses, ClassOrInterface objectClass) {
|
||||
allClasses.addAll(importedClasses);
|
||||
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
|
||||
}
|
||||
|
||||
void addMethods(SourceFile sf, ClassOrInterface cl, List<ClassOrInterface> importedClasses,
|
||||
ClassOrInterface objectClass) {
|
||||
if (!cl.areMethodsAdded()) {
|
||||
ClassOrInterface superclass = null;
|
||||
if (cl.getSuperClass().getName().equals(new JavaClassName("java.lang.Object"))) {
|
||||
superclass = objectClass;
|
||||
}
|
||||
else {
|
||||
Optional<ClassOrInterface> optSuperclass =
|
||||
importedClasses.stream().filter(x -> x.getClassName().equals(
|
||||
cl.getSuperClass().getName())).findFirst();
|
||||
} else {
|
||||
Optional<ClassOrInterface> optSuperclass = importedClasses.stream().filter(x -> x.getClassName().equals(
|
||||
cl.getSuperClass().getName())).findFirst();
|
||||
if (optSuperclass.isPresent()) {
|
||||
superclass = optSuperclass.get();
|
||||
}
|
||||
else {
|
||||
optSuperclass =
|
||||
sf.KlassenVektor.stream().filter(x -> x.getClassName().equals(
|
||||
cl.getSuperClass().getName())).findFirst();
|
||||
} else {
|
||||
optSuperclass = sf.KlassenVektor.stream().filter(x -> x.getClassName().equals(
|
||||
cl.getSuperClass().getName())).findFirst();
|
||||
if (optSuperclass.isPresent()) {
|
||||
superclass = optSuperclass.get();
|
||||
addMethods(sf, superclass, importedClasses, objectClass);
|
||||
}
|
||||
else {
|
||||
//throw new ClassNotFoundException("");
|
||||
addMethods(sf, superclass, importedClasses, objectClass);
|
||||
} else {
|
||||
// throw new ClassNotFoundException("");
|
||||
}
|
||||
}
|
||||
}
|
||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt= cl.getSuperClass().getParaList().iterator();
|
||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt = cl.getSuperClass().getParaList().iterator();
|
||||
Iterator<GenericTypeVar> tvarVarIt = superclass.getGenerics().iterator();
|
||||
|
||||
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
|
||||
while (paraIt.hasNext()) {
|
||||
while (paraIt.hasNext()) {
|
||||
gtvs.put(tvarVarIt.next().getName(), paraIt.next());
|
||||
}
|
||||
Iterator<Method> methodIt = superclass.getMethods().iterator();
|
||||
//TODO: PL 2020-05-06: Hier müssen ueberschriebene Methoden noch rausgefiltert werden
|
||||
while(methodIt.hasNext()) {
|
||||
// TODO: PL 2020-05-06: Hier müssen ueberschriebene Methoden noch rausgefiltert
|
||||
// werden
|
||||
while (methodIt.hasNext()) {
|
||||
Method m = methodIt.next();
|
||||
ParameterList newParaList = new ParameterList(
|
||||
m.getParameterList()
|
||||
.getFormalparalist()
|
||||
.stream()
|
||||
.map(fp -> new FormalParameter(fp.getName(), fp.getType().acceptTV(new TypeExchanger(gtvs)), fp.getOffset()))
|
||||
.collect(Collectors.toCollection(ArrayList::new)), m.getParameterList().getOffset());
|
||||
cl.getMethods().add(new Method(m.modifier, m.name, m.getReturnType().acceptTV(new TypeExchanger(gtvs)), newParaList, m.block,
|
||||
//new GenericDeclarationList(newGenericsList, ((GenericDeclarationList)m.getGenerics()).getOffset()),
|
||||
(GenericDeclarationList)m.getGenerics(),
|
||||
m.getOffset(), true));
|
||||
m.getParameterList()
|
||||
.getFormalparalist()
|
||||
.stream()
|
||||
.map(fp -> new FormalParameter(fp.getName(), fp.getType().acceptTV(new TypeExchanger(gtvs)),
|
||||
fp.getOffset()))
|
||||
.collect(Collectors.toCollection(ArrayList::new)),
|
||||
m.getParameterList().getOffset());
|
||||
cl.getMethods()
|
||||
.add(new Method(m.modifier, m.name, m.getReturnType().acceptTV(new TypeExchanger(gtvs)), newParaList,
|
||||
m.block,
|
||||
// new GenericDeclarationList(newGenericsList,
|
||||
// ((GenericDeclarationList)m.getGenerics()).getOffset()),
|
||||
(GenericDeclarationList) m.getGenerics(),
|
||||
m.getOffset(), true));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
cl.setMethodsAdded();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
||||
//PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal hinzugefuegt werden
|
||||
//List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
|
||||
/* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt
|
||||
}
|
||||
allClasses.addAll(importedClasses);
|
||||
|
||||
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
|
||||
}
|
||||
|
||||
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
||||
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal
|
||||
@ -219,6 +209,22 @@ public class JavaTXCompiler {
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
|
||||
/*
|
||||
* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt
|
||||
* }
|
||||
* allClasses.addAll(importedClasses);
|
||||
*
|
||||
* return new TYPE(sourceFiles.values(), allClasses).getConstraints();
|
||||
* }
|
||||
*
|
||||
* public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile)
|
||||
* throws ClassNotFoundException {
|
||||
* // PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal
|
||||
* // hinzugefuegt werden
|
||||
* // List<ClassOrInterface> allClasses = new
|
||||
* // ArrayList<>();//environment.getAllAvailableClasses();
|
||||
* Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
*
|
||||
* /*
|
||||
* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt for
|
||||
* (SourceFile sf : sourceFiles.values()) { allClasses.addAll(sf.getClasses());
|
||||
* }
|
||||
@ -388,7 +394,8 @@ public class JavaTXCompiler {
|
||||
SourceFile sf = sourceFiles.get(f);
|
||||
allClasses.addAll(getAvailableClasses(sf));
|
||||
allClasses.addAll(sf.getClasses());
|
||||
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(f,classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList()));
|
||||
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(f, classLoader).stream()
|
||||
.map(ASTFactory::createClass).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
final ConstraintSet<Pair> cons = getConstraints();
|
||||
@ -510,7 +517,7 @@ public class JavaTXCompiler {
|
||||
}
|
||||
}
|
||||
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
|
||||
// JEWEILS ANDERE SEITE
|
||||
// JEWEILS ANDERE SEITE
|
||||
});
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
@ -536,13 +543,18 @@ public class JavaTXCompiler {
|
||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||
// logFile, log);
|
||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*.stream().map(x -> {
|
||||
Set<Set<UnifyPair>> ret = new HashSet<>();
|
||||
for (Constraint<UnifyPair> y : x) {
|
||||
ret.add(new HashSet<>(y));
|
||||
}
|
||||
return ret;
|
||||
}).collect(Collectors.toCollection(ArrayList::new))*/;
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*
|
||||
* .stream().map(x -> {
|
||||
* Set<Set<UnifyPair>> ret = new
|
||||
* HashSet<>();
|
||||
* for (Constraint<UnifyPair> y
|
||||
* : x) {
|
||||
* ret.add(new HashSet<>(y));
|
||||
* }
|
||||
* return ret;
|
||||
* }).collect(Collectors.
|
||||
* toCollection(ArrayList::new))
|
||||
*/;
|
||||
unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm,
|
||||
usedTasks);
|
||||
} catch (IOException e) {
|
||||
@ -558,13 +570,14 @@ public class JavaTXCompiler {
|
||||
SourceFile sf = sourceFiles.get(f);
|
||||
allClasses.addAll(getAvailableClasses(sf));
|
||||
allClasses.addAll(sf.getClasses());
|
||||
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(f,classLoader).stream().map(ASTFactory::createClass).collect(Collectors.toList()));
|
||||
allClasses.addAll(CompilationEnvironment.loadDefaultPackageClasses(f, classLoader).stream()
|
||||
.map(ASTFactory::createClass).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
final ConstraintSet<Pair> cons = getConstraints();
|
||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||
try {
|
||||
Writer logFile = //new OutputStreamWriter(new NullOutputStream());
|
||||
Writer logFile = // new OutputStreamWriter(new NullOutputStream());
|
||||
// new FileWriter(new
|
||||
// File(System.getProperty("user.dir")+"/resources/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName()));
|
||||
new FileWriter(new File(System.getProperty("user.dir") + "/logFiles/" + "log_"
|
||||
@ -584,7 +597,7 @@ public class JavaTXCompiler {
|
||||
return x;
|
||||
|
||||
};
|
||||
|
||||
|
||||
logFile.write("Unify:" + unifyCons.toString());
|
||||
System.out.println("Unify:" + unifyCons.toString());
|
||||
unifyCons = unifyCons.map(distributeInnerVars);
|
||||
@ -681,24 +694,28 @@ public class JavaTXCompiler {
|
||||
}
|
||||
}
|
||||
return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
|
||||
// JEWEILS ANDERE SEITE
|
||||
// JEWEILS ANDERE SEITE
|
||||
});
|
||||
|
||||
//PL 2020-02-05 alle Oder-Constraints Receiver und Parameter werden auf variance 1 gesetzt
|
||||
//Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für Parameter die Typen der Argumente links stehen
|
||||
//und die Typen der Rückgabewerte immer rechts stehen
|
||||
|
||||
|
||||
// PL 2020-02-05 alle Oder-Constraints Receiver und Parameter werden auf
|
||||
// variance 1 gesetzt
|
||||
// Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für
|
||||
// Parameter die Typen der Argumente links stehen
|
||||
// und die Typen der Rückgabewerte immer rechts stehen
|
||||
|
||||
/*
|
||||
unifyCons.getOderConstraints().forEach(z -> z.forEach(y -> y.forEach(x -> {
|
||||
if ((x.getLhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.SMALLERDOT) == 0) {
|
||||
((PlaceholderType) x.getLhsType()).setVariance((byte)1);
|
||||
}
|
||||
else if ((x.getRhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.EQUALSDOT) == 0) {
|
||||
((PlaceholderType) x.getRhsType()).setVariance((byte)-1);
|
||||
}
|
||||
})));
|
||||
*/
|
||||
|
||||
* unifyCons.getOderConstraints().forEach(z -> z.forEach(y -> y.forEach(x -> {
|
||||
* if ((x.getLhsType() instanceof PlaceholderType) &&
|
||||
* x.getPairOp().compareTo(PairOperator.SMALLERDOT) == 0) {
|
||||
* ((PlaceholderType) x.getLhsType()).setVariance((byte)1);
|
||||
* }
|
||||
* else if ((x.getRhsType() instanceof PlaceholderType) &&
|
||||
* x.getPairOp().compareTo(PairOperator.EQUALSDOT) == 0) {
|
||||
* ((PlaceholderType) x.getRhsType()).setVariance((byte)-1);
|
||||
* }
|
||||
* })));
|
||||
*/
|
||||
|
||||
System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
|
||||
Set<PlaceholderType> varianceTPHold;
|
||||
Set<PlaceholderType> varianceTPH = new HashSet<>();
|
||||
@ -724,13 +741,15 @@ public class JavaTXCompiler {
|
||||
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
|
||||
// logFile, log);
|
||||
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()//.stream().map(x -> {
|
||||
/*Set<Set<UnifyPair>> ret = new HashSet<>();
|
||||
for (Constraint<UnifyPair> y : x) {
|
||||
ret.add(new HashSet<>(y));
|
||||
}
|
||||
return ret;
|
||||
}).collect(Collectors.toCollection(ArrayList::new))*/;
|
||||
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> {
|
||||
/*
|
||||
* Set<Set<UnifyPair>> ret = new HashSet<>();
|
||||
* for (Constraint<UnifyPair> y : x) {
|
||||
* ret.add(new HashSet<>(y));
|
||||
* }
|
||||
* return ret;
|
||||
* }).collect(Collectors.toCollection(ArrayList::new))
|
||||
*/;
|
||||
if (resultmodel) {
|
||||
/* UnifyResultModel Anfang */
|
||||
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
|
||||
@ -830,14 +849,14 @@ public class JavaTXCompiler {
|
||||
}
|
||||
});
|
||||
phSetVariance = new ArrayList<>(phSet); // macht vermutlich keinen Sinn PL 2018-10-18, doch, es koennen neue
|
||||
// TPHs mit Variancen dazugekommen sein PL 2018-11-07
|
||||
// TPHs mit Variancen dazugekommen sein PL 2018-11-07
|
||||
phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x)));
|
||||
}
|
||||
return usedTPH;
|
||||
}
|
||||
|
||||
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
|
||||
CompilationUnitContext tree = JavaTXParser.parse(sourceFile);
|
||||
SourceFileContext tree = JavaTXParser.parse(sourceFile);
|
||||
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile, classLoader),
|
||||
new GenericsRegistry(null));
|
||||
SourceFile ret = generator.convert(tree, environment.packageCrawler, classLoader);
|
||||
@ -847,8 +866,9 @@ public class JavaTXCompiler {
|
||||
public void generateBytecodForFile(File path, HashMap<JavaClassName, byte[]> classFiles, SourceFile sf,
|
||||
List<ResultSet> typeinferenceResult) throws IOException {
|
||||
try {
|
||||
List<GenericGenratorResultForSourceFile> genericResults = getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult);
|
||||
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult, genericResults, sf,path, classLoader);
|
||||
List<GenericGenratorResultForSourceFile> genericResults = getGeneratedGenericResultsForAllSourceFiles(
|
||||
typeinferenceResult);
|
||||
BytecodeGen bytecodeGen = new BytecodeGen(classFiles, typeinferenceResult, genericResults, sf, path, classLoader);
|
||||
bytecodeGen.visit(sf);
|
||||
this.writeClassFile(bytecodeGen.getClassFiles(), path);
|
||||
} catch (ClassNotFoundException e) {
|
||||
@ -857,7 +877,6 @@ public class JavaTXCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles()
|
||||
throws ClassNotFoundException, IOException {
|
||||
List<GenericGenratorResultForSourceFile> result = new ArrayList<>();
|
||||
@ -889,17 +908,19 @@ public class JavaTXCompiler {
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
if(path != null)
|
||||
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
|
||||
* @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();
|
||||
@ -909,7 +930,9 @@ public class JavaTXCompiler {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param outputPath - can be null, then class file output is in the same directory as the parsed source files
|
||||
* @param outputPath - can be null, then class file output
|
||||
* is in the same directory as the
|
||||
* parsed source files
|
||||
* @param typeinferenceResult
|
||||
* @param simplifyResultsForAllSourceFiles
|
||||
* @throws IOException
|
||||
@ -920,10 +943,10 @@ public class JavaTXCompiler {
|
||||
HashMap<JavaClassName, byte[]> classFiles = new HashMap<>();
|
||||
SourceFile sf = sourceFiles.get(f);
|
||||
File path;
|
||||
if(outputPath == null){
|
||||
path = f.getParentFile(); //Set path to path of the parsed .jav file
|
||||
}else{
|
||||
path = new File(outputPath ,sf.getPkgName().replace(".","/")); //add package path to root path
|
||||
if (outputPath == null) {
|
||||
path = f.getParentFile(); // Set path to path of the parsed .jav file
|
||||
} else {
|
||||
path = new File(outputPath, sf.getPkgName().replace(".", "/")); // add package path to root path
|
||||
}
|
||||
BytecodeGen bytecodeGen = new BytecodeGen(classFiles, typeinferenceResult, simplifyResultsForAllSourceFiles,
|
||||
sf, path, classLoader);
|
||||
@ -947,53 +970,57 @@ public class JavaTXCompiler {
|
||||
System.out.println(name + ".class file generated");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* PL 2020-03-17 mit TypeExchanger in FCGenerator.java zusammenfuehren */
|
||||
/**
|
||||
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
|
||||
*/
|
||||
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
|
||||
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der
|
||||
* übergebenen Map aus.
|
||||
*/
|
||||
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric> {
|
||||
|
||||
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
|
||||
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
|
||||
|
||||
TypeExchanger(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs){
|
||||
this.gtvs = gtvs;
|
||||
}
|
||||
TypeExchanger(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) {
|
||||
this.gtvs = gtvs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
|
||||
params.add(param.acceptTV(this));
|
||||
}
|
||||
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
|
||||
return ret;
|
||||
}
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for (RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()) {
|
||||
params.add(param.acceptTV(this));
|
||||
}
|
||||
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
|
||||
SuperWildcardType ret = new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this), superWildcardType.getOffset());
|
||||
return ret;
|
||||
}
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
|
||||
SuperWildcardType ret = new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this),
|
||||
superWildcardType.getOffset());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
|
||||
return typePlaceholder; //TypePlaceholder der vererbert wird kann bei der Vererbung nicht instanziert werden.
|
||||
}
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
|
||||
return typePlaceholder; // TypePlaceholder der vererbert wird kann bei der Vererbung nicht instanziert
|
||||
// werden.
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
|
||||
ExtendsWildcardType ret = new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this), extendsWildcardType.getOffset());
|
||||
return ret;
|
||||
}
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
|
||||
ExtendsWildcardType ret = new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this),
|
||||
extendsWildcardType.getOffset());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
|
||||
if(! gtvs.containsKey(genericRefType.getParsedName()))
|
||||
throw new DebugException("Dieser Fall darf nicht auftreten");
|
||||
return gtvs.get(genericRefType.getParsedName());
|
||||
}
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
|
||||
if (!gtvs.containsKey(genericRefType.getParsedName()))
|
||||
throw new DebugException("Dieser Fall darf nicht auftreten");
|
||||
return gtvs.get(genericRefType.getParsedName());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,19 +9,22 @@ import java.util.*;
|
||||
import com.google.common.collect.Lists;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.DebugException;
|
||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.CompilationUnitContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
|
||||
import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext;
|
||||
import de.dhbwstuttgart.parser.scope.GatherNames;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
|
||||
/**
|
||||
* Stellt die Java-Environment dar und speichert alle Binarys, Librarys und Sourcefiles im zu kompilierenden Projekt
|
||||
* Stellt die Java-Environment dar und speichert alle Binarys, Librarys und
|
||||
* Sourcefiles im zu kompilierenden Projekt
|
||||
* Sie erstellt anhand dieser Informationen die JavaClassNameRegistry
|
||||
*
|
||||
* TODO: Zur Initialisierung der CompilationEnvironment sollten alle SourceFiles mit ANTLR geparst werden und alle Klassen Generics und Typen herausgefunden werden
|
||||
* TODO: Zur Initialisierung der CompilationEnvironment sollten alle SourceFiles
|
||||
* mit ANTLR geparst werden und alle Klassen Generics und Typen herausgefunden
|
||||
* werden
|
||||
*/
|
||||
public class CompilationEnvironment {
|
||||
private final List<URL> librarys;
|
||||
@ -29,8 +32,10 @@ public class CompilationEnvironment {
|
||||
public final PackageCrawler packageCrawler;
|
||||
|
||||
/**
|
||||
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien
|
||||
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von
|
||||
* java-Dateien
|
||||
* Die Environment enth<EFBFBD>lt automatisch die Java Standard Library
|
||||
*
|
||||
* @param sourceFiles die zu kompilierenden Dateien
|
||||
*/
|
||||
public CompilationEnvironment(List<File> sourceFiles) {
|
||||
@ -42,65 +47,74 @@ public class CompilationEnvironment {
|
||||
* https://stackoverflow.com/questions/46494112/classloaders-hierarchy-in-java-9
|
||||
*
|
||||
*/
|
||||
//String bootClassPath = System.getProperty("sun.boot.class.path");
|
||||
// DirectoryClassLoader cl = DirectoryClassLoader.getPlatformClassLoader();
|
||||
String bootClassPath = System.getProperty("java.class.path");
|
||||
// String bootClassPath = System.getProperty("sun.boot.class.path");
|
||||
// DirectoryClassLoader cl = DirectoryClassLoader.getPlatformClassLoader();
|
||||
String bootClassPath = System.getProperty("java.class.path");
|
||||
librarys = new ArrayList<>();
|
||||
for(String path : bootClassPath.split(File.pathSeparator)) {
|
||||
try {
|
||||
librarys.add(new URL("file:"+path));
|
||||
} catch (MalformedURLException e) {
|
||||
new DebugException("Fehler im Classpath auf diesem System");
|
||||
}
|
||||
for (String path : bootClassPath.split(File.pathSeparator)) {
|
||||
try {
|
||||
librarys.add(new URL("file:" + path));
|
||||
} catch (MalformedURLException e) {
|
||||
new DebugException("Fehler im Classpath auf diesem System");
|
||||
}
|
||||
//URLClassLoader loader = new URLClassLoader(new URL[0], cl);
|
||||
//librarys = Arrays.asList(loader.getURLs());
|
||||
}
|
||||
// URLClassLoader loader = new URLClassLoader(new URL[0], cl);
|
||||
// librarys = Arrays.asList(loader.getURLs());
|
||||
|
||||
this.sourceFiles = sourceFiles;
|
||||
this.packageCrawler = new PackageCrawler(librarys);
|
||||
this.packageCrawler = new PackageCrawler(librarys);
|
||||
}
|
||||
|
||||
public JavaClassRegistry getRegistry(File forSourceFile, ClassLoader classLoader) throws ClassNotFoundException, IOException {
|
||||
public JavaClassRegistry getRegistry(File forSourceFile, ClassLoader classLoader)
|
||||
throws ClassNotFoundException, IOException {
|
||||
Map<String, Integer> allNames;
|
||||
CompilationUnitContext tree = JavaTXParser.parse(forSourceFile);
|
||||
SourceFileContext tree = JavaTXParser.parse(forSourceFile);
|
||||
allNames = GatherNames.getNames(tree, packageCrawler, classLoader);
|
||||
for(Class c : loadDefaultPackageClasses(forSourceFile, classLoader)){
|
||||
for (Class c : loadDefaultPackageClasses(forSourceFile, classLoader)) {
|
||||
allNames.put(c.getName(), c.getTypeParameters().length);
|
||||
}
|
||||
return new JavaClassRegistry(allNames);
|
||||
}
|
||||
|
||||
public static List<Class> loadDefaultPackageClasses(File forSourceFile, ClassLoader classLoader) throws IOException, ClassNotFoundException {
|
||||
public static List<Class> loadDefaultPackageClasses(File forSourceFile, ClassLoader classLoader)
|
||||
throws IOException, ClassNotFoundException {
|
||||
List<Class> ret = new ArrayList<>();
|
||||
String packageName = getPackageName(JavaTXParser.parse(forSourceFile));
|
||||
//Set classLoader to include default package for this specific source file
|
||||
SourceFileContext srcfilectx = JavaTXParser.parse(forSourceFile);
|
||||
String packageName;
|
||||
if (srcfilectx instanceof SrcfileContext) {
|
||||
packageName = getPackageName((SrcfileContext) srcfilectx);
|
||||
} else {
|
||||
packageName = "";
|
||||
}
|
||||
// Set classLoader to include default package for this specific source file
|
||||
File dir = new File(forSourceFile.getAbsoluteFile().getParent());
|
||||
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;
|
||||
ArrayList<File> defaultPath = Lists.newArrayList(new File(path));
|
||||
classLoader = new DirectoryClassLoader(defaultPath, classLoader);
|
||||
//Gather all names in the default package for this source file (classes that are imported by default)
|
||||
File [] files = dir.listFiles((dir1, name) -> name.endsWith(".class"));
|
||||
if(files != null)for (File classFile : files) {
|
||||
String className = classFile.getName().substring(0,classFile.getName().length()-6);
|
||||
ret.add(classLoader.loadClass(packageName + className));
|
||||
}
|
||||
// Gather all names in the default package for this source file (classes that
|
||||
// are imported by default)
|
||||
File[] files = dir.listFiles((dir1, name) -> name.endsWith(".class"));
|
||||
if (files != null)
|
||||
for (File classFile : files) {
|
||||
String className = classFile.getName().substring(0, classFile.getName().length() - 6);
|
||||
ret.add(classLoader.loadClass(packageName + className));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static String getPackageName(CompilationUnitContext forTree){
|
||||
private static String getPackageName(SrcfileContext forTree) {
|
||||
String packageName = "";
|
||||
if(forTree.packageDeclaration() != null && forTree.packageDeclaration().Identifier() != null)
|
||||
for(TerminalNode subPackage : forTree.packageDeclaration().Identifier()){
|
||||
packageName += subPackage.toString() + ".";
|
||||
}
|
||||
if (forTree.packageDeclaration() != null && !forTree.packageDeclaration().qualifiedName().identifier().isEmpty())
|
||||
packageName = forTree.packageDeclaration().qualifiedName().getText();
|
||||
return packageName;
|
||||
}
|
||||
|
||||
public List<ClassOrInterface> getAllAvailableClasses() {
|
||||
List<ClassOrInterface> ret = new ArrayList<>();
|
||||
for(Class c : new PackageCrawler(librarys).getAllAvailableClasses()){
|
||||
for (Class c : new PackageCrawler(librarys).getAllAvailableClasses()) {
|
||||
ret.add(ASTFactory.createClass(c));
|
||||
}
|
||||
return ret;
|
||||
|
@ -16,24 +16,30 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class JavaTXParser {
|
||||
public static Java17Parser.CompilationUnitContext parse(File source) throws IOException, java.lang.ClassNotFoundException {
|
||||
public class JavaTXParser {
|
||||
public static Java17Parser.SourceFileContext parse(File source)
|
||||
throws IOException, java.lang.ClassNotFoundException {
|
||||
InputStream stream = new FileInputStream(source);
|
||||
//DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
|
||||
// DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
|
||||
CharStream input = CharStreams.fromStream(stream);
|
||||
Java17Lexer lexer = new Java17Lexer(input);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
Java17Parser parser = new Java17Parser(tokens);
|
||||
return parser.compilationUnit();
|
||||
return parser.sourceFile();
|
||||
/*
|
||||
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(source));
|
||||
return generator.convert(tree);
|
||||
*/
|
||||
* SyntaxTreeGenerator generator = new
|
||||
* SyntaxTreeGenerator(environment.getRegistry(source));
|
||||
* return generator.convert(tree);
|
||||
*/
|
||||
}
|
||||
|
||||
/* Für das Typsystem ist es notwendig, dass sich der Source in einer Datei befindet:
|
||||
public SourceFile parse(String fileContent) throws IOException, java.lang.ClassNotFoundException {
|
||||
return this.parse(new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Für das Typsystem ist es notwendig, dass sich der Source in einer Datei
|
||||
* befindet:
|
||||
* public SourceFile parse(String fileContent) throws IOException,
|
||||
* java.lang.ClassNotFoundException {
|
||||
* return this.parse(new
|
||||
* ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8)));
|
||||
* }
|
||||
*/
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user