diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index 22518b69..d4b9ea94 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -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 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 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 sourceFiles) throws IOException, ClassNotFoundException { this(sourceFiles, null); } - public JavaTXCompiler(List sources, List contextPath) throws IOException, ClassNotFoundException { - if(contextPath == null || contextPath.isEmpty()){ - //When no contextPaths are given, the working directory is the sources root + + public JavaTXCompiler(List sources, List 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 getConstraints() throws ClassNotFoundException, IOException { - List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); - List 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 getConstraints() throws ClassNotFoundException, IOException { + List allClasses = new ArrayList<>();// environment.getAllAvailableClasses(); + List 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 importedClasses, ClassOrInterface objectClass) { + allClasses.addAll(importedClasses); + return new TYPE(sourceFiles.values(), allClasses).getConstraints(); + } + + void addMethods(SourceFile sf, ClassOrInterface cl, List importedClasses, + ClassOrInterface objectClass) { if (!cl.areMethodsAdded()) { ClassOrInterface superclass = null; if (cl.getSuperClass().getName().equals(new JavaClassName("java.lang.Object"))) { superclass = objectClass; - } - else { - Optional optSuperclass = - importedClasses.stream().filter(x -> x.getClassName().equals( - cl.getSuperClass().getName())).findFirst(); + } else { + Optional 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 paraIt= cl.getSuperClass().getParaList().iterator(); + Iterator paraIt = cl.getSuperClass().getParaList().iterator(); Iterator tvarVarIt = superclass.getGenerics().iterator(); - + HashMap gtvs = new HashMap<>(); - while (paraIt.hasNext()) { + while (paraIt.hasNext()) { gtvs.put(tvarVarIt.next().getName(), paraIt.next()); } Iterator 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 getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException { - //PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal hinzugefuegt werden - //List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); - Set 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 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 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 getAvailableClasses(SourceFile forSourceFile) + * throws ClassNotFoundException { + * // PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal + * // hinzugefuegt werden + * // List allClasses = new + * // ArrayList<>();//environment.getAllAvailableClasses(); + * Set 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 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 varianceTPHold; Set varianceTPH = new HashSet<>(); @@ -536,13 +543,18 @@ public class JavaTXCompiler { // Set> result = unify.unifySequential(xConsSet, finiteClosure, // logFile, log); // Set> result = unify.unify(xConsSet, finiteClosure); - List>> oderConstraints = unifyCons.getOderConstraints()/*.stream().map(x -> { - Set> ret = new HashSet<>(); - for (Constraint y : x) { - ret.add(new HashSet<>(y)); - } - return ret; - }).collect(Collectors.toCollection(ArrayList::new))*/; + List>> oderConstraints = unifyCons.getOderConstraints()/* + * .stream().map(x -> { + * Set> ret = new + * HashSet<>(); + * for (Constraint 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 cons = getConstraints(); Set> 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 varianceTPHold; Set varianceTPH = new HashSet<>(); @@ -724,13 +741,15 @@ public class JavaTXCompiler { // Set> result = unify.unifySequential(xConsSet, finiteClosure, // logFile, log); // Set> result = unify.unify(xConsSet, finiteClosure); - List>> oderConstraints = unifyCons.getOderConstraints()//.stream().map(x -> { - /*Set> ret = new HashSet<>(); - for (Constraint y : x) { - ret.add(new HashSet<>(y)); - } - return ret; - }).collect(Collectors.toCollection(ArrayList::new))*/; + List>> oderConstraints = unifyCons.getOderConstraints()// .stream().map(x -> { + /* + * Set> ret = new HashSet<>(); + * for (Constraint 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 classFiles, SourceFile sf, List typeinferenceResult) throws IOException { try { - List genericResults = getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult); - BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult, genericResults, sf,path, classLoader); + List 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 getGeneratedGenericResultsForAllSourceFiles() throws ClassNotFoundException, IOException { List 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 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 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{ + * Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der + * übergebenen Map aus. + */ + private static class TypeExchanger implements TypeVisitor { - private final HashMap gtvs; + private final HashMap gtvs; - TypeExchanger(HashMap gtvs){ - this.gtvs = gtvs; - } + TypeExchanger(HashMap gtvs) { + this.gtvs = gtvs; + } - @Override - public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) { - List 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 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()); + } - } + } } diff --git a/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java index 4d942eb4..9e34c54f 100644 --- a/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java +++ b/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java @@ -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 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�lt automatisch die Java Standard Library + * * @param sourceFiles die zu kompilierenden Dateien */ public CompilationEnvironment(List 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 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 loadDefaultPackageClasses(File forSourceFile, ClassLoader classLoader) throws IOException, ClassNotFoundException { + public static List loadDefaultPackageClasses(File forSourceFile, ClassLoader classLoader) + throws IOException, ClassNotFoundException { List 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 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 getAllAvailableClasses() { List ret = new ArrayList<>(); - for(Class c : new PackageCrawler(librarys).getAllAvailableClasses()){ + for (Class c : new PackageCrawler(librarys).getAllAvailableClasses()) { ret.add(ASTFactory.createClass(c)); } return ret; diff --git a/src/main/java/de/dhbwstuttgart/parser/JavaTXParser.java b/src/main/java/de/dhbwstuttgart/parser/JavaTXParser.java index cb4c797e..4cbc5a40 100644 --- a/src/main/java/de/dhbwstuttgart/parser/JavaTXParser.java +++ b/src/main/java/de/dhbwstuttgart/parser/JavaTXParser.java @@ -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))); + * } + */ }