forked from JavaTX/JavaCompilerCore
113 lines
4.7 KiB
Java
113 lines
4.7 KiB
Java
package de.dhbwstuttgart.environment;
|
||
|
||
import java.io.File;
|
||
import java.io.IOException;
|
||
import java.net.MalformedURLException;
|
||
import java.net.URL;
|
||
import java.util.*;
|
||
|
||
import com.google.common.collect.Lists;
|
||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||
|
||
import de.dhbwstuttgart.exceptions.DebugException;
|
||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||
import de.dhbwstuttgart.parser.JavaTXParser;
|
||
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 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
|
||
*/
|
||
public class CompilationEnvironment {
|
||
private final List<URL> librarys;
|
||
private final List<File> sourceFiles;
|
||
public final PackageCrawler packageCrawler;
|
||
|
||
/**
|
||
* Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien Die Environment enth<74>lt automatisch die Java Standard Library
|
||
*
|
||
* @param sourceFiles die zu kompilierenden Dateien
|
||
*/
|
||
public CompilationEnvironment(List<File> sourceFiles) {
|
||
/**
|
||
* Java 9 bringt einige Änderungen am Classloader So funktioniert der BootClassLoader nicht mehr. hier gibts ein paar Quellen zum nachlesen: http://java9.wtf/class-loading/ 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");
|
||
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");
|
||
}
|
||
}
|
||
// URLClassLoader loader = new URLClassLoader(new URL[0], cl);
|
||
// librarys = Arrays.asList(loader.getURLs());
|
||
|
||
this.sourceFiles = sourceFiles;
|
||
this.packageCrawler = new PackageCrawler(librarys);
|
||
}
|
||
|
||
public void addClassesToRegistry(JavaClassRegistry registry, SourceFileContext tree, File sourceFile, JavaTXCompiler compiler) throws ClassNotFoundException, IOException {
|
||
Map<String, Integer> allNames;
|
||
if (tree instanceof SrcfileContext srcfile) {
|
||
allNames = GatherNames.getNames((SrcfileContext) tree, packageCrawler, compiler);
|
||
for (Class c : loadDefaultPackageClasses(getPackageName(srcfile), sourceFile, compiler)) {
|
||
allNames.put(c.getName(), c.getTypeParameters().length);
|
||
}
|
||
registry.addNames(allNames);
|
||
} else {
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
}
|
||
|
||
public static List<Class> loadDefaultPackageClasses(String packageName, File sourceFile, JavaTXCompiler compiler) throws IOException, ClassNotFoundException {
|
||
ClassLoader classLoader = compiler.getClassLoader();
|
||
List<Class> ret = new ArrayList<>();
|
||
// Set classLoader to include default package for this specific source file
|
||
File dir = sourceFile.getAbsoluteFile().getParentFile();
|
||
String dirPath = dir.toString() + "/";
|
||
if (packageName.length() > 0)
|
||
dirPath = dirPath.substring(0, dirPath.length() - packageName.length() - 1);
|
||
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);
|
||
if (className.matches("Fun\\d+\\$\\$.*"))
|
||
continue;
|
||
ret.add(classLoader.loadClass(packageName + className));
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
private static String getPackageName(SrcfileContext forTree) {
|
||
String packageName = "";
|
||
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()) {
|
||
ret.add(ASTFactory.createClass(c));
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
}
|