From 841ac5fcbfa9d19aa93365e84b3542a9f7b9fa66 Mon Sep 17 00:00:00 2001 From: Andreas Stadelmeier Date: Fri, 14 Jul 2017 17:47:02 +0200 Subject: [PATCH] PackageCrawler durch ClassLoader ersetzen --- .classpath | 5 +- src/de/dhbwstuttgart/core/JavaTXCompiler.java | 4 +- src/de/dhbwstuttgart/parser/JavaTXParser.java | 24 +++----- .../dhbwstuttgart/parser/PackageCrawler.java | 48 ---------------- src/de/dhbwstuttgart/parser/RunTXParser.java | 57 ------------------- .../SyntaxTreeGenerator.java | 17 ++---- .../typecheck/JavaClassName.java | 9 +++ .../typecheck/JavaClassRegistry.java | 25 +++++++- test/typeinference/JavaTXCompilerTest.java | 2 +- 9 files changed, 50 insertions(+), 141 deletions(-) delete mode 100644 src/de/dhbwstuttgart/parser/PackageCrawler.java delete mode 100644 src/de/dhbwstuttgart/parser/RunTXParser.java diff --git a/.classpath b/.classpath index 61250ae9..bebca6c3 100644 --- a/.classpath +++ b/.classpath @@ -4,19 +4,18 @@ - - - + + diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index 70503e1a..36cb6617 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -72,13 +72,13 @@ public class JavaTXCompiler { return ret; } - public SourceFile parse(File sourceFile) throws IOException, ClassNotFoundException { + public SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException { SourceFile ret = new JavaTXParser().parse(sourceFile); sourceFiles.add(ret); return ret; } - public SourceFile parse(String source) throws IOException, ClassNotFoundException { + public SourceFile parse(String source) throws IOException, java.lang.ClassNotFoundException { SourceFile ret = new JavaTXParser().parse(source); sourceFiles.add(ret); return ret; diff --git a/src/de/dhbwstuttgart/parser/JavaTXParser.java b/src/de/dhbwstuttgart/parser/JavaTXParser.java index b620f33e..970958af 100644 --- a/src/de/dhbwstuttgart/parser/JavaTXParser.java +++ b/src/de/dhbwstuttgart/parser/JavaTXParser.java @@ -14,35 +14,25 @@ import java.util.ArrayList; import java.util.List; public class JavaTXParser { - public SourceFile parse(InputStream source) throws IOException, ClassNotFoundException { + public SourceFile parse(InputStream source) throws IOException, java.lang.ClassNotFoundException { InputStream stream = source;//new FileInputStream(sourceFile); ANTLRInputStream input = new ANTLRInputStream(stream); Java8Lexer lexer = new Java8Lexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); Java8Parser parser = new Java8Parser(tokens); Java8Parser.CompilationUnitContext tree = parser.compilationUnit(); - - SyntaxTreeGenerator generator = new SyntaxTreeGenerator(new JavaClassRegistry(generateJavaLangNames())); + + JavaClassRegistry reg = new JavaClassRegistry(new ArrayList<>()); + reg.addPackage("java.lang"); + SyntaxTreeGenerator generator = new SyntaxTreeGenerator(reg); return generator.convert(tree); } - private List generateJavaLangNames() throws IOException, ClassNotFoundException { - List ret = new ArrayList<>(); - - for(Class cl : PackageCrawler.getClassesInPackage("java.lang")){ - ret.add(cl.getName()); - } - //TODO: Wieso muss man das händisch anhängen? - ret.add("java.lang.Object"); - - return ret; - } - - public SourceFile parse(File file) throws IOException, ClassNotFoundException { + public SourceFile parse(File file) throws IOException, java.lang.ClassNotFoundException { return this.parse(new FileInputStream(file)); } - public SourceFile parse(String fileContent) throws IOException, ClassNotFoundException { + public SourceFile parse(String fileContent) throws IOException, java.lang.ClassNotFoundException { return this.parse(new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8))); } } diff --git a/src/de/dhbwstuttgart/parser/PackageCrawler.java b/src/de/dhbwstuttgart/parser/PackageCrawler.java deleted file mode 100644 index 7028c8e7..00000000 --- a/src/de/dhbwstuttgart/parser/PackageCrawler.java +++ /dev/null @@ -1,48 +0,0 @@ -package de.dhbwstuttgart.parser; - -import de.dhbwstuttgart.typecheck.JavaClassName; -import org.reflections.Reflections; -import org.reflections.scanners.ResourcesScanner; -import org.reflections.scanners.SubTypesScanner; -import org.reflections.util.ClasspathHelper; -import org.reflections.util.ConfigurationBuilder; -import org.reflections.util.FilterBuilder; - -import java.util.LinkedList; -import java.util.List; -import java.util.ArrayList; -import java.util.Set; -import java.lang.InterruptedException; -/** - * Hilft beim Durchsuchen von Packages - * Benutzt die Reflections-Library (https://github.com/ronmamo/reflections) - * Hilfe dazu: http://stackoverflow.com/a/9571146 - */ -public class PackageCrawler { - - public static Set> getClassesInPackage(String packageName){ - List classLoadersList = new LinkedList(); - classLoadersList.add(Thread.currentThread().getContextClassLoader()); - classLoadersList.add(ClasspathHelper.staticClassLoader()); - classLoadersList.add(Thread.currentThread().getContextClassLoader().getParent()); - - Reflections reflections = new Reflections(new ConfigurationBuilder() - .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner()) - .setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0]))) - .filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix(packageName)))); - - Set> classes = reflections.getSubTypesOf(Object.class); - - return classes; - } - - // Returns a list of JavaClassNames. - public static List getClassNames(String packageName){ - List nameList = new ArrayList(); - Set> classes = getClassesInPackage(packageName); - for(Class c : classes){ - nameList.add(new JavaClassName(c.getName())); - } - return nameList; - } -} diff --git a/src/de/dhbwstuttgart/parser/RunTXParser.java b/src/de/dhbwstuttgart/parser/RunTXParser.java deleted file mode 100644 index 8d4c6d9e..00000000 --- a/src/de/dhbwstuttgart/parser/RunTXParser.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.dhbwstuttgart.parser; -import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator; -import de.dhbwstuttgart.parser.antlr.Java8Lexer; -import de.dhbwstuttgart.parser.antlr.Java8Parser; -import de.dhbwstuttgart.typecheck.JavaClassName; -import de.dhbwstuttgart.typecheck.JavaClassRegistry; -import org.antlr.v4.runtime.ANTLRInputStream; -import org.antlr.v4.runtime.CommonTokenStream; -import de.dhbwstuttgart.syntaxtree.*; - -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Scanner; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -public class RunTXParser{ - public static void main(String[] args){ - try{ - JavaTXParser parser = new JavaTXParser(); - SourceFile f = parser.parse(new File(args[0])); - String pkgName = f.getPkgName(); - System.out.println("package: " + pkgName); - System.out.println("Imports:"); - for(JavaClassName c : f.getImports()){ - System.out.println(c.toString()); - } - System.out.println("classes:"); - for(ClassOrInterface c : f.getClasses()){ - int mod = c.getModifiers(); - System.out.println(Modifier.toString(mod)); - System.out.println(c.getClassName().toString()); - System.out.println("{"); - for(Field field : c.getFieldDecl()){ - System.out.println(field.getName()); - } - System.out.println("}"); - } - } - catch(java.util.NoSuchElementException e){ - System.out.println("Error: Source seems to be empty."); - } - catch(ClassNotFoundException e){ - System.out.println("Class not found."); - } - catch(FileNotFoundException e){ - System.out.println("File not found."); - } - catch(IOException e){ - System.out.println("An exception occured which is on our TODO list."); - e.printStackTrace(); - } - } -} diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index d61fcb80..c27a5ac8 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -1,9 +1,8 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator; import de.dhbwstuttgart.exceptions.NotImplementedException; -import de.dhbwstuttgart.parser.ClassNotFoundException; +import java.lang.ClassNotFoundException; import de.dhbwstuttgart.parser.NullToken; -import de.dhbwstuttgart.parser.PackageCrawler; import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; @@ -136,16 +135,10 @@ public class SyntaxTreeGenerator{ private JavaClassName convertSingleTypeImportDeclaration(Java8Parser.SingleTypeImportDeclarationContext ctx) throws ClassNotFoundException{ String typeName = convertTypeName(ctx.typeName()); - String packageName = getPackageFromClass(typeName); - List classes = PackageCrawler.getClassNames(packageName); - reg.add(typeName); - JavaClassName ret = reg.getName(typeName); - if(classes.contains(ret)){ - return ret; - } - else{ - throw new ClassNotFoundException(); - } + Thread.currentThread().getContextClassLoader().loadClass(typeName); + reg.add(typeName); + JavaClassName ret = reg.getName(typeName); + return ret; } private JavaClassName convertTypeImportOnDemandDeclaration(Java8Parser.TypeImportOnDemandDeclarationContext ctx){ diff --git a/src/de/dhbwstuttgart/typecheck/JavaClassName.java b/src/de/dhbwstuttgart/typecheck/JavaClassName.java index 669cd469..83bd566e 100644 --- a/src/de/dhbwstuttgart/typecheck/JavaClassName.java +++ b/src/de/dhbwstuttgart/typecheck/JavaClassName.java @@ -34,6 +34,15 @@ public class JavaClassName { } } + /** + * Gibt von einem Klassennamen nur den Namen der Klasse zurück + * Beispiel: + * java.lang.Object wird zu: Object + */ + public static String stripClassName(String className) { + return new JavaClassName(className).name; + } + @Override public int hashCode() { final int prime = 31; diff --git a/src/de/dhbwstuttgart/typecheck/JavaClassRegistry.java b/src/de/dhbwstuttgart/typecheck/JavaClassRegistry.java index 0c70f98f..8bda1f0a 100644 --- a/src/de/dhbwstuttgart/typecheck/JavaClassRegistry.java +++ b/src/de/dhbwstuttgart/typecheck/JavaClassRegistry.java @@ -7,7 +7,8 @@ import java.util.List; * Speichert die Klassen im aktuellen Projektscope */ public class JavaClassRegistry { - public List existingClasses = new ArrayList<>(); + final List existingClasses = new ArrayList<>(); + final List importedPackages = new ArrayList<>(); public JavaClassRegistry(List initialNames){ for(String name : initialNames){ @@ -15,6 +16,15 @@ public class JavaClassRegistry { } } + /** + * Fügt ein gesamtes Package der ClassRegistry hinzu. + * Dies geschieht beispielsweise, wenn der Benutzer ein "import package.*;" statement verwendet + * @param packageName + */ + public void addPackage(String packageName) { + importedPackages.add(packageName); + } + public void add(String className){ existingClasses.add(new JavaClassName(className)); } @@ -23,6 +33,19 @@ public class JavaClassRegistry { for(JavaClassName name : existingClasses){ if(name.equals(new JavaClassName(className)))return name; } + //Jetzt noch alle importierten Packages durchsuchen: + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + String shortName = JavaClassName.stripClassName(className); + for(String packageName : importedPackages) { + try { + loader.loadClass(packageName+"."+shortName); + //Keine Exception! Die Klasse existiert: + JavaClassName ret = new JavaClassName(packageName+"."+shortName); + if(ret.equals(new JavaClassName(className)))return ret; + } catch (ClassNotFoundException e) { + //Die Klasse wurde nicht gefunden! + } + } throw new TypeNotPresentException(className, new Throwable()); } diff --git a/test/typeinference/JavaTXCompilerTest.java b/test/typeinference/JavaTXCompilerTest.java index c08efd9a..e774e4d4 100644 --- a/test/typeinference/JavaTXCompilerTest.java +++ b/test/typeinference/JavaTXCompilerTest.java @@ -32,7 +32,7 @@ public class JavaTXCompilerTest extends JavaTXCompiler { private static final List filesToTest = new ArrayList<>(); @Test - public void test() throws IOException, ClassNotFoundException { + public void test() throws IOException, java.lang.ClassNotFoundException { //filesToTest.add(new File(rootDirectory+"Faculty.jav")); filesToTest.add(new File(rootDirectory+"mathStruc.jav")); //filesToTest.add(new File(rootDirectory+"Lambda.jav"));