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.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());
}
}
}
}

View File

@ -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;

View File

@ -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)));
* }
*/
}