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,32 +69,34 @@ 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;
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?
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
// 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(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
@ -144,28 +146,24 @@ public class JavaTXCompiler {
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()) {
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(
} 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(
} 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 {
} else {
// throw new ClassNotFoundException("");
}
}
@ -178,17 +176,23 @@ public class JavaTXCompiler {
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
// 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()),
.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));
}
@ -197,20 +201,6 @@ public class JavaTXCompiler {
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
// hinzugefuegt werden
@ -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();
@ -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,7 +570,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();
@ -684,19 +697,23 @@ public class JavaTXCompiler {
// 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
// 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());
@ -725,12 +742,14 @@ public class JavaTXCompiler {
// 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))*/;
/*
* 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);
@ -837,7 +856,7 @@ public class JavaTXCompiler {
}
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,7 +866,8 @@ 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);
List<GenericGenratorResultForSourceFile> genericResults = getGeneratedGenericResultsForAllSourceFiles(
typeinferenceResult);
BytecodeGen bytecodeGen = new BytecodeGen(classFiles, typeinferenceResult, genericResults, sf, path, classLoader);
bytecodeGen.visit(sf);
this.writeClassFile(bytecodeGen.getClassFiles(), path);
@ -857,7 +877,6 @@ public class JavaTXCompiler {
}
}
public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles()
throws ClassNotFoundException, IOException {
List<GenericGenratorResultForSourceFile> result = new ArrayList<>();
@ -889,7 +908,8 @@ 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)
@ -899,7 +919,8 @@ 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(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
@ -950,7 +973,8 @@ public class JavaTXCompiler {
/* 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> {
@ -972,18 +996,21 @@ public class JavaTXCompiler {
@Override
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
SuperWildcardType ret = new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this), superWildcardType.getOffset());
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.
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());
ExtendsWildcardType ret = new ExtendsWildcardType(extendsWildcardType.getInnerType().acceptTV(this),
extendsWildcardType.getOffset());
return ret;
}

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) {
@ -60,9 +65,10 @@ public class CompilationEnvironment {
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)) {
allNames.put(c.getName(), c.getTypeParameters().length);
@ -70,31 +76,39 @@ public class CompilationEnvironment {
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));
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)
// 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) {
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;
}

View File

@ -17,23 +17,29 @@ import java.util.ArrayList;
import java.util.List;
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);
// 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)));
* }
*/
}