Anpassungen der Grammatikregeln übernommen

This commit is contained in:
luca9913 2023-01-17 06:34:39 +01:00
parent b0bec83900
commit 6d52949215
3 changed files with 279 additions and 232 deletions

View File

@ -14,7 +14,7 @@ import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator; 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.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
@ -69,147 +69,137 @@ import java.util.stream.Collectors;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import org.apache.commons.io.output.NullOutputStream; import org.apache.commons.io.output.NullOutputStream;
public class JavaTXCompiler { 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
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel(); // System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden
private final ClassLoader classLoader; // soll?
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
//nur fuer Testzwecke of Generated Generics private final ClassLoader classLoader;
//wieder loeschen PL 2021-03-22
public FamilyOfGeneratedGenerics fogg; // nur fuer Testzwecke of Generated Generics wieder loeschen PL 2021-03-22
public FamilyOfGeneratedGenerics fogg;
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException { public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Arrays.asList(sourceFile), null); this(Arrays.asList(sourceFile), null);
} }
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
this(sourceFile); public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
this.log = log; this(sourceFile);
} this.log = log;
}
public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException { public JavaTXCompiler(List<File> sourceFiles) throws IOException, ClassNotFoundException {
this(sourceFiles, null); this(sourceFiles, null);
} }
public JavaTXCompiler(List<File> sources, List<File> contextPath) throws IOException, ClassNotFoundException {
if(contextPath == null || contextPath.isEmpty()){ public JavaTXCompiler(List<File> sources, List<File> contextPath) throws IOException, ClassNotFoundException {
//When no contextPaths are given, the working directory is the sources root 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"))); 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); environment = new CompilationEnvironment(sources);
for (File s : sources) { for (File s : sources) {
sourceFiles.put(s, parse(s)); sourceFiles.put(s, parse(s));
} }
//INSTANCE = this; // INSTANCE = this;
} }
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException { public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException {
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
List<ClassOrInterface> importedClasses = new ArrayList<>(); List<ClassOrInterface> importedClasses = new ArrayList<>();
ClassOrInterface objectClass = ASTFactory.createClass( ClassOrInterface objectClass = ASTFactory.createClass(
classLoader.loadClass(new JavaClassName("java.lang.Object").toString())); classLoader.loadClass(new JavaClassName("java.lang.Object").toString()));
//Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC // Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for (File forSourceFile : sourceFiles.keySet()){ for (File forSourceFile : sourceFiles.keySet()) {
for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) { for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) {
//TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet // TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
ClassOrInterface importedClass = ASTFactory.createClass( ClassOrInterface importedClass = ASTFactory.createClass(
classLoader.loadClass(name.toString())); classLoader.loadClass(name.toString()));
importedClasses.add(importedClass); importedClasses.add(importedClass);
} }
for(Class c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)){ for (Class c : CompilationEnvironment.loadDefaultPackageClasses(forSourceFile, classLoader)) {
ClassOrInterface importedClass = ASTFactory.createClass(c); ClassOrInterface importedClass = ASTFactory.createClass(c);
importedClasses.add(importedClass); importedClasses.add(importedClass);
} }
} }
for (File f : this.sourceFiles.keySet()) { for (File f : this.sourceFiles.keySet()) {
SourceFile sf = sourceFiles.get(f); SourceFile sf = sourceFiles.get(f);
sf = new SourceFile(sf.getPkgName(), sf = new SourceFile(sf.getPkgName(),
sf.KlassenVektor.stream() sf.KlassenVektor.stream()
.map(cl -> new ClassOrInterface(cl)) .map(cl -> new ClassOrInterface(cl))
.collect(Collectors.toCollection(ArrayList::new)), .collect(Collectors.toCollection(ArrayList::new)),
sf.imports); sf.imports);
//sf enthaelt neues Source-File, neue Klassen-Objekte und neue // sf enthaelt neues Source-File, neue Klassen-Objekte und neue
//ArrayListen-Objekte fuer Fields, Construktoren und Methoden // ArrayListen-Objekte fuer Fields, Construktoren und Methoden
//Alle anderen Objekte werden nur kopiert. // Alle anderen Objekte werden nur kopiert.
SourceFile sf_new = sf; SourceFile sf_new = sf;
sf.KlassenVektor.forEach(cl -> addMethods(sf_new, cl, importedClasses, objectClass)); sf.KlassenVektor.forEach(cl -> addMethods(sf_new, cl, importedClasses, objectClass));
allClasses.addAll(sf.getClasses()); allClasses.addAll(sf.getClasses());
} }
allClasses.addAll(importedClasses); allClasses.addAll(importedClasses);
return new TYPE(sourceFiles.values(), allClasses).getConstraints(); return new TYPE(sourceFiles.values(), allClasses).getConstraints();
} }
void addMethods(SourceFile sf, ClassOrInterface cl, List<ClassOrInterface> importedClasses, ClassOrInterface objectClass) { void addMethods(SourceFile sf, ClassOrInterface cl, List<ClassOrInterface> importedClasses,
ClassOrInterface objectClass) {
if (!cl.areMethodsAdded()) { if (!cl.areMethodsAdded()) {
ClassOrInterface superclass = null; ClassOrInterface superclass = null;
if (cl.getSuperClass().getName().equals(new JavaClassName("java.lang.Object"))) { if (cl.getSuperClass().getName().equals(new JavaClassName("java.lang.Object"))) {
superclass = objectClass; superclass = objectClass;
} } else {
else { Optional<ClassOrInterface> optSuperclass = importedClasses.stream().filter(x -> x.getClassName().equals(
Optional<ClassOrInterface> optSuperclass = cl.getSuperClass().getName())).findFirst();
importedClasses.stream().filter(x -> x.getClassName().equals(
cl.getSuperClass().getName())).findFirst();
if (optSuperclass.isPresent()) { if (optSuperclass.isPresent()) {
superclass = optSuperclass.get(); superclass = optSuperclass.get();
} } else {
else { optSuperclass = sf.KlassenVektor.stream().filter(x -> x.getClassName().equals(
optSuperclass = cl.getSuperClass().getName())).findFirst();
sf.KlassenVektor.stream().filter(x -> x.getClassName().equals(
cl.getSuperClass().getName())).findFirst();
if (optSuperclass.isPresent()) { if (optSuperclass.isPresent()) {
superclass = optSuperclass.get(); superclass = optSuperclass.get();
addMethods(sf, superclass, importedClasses, objectClass); addMethods(sf, superclass, importedClasses, objectClass);
} } else {
else { // throw new ClassNotFoundException("");
//throw new ClassNotFoundException("");
} }
} }
} }
Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt= cl.getSuperClass().getParaList().iterator(); Iterator<RefTypeOrTPHOrWildcardOrGeneric> paraIt = cl.getSuperClass().getParaList().iterator();
Iterator<GenericTypeVar> tvarVarIt = superclass.getGenerics().iterator(); Iterator<GenericTypeVar> tvarVarIt = superclass.getGenerics().iterator();
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>(); HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
while (paraIt.hasNext()) { while (paraIt.hasNext()) {
gtvs.put(tvarVarIt.next().getName(), paraIt.next()); gtvs.put(tvarVarIt.next().getName(), paraIt.next());
} }
Iterator<Method> methodIt = superclass.getMethods().iterator(); Iterator<Method> methodIt = superclass.getMethods().iterator();
//TODO: PL 2020-05-06: Hier müssen ueberschriebene Methoden noch rausgefiltert werden // TODO: PL 2020-05-06: Hier müssen ueberschriebene Methoden noch rausgefiltert
while(methodIt.hasNext()) { // werden
while (methodIt.hasNext()) {
Method m = methodIt.next(); Method m = methodIt.next();
ParameterList newParaList = new ParameterList( ParameterList newParaList = new ParameterList(
m.getParameterList() m.getParameterList()
.getFormalparalist() .getFormalparalist()
.stream() .stream()
.map(fp -> new FormalParameter(fp.getName(), fp.getType().acceptTV(new TypeExchanger(gtvs)), fp.getOffset())) .map(fp -> new FormalParameter(fp.getName(), fp.getType().acceptTV(new TypeExchanger(gtvs)),
.collect(Collectors.toCollection(ArrayList::new)), m.getParameterList().getOffset()); fp.getOffset()))
cl.getMethods().add(new Method(m.modifier, m.name, m.getReturnType().acceptTV(new TypeExchanger(gtvs)), newParaList, m.block, .collect(Collectors.toCollection(ArrayList::new)),
//new GenericDeclarationList(newGenericsList, ((GenericDeclarationList)m.getGenerics()).getOffset()), m.getParameterList().getOffset());
(GenericDeclarationList)m.getGenerics(), cl.getMethods()
m.getOffset(), true)); .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(); 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 { public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal // 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<>(); 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 * PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt for
* (SourceFile sf : sourceFiles.values()) { allClasses.addAll(sf.getClasses()); * (SourceFile sf : sourceFiles.values()) { allClasses.addAll(sf.getClasses());
* } * }
@ -388,7 +394,8 @@ public class JavaTXCompiler {
SourceFile sf = sourceFiles.get(f); SourceFile sf = sourceFiles.get(f);
allClasses.addAll(getAvailableClasses(sf)); allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses()); 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(); 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 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> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>(); Set<PlaceholderType> varianceTPH = new HashSet<>();
@ -536,13 +543,18 @@ public class JavaTXCompiler {
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure, // Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log); // logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure); // Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*.stream().map(x -> { List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()/*
Set<Set<UnifyPair>> ret = new HashSet<>(); * .stream().map(x -> {
for (Constraint<UnifyPair> y : x) { * Set<Set<UnifyPair>> ret = new
ret.add(new HashSet<>(y)); * HashSet<>();
} * for (Constraint<UnifyPair> y
return ret; * : x) {
}).collect(Collectors.toCollection(ArrayList::new))*/; * ret.add(new HashSet<>(y));
* }
* return ret;
* }).collect(Collectors.
* toCollection(ArrayList::new))
*/;
unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm, unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm,
usedTasks); usedTasks);
} catch (IOException e) { } catch (IOException e) {
@ -558,13 +570,14 @@ public class JavaTXCompiler {
SourceFile sf = sourceFiles.get(f); SourceFile sf = sourceFiles.get(f);
allClasses.addAll(getAvailableClasses(sf)); allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses()); 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(); final ConstraintSet<Pair> cons = getConstraints();
Set<Set<UnifyPair>> results = new HashSet<>(); Set<Set<UnifyPair>> results = new HashSet<>();
try { try {
Writer logFile = //new OutputStreamWriter(new NullOutputStream()); Writer logFile = // new OutputStreamWriter(new NullOutputStream());
// new FileWriter(new // new FileWriter(new
// File(System.getProperty("user.dir")+"/resources/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName())); // File(System.getProperty("user.dir")+"/resources/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName()));
new FileWriter(new File(System.getProperty("user.dir") + "/logFiles/" + "log_" new FileWriter(new File(System.getProperty("user.dir") + "/logFiles/" + "log_"
@ -584,7 +597,7 @@ public class JavaTXCompiler {
return x; return x;
}; };
logFile.write("Unify:" + unifyCons.toString()); logFile.write("Unify:" + unifyCons.toString());
System.out.println("Unify:" + unifyCons.toString()); System.out.println("Unify:" + unifyCons.toString());
unifyCons = unifyCons.map(distributeInnerVars); 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 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 // PL 2020-02-05 alle Oder-Constraints Receiver und Parameter werden auf
//Es wird davon ausgegangen, dass in OderConstraints in Bedingungen für Parameter die Typen der Argumente links stehen // variance 1 gesetzt
//und die Typen der Rückgabewerte immer rechts stehen // 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 -> { * unifyCons.getOderConstraints().forEach(z -> z.forEach(y -> y.forEach(x -> {
if ((x.getLhsType() instanceof PlaceholderType) && x.getPairOp().compareTo(PairOperator.SMALLERDOT) == 0) { * if ((x.getLhsType() instanceof PlaceholderType) &&
((PlaceholderType) x.getLhsType()).setVariance((byte)1); * 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); * 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()); System.out.println("Unify nach Oder-Constraints-Anpassung:" + unifyCons.toString());
Set<PlaceholderType> varianceTPHold; Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>(); Set<PlaceholderType> varianceTPH = new HashSet<>();
@ -724,13 +741,15 @@ public class JavaTXCompiler {
// Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure, // Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log); // logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure); // Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()//.stream().map(x -> { List<Set<Constraint<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> {
/*Set<Set<UnifyPair>> ret = new HashSet<>(); /*
for (Constraint<UnifyPair> y : x) { * Set<Set<UnifyPair>> ret = new HashSet<>();
ret.add(new HashSet<>(y)); * for (Constraint<UnifyPair> y : x) {
} * ret.add(new HashSet<>(y));
return ret; * }
}).collect(Collectors.toCollection(ArrayList::new))*/; * return ret;
* }).collect(Collectors.toCollection(ArrayList::new))
*/;
if (resultmodel) { if (resultmodel) {
/* UnifyResultModel Anfang */ /* UnifyResultModel Anfang */
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure); 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 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))); phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x)));
} }
return usedTPH; return usedTPH;
} }
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); SourceFileContext tree = JavaTXParser.parse(sourceFile);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile, classLoader), SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile, classLoader),
new GenericsRegistry(null)); new GenericsRegistry(null));
SourceFile ret = generator.convert(tree, environment.packageCrawler, classLoader); 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, public void generateBytecodForFile(File path, HashMap<JavaClassName, byte[]> classFiles, SourceFile sf,
List<ResultSet> typeinferenceResult) throws IOException { List<ResultSet> typeinferenceResult) throws IOException {
try { try {
List<GenericGenratorResultForSourceFile> genericResults = getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult); List<GenericGenratorResultForSourceFile> genericResults = getGeneratedGenericResultsForAllSourceFiles(
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult, genericResults, sf,path, classLoader); typeinferenceResult);
BytecodeGen bytecodeGen = new BytecodeGen(classFiles, typeinferenceResult, genericResults, sf, path, classLoader);
bytecodeGen.visit(sf); bytecodeGen.visit(sf);
this.writeClassFile(bytecodeGen.getClassFiles(), path); this.writeClassFile(bytecodeGen.getClassFiles(), path);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
@ -857,7 +877,6 @@ public class JavaTXCompiler {
} }
} }
public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles() public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles()
throws ClassNotFoundException, IOException { throws ClassNotFoundException, IOException {
List<GenericGenratorResultForSourceFile> result = new ArrayList<>(); 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 { public void generateBytecode(String path) throws ClassNotFoundException, IOException, BytecodeGeneratorError {
if(path != null) if (path != null)
generateBytecode(new File(path)); generateBytecode(new File(path));
else else
generateBytecode(); 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 { public void generateBytecode(File path) throws ClassNotFoundException, IOException, BytecodeGeneratorError {
List<ResultSet> typeinferenceResult = this.typeInference(); 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 typeinferenceResult
* @param simplifyResultsForAllSourceFiles * @param simplifyResultsForAllSourceFiles
* @throws IOException * @throws IOException
@ -920,10 +943,10 @@ public class JavaTXCompiler {
HashMap<JavaClassName, byte[]> classFiles = new HashMap<>(); HashMap<JavaClassName, byte[]> classFiles = new HashMap<>();
SourceFile sf = sourceFiles.get(f); SourceFile sf = sourceFiles.get(f);
File path; File path;
if(outputPath == null){ if (outputPath == null) {
path = f.getParentFile(); //Set path to path of the parsed .jav file path = f.getParentFile(); // Set path to path of the parsed .jav file
}else{ } else {
path = new File(outputPath ,sf.getPkgName().replace(".","/")); //add package path to root path path = new File(outputPath, sf.getPkgName().replace(".", "/")); // add package path to root path
} }
BytecodeGen bytecodeGen = new BytecodeGen(classFiles, typeinferenceResult, simplifyResultsForAllSourceFiles, BytecodeGen bytecodeGen = new BytecodeGen(classFiles, typeinferenceResult, simplifyResultsForAllSourceFiles,
sf, path, classLoader); sf, path, classLoader);
@ -947,53 +970,57 @@ public class JavaTXCompiler {
System.out.println(name + ".class file generated"); System.out.println(name + ".class file generated");
} }
} }
/* PL 2020-03-17 mit TypeExchanger in FCGenerator.java zusammenfuehren */ /* 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. * Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der
*/ * übergebenen Map aus.
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{ */
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric> {
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs; private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
TypeExchanger(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs){ TypeExchanger(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) {
this.gtvs = gtvs; this.gtvs = gtvs;
} }
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) { public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){ for (RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()) {
params.add(param.acceptTV(this)); params.add(param.acceptTV(this));
} }
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken()); RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
return ret; return ret;
} }
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) { public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
SuperWildcardType ret = new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this), superWildcardType.getOffset()); SuperWildcardType ret = new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this),
return ret; superWildcardType.getOffset());
} return ret;
}
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) { public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
return typePlaceholder; //TypePlaceholder der vererbert wird kann bei der Vererbung nicht instanziert werden. return typePlaceholder; // TypePlaceholder der vererbert wird kann bei der Vererbung nicht instanziert
} // werden.
}
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) { public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
ExtendsWildcardType ret = new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this), extendsWildcardType.getOffset()); ExtendsWildcardType ret = new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this),
return ret; extendsWildcardType.getOffset());
} return ret;
}
@Override @Override
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) { public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
if(! gtvs.containsKey(genericRefType.getParsedName())) if (!gtvs.containsKey(genericRefType.getParsedName()))
throw new DebugException("Dieser Fall darf nicht auftreten"); throw new DebugException("Dieser Fall darf nicht auftreten");
return gtvs.get(genericRefType.getParsedName()); return gtvs.get(genericRefType.getParsedName());
} }
} }
} }

View File

@ -9,19 +9,22 @@ import java.util.*;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import org.antlr.v4.runtime.tree.TerminalNode;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.parser.JavaTXParser; 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.GatherNames;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry; 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 * 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 { public class CompilationEnvironment {
private final List<URL> librarys; private final List<URL> librarys;
@ -29,8 +32,10 @@ public class CompilationEnvironment {
public final PackageCrawler packageCrawler; 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 * Die Environment enth<EFBFBD>lt automatisch die Java Standard Library
*
* @param sourceFiles die zu kompilierenden Dateien * @param sourceFiles die zu kompilierenden Dateien
*/ */
public CompilationEnvironment(List<File> sourceFiles) { public CompilationEnvironment(List<File> sourceFiles) {
@ -42,65 +47,74 @@ public class CompilationEnvironment {
* https://stackoverflow.com/questions/46494112/classloaders-hierarchy-in-java-9 * https://stackoverflow.com/questions/46494112/classloaders-hierarchy-in-java-9
* *
*/ */
//String bootClassPath = System.getProperty("sun.boot.class.path"); // String bootClassPath = System.getProperty("sun.boot.class.path");
// DirectoryClassLoader cl = DirectoryClassLoader.getPlatformClassLoader(); // DirectoryClassLoader cl = DirectoryClassLoader.getPlatformClassLoader();
String bootClassPath = System.getProperty("java.class.path"); String bootClassPath = System.getProperty("java.class.path");
librarys = new ArrayList<>(); librarys = new ArrayList<>();
for(String path : bootClassPath.split(File.pathSeparator)) { for (String path : bootClassPath.split(File.pathSeparator)) {
try { try {
librarys.add(new URL("file:"+path)); librarys.add(new URL("file:" + path));
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
new DebugException("Fehler im Classpath auf diesem System"); 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.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; Map<String, Integer> allNames;
CompilationUnitContext tree = JavaTXParser.parse(forSourceFile); SourceFileContext tree = JavaTXParser.parse(forSourceFile);
allNames = GatherNames.getNames(tree, packageCrawler, classLoader); 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); allNames.put(c.getName(), c.getTypeParameters().length);
} }
return new JavaClassRegistry(allNames); 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<>(); List<Class> ret = new ArrayList<>();
String packageName = getPackageName(JavaTXParser.parse(forSourceFile)); SourceFileContext srcfilectx = JavaTXParser.parse(forSourceFile);
//Set classLoader to include default package for this specific source file 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()); File dir = new File(forSourceFile.getAbsoluteFile().getParent());
String dirPath = dir.toString() + "/"; String dirPath = dir.toString() + "/";
if(packageName.length()>0)dirPath = dirPath.substring(0,dirPath.length() - packageName.length()); if (packageName.length() > 0)
dirPath = dirPath.substring(0, dirPath.length() - packageName.length());
String path = dirPath; String path = dirPath;
ArrayList<File> defaultPath = Lists.newArrayList(new File(path)); ArrayList<File> defaultPath = Lists.newArrayList(new File(path));
classLoader = new DirectoryClassLoader(defaultPath, classLoader); classLoader = new DirectoryClassLoader(defaultPath, classLoader);
//Gather all names in the default package for this source file (classes that are imported by default) // Gather all names in the default package for this source file (classes that
File [] files = dir.listFiles((dir1, name) -> name.endsWith(".class")); // are imported by default)
if(files != null)for (File classFile : files) { File[] files = dir.listFiles((dir1, name) -> name.endsWith(".class"));
String className = classFile.getName().substring(0,classFile.getName().length()-6); if (files != null)
ret.add(classLoader.loadClass(packageName + className)); for (File classFile : files) {
} String className = classFile.getName().substring(0, classFile.getName().length() - 6);
ret.add(classLoader.loadClass(packageName + className));
}
return ret; return ret;
} }
private static String getPackageName(CompilationUnitContext forTree){ private static String getPackageName(SrcfileContext forTree) {
String packageName = ""; String packageName = "";
if(forTree.packageDeclaration() != null && forTree.packageDeclaration().Identifier() != null) if (forTree.packageDeclaration() != null && !forTree.packageDeclaration().qualifiedName().identifier().isEmpty())
for(TerminalNode subPackage : forTree.packageDeclaration().Identifier()){ packageName = forTree.packageDeclaration().qualifiedName().getText();
packageName += subPackage.toString() + ".";
}
return packageName; return packageName;
} }
public List<ClassOrInterface> getAllAvailableClasses() { public List<ClassOrInterface> getAllAvailableClasses() {
List<ClassOrInterface> ret = new ArrayList<>(); List<ClassOrInterface> ret = new ArrayList<>();
for(Class c : new PackageCrawler(librarys).getAllAvailableClasses()){ for (Class c : new PackageCrawler(librarys).getAllAvailableClasses()) {
ret.add(ASTFactory.createClass(c)); ret.add(ASTFactory.createClass(c));
} }
return ret; return ret;

View File

@ -16,24 +16,30 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class JavaTXParser { public class JavaTXParser {
public static Java17Parser.CompilationUnitContext parse(File source) throws IOException, java.lang.ClassNotFoundException { public static Java17Parser.SourceFileContext parse(File source)
throws IOException, java.lang.ClassNotFoundException {
InputStream stream = new FileInputStream(source); InputStream stream = new FileInputStream(source);
//DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream); // DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
CharStream input = CharStreams.fromStream(stream); CharStream input = CharStreams.fromStream(stream);
Java17Lexer lexer = new Java17Lexer(input); Java17Lexer lexer = new Java17Lexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer); CommonTokenStream tokens = new CommonTokenStream(lexer);
Java17Parser parser = new Java17Parser(tokens); Java17Parser parser = new Java17Parser(tokens);
return parser.compilationUnit(); return parser.sourceFile();
/* /*
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(source)); * SyntaxTreeGenerator generator = new
return generator.convert(tree); * 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 { * Für das Typsystem ist es notwendig, dass sich der Source in einer Datei
return this.parse(new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8))); * befindet:
} * public SourceFile parse(String fileContent) throws IOException,
*/ * java.lang.ClassNotFoundException {
* return this.parse(new
* ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8)));
* }
*/
} }