Typdeklarationen wie List, werden jetzt automatisch TPHs eingesetzt. (Als hätte man den Diamond-Operator benutzt)

This commit is contained in:
JanUlrich 2017-11-16 16:56:12 +01:00
parent 16e14f9363
commit 9a886ed223
8 changed files with 69 additions and 38 deletions

View File

@ -5,10 +5,7 @@ import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.ArrayList; import java.util.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
@ -55,7 +52,7 @@ public class CompilationEnvironment {
} }
public JavaClassRegistry getRegistry(File forSourceFile) throws ClassNotFoundException, IOException { public JavaClassRegistry getRegistry(File forSourceFile) throws ClassNotFoundException, IOException {
List<String> allNames; Map<String, Integer> allNames;
CompilationUnitContext tree = JavaTXParser.parse(forSourceFile); CompilationUnitContext tree = JavaTXParser.parse(forSourceFile);
allNames = GatherNames.getNames(tree, new PackageCrawler(librarys)); allNames = GatherNames.getNames(tree, new PackageCrawler(librarys));
return new JavaClassRegistry(allNames); return new JavaClassRegistry(allNames);

View File

@ -1,10 +1,7 @@
package de.dhbwstuttgart.environment; package de.dhbwstuttgart.environment;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.reflections.Reflections; import org.reflections.Reflections;
import org.reflections.scanners.ResourcesScanner; import org.reflections.scanners.ResourcesScanner;
@ -66,14 +63,14 @@ public class PackageCrawler {
return classes; return classes;
} }
public List<String> getClassNames(String packageName){ public Map<String, Integer> getClassNames(String packageName){
List<String> nameList = new ArrayList(); Map<String, Integer> nameList = new HashMap<>();
Set<Class<?>> classes = getClassesInPackage(packageName); Set<Class<?>> classes = getClassesInPackage(packageName);
if(packageName.equals("java.lang") && ! classes.contains(Object.class)) { if(packageName.equals("java.lang") && ! classes.contains(Object.class)) {
classes.add(Object.class); classes.add(Object.class);
} }
for(Class c : classes){ for(Class c : classes){
nameList.add(c.getName()); nameList.put(c.getName(), c.getTypeParameters().length);
} }
return nameList; return nameList;
} }

View File

@ -14,6 +14,7 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import java.util.ArrayList; import java.util.ArrayList;
@ -131,7 +132,11 @@ public class TypeGenerator {
} }
} }
if(typeArguments == null){ if(typeArguments == null){
return new RefType(reg.getName(name), offset); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(int i = 0; i<reg.getNumberOfGenerics(name);i++){
params.add(TypePlaceholder.fresh(offset));
}
return new RefType(reg.getName(name), params, offset);
}else{ }else{
return new RefType(reg.getName(name), convert(typeArguments, reg, generics), offset); return new RefType(reg.getName(name), convert(typeArguments, reg, generics), offset);
} }

View File

@ -1,7 +1,9 @@
package de.dhbwstuttgart.parser.scope; package de.dhbwstuttgart.parser.scope;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import de.dhbwstuttgart.parser.antlr.Java8BaseListener; import de.dhbwstuttgart.parser.antlr.Java8BaseListener;
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
@ -13,8 +15,8 @@ import de.dhbwstuttgart.parser.antlr.Java8Parser;
public class GatherNames { public class GatherNames {
public static List<String> getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException{ public static Map<String, Integer> getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException{
List<String> ret = new ArrayList<>(); Map<String, Integer> ret = new HashMap<>();
String pkgName = getPackageName(ctx); String pkgName = getPackageName(ctx);
String nameString = ""; String nameString = "";
for (Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){ for (Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){
@ -26,6 +28,8 @@ public class GatherNames {
else{ else{
nameString = typeDecl.interfaceDeclaration().normalInterfaceDeclaration().Identifier().toString(); nameString = typeDecl.interfaceDeclaration().normalInterfaceDeclaration().Identifier().toString();
} }
int numGenerics = typeDecl.interfaceDeclaration().normalInterfaceDeclaration().typeParameters()!=null?
typeDecl.interfaceDeclaration().normalInterfaceDeclaration().typeParameters().typeParameterList().typeParameter().size():0;
//Die Generic TypeParameter Definitionen Nicht! an die JavaClassName-Registry anfügen: //Die Generic TypeParameter Definitionen Nicht! an die JavaClassName-Registry anfügen:
/* //Diese gelängen dadurch in den globalen Scope, was sie schließlich nicht sind /* //Diese gelängen dadurch in den globalen Scope, was sie schließlich nicht sind
if(typeDecl.classDeclaration().normalClassDeclaration().typeParameters() != null){ if(typeDecl.classDeclaration().normalClassDeclaration().typeParameters() != null){
@ -34,7 +38,7 @@ public class GatherNames {
} }
} }
*/ */
ret.add(nameString); ret.put(nameString, numGenerics);
} }
} }
else{ else{
@ -53,30 +57,36 @@ public class GatherNames {
} }
} }
*/ */
ret.add(nameString); int numGenerics = typeDecl.classDeclaration().normalClassDeclaration().typeParameters()!=null?
typeDecl.classDeclaration().normalClassDeclaration().typeParameters().typeParameterList().typeParameter().size():0;
ret.put(nameString, numGenerics);
} }
} }
} }
ret.addAll(getImports(ctx, packages)); ret.putAll(getImports(ctx, packages));
return ret; return ret;
} }
private static List<String> getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException { private static Map<String, Integer> getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException {
List<String> ret = new ArrayList(); Map<String, Integer> ret = new HashMap<>();
ret.addAll(packages.getClassNames("java.lang")); ret.putAll(packages.getClassNames("java.lang"));
for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){ ClassLoader classLoader = ClassLoader.getSystemClassLoader();
for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){
if(importDeclCtx.singleTypeImportDeclaration() != null){ if(importDeclCtx.singleTypeImportDeclaration() != null){
ret.add(importDeclCtx.singleTypeImportDeclaration().typeName().getText()); Class cl = classLoader.loadClass(importDeclCtx.singleTypeImportDeclaration().typeName().getText());
ret.put(cl.getName(), cl.getTypeParameters().length);
} }
else if(importDeclCtx.typeImportOnDemandDeclaration() != null){ else if(importDeclCtx.typeImportOnDemandDeclaration() != null){
ret.addAll(packages.getClassNames(importDeclCtx.typeImportOnDemandDeclaration().packageOrTypeName().getText())); ret.putAll(packages.getClassNames(importDeclCtx.typeImportOnDemandDeclaration().packageOrTypeName().getText()));
} }
else if(importDeclCtx.singleStaticImportDeclaration() != null){ else if(importDeclCtx.singleStaticImportDeclaration() != null){
ret.add(importDeclCtx.singleStaticImportDeclaration().typeName().getText()+"."+importDeclCtx.singleStaticImportDeclaration().Identifier().getText()); Class cl = classLoader.loadClass(importDeclCtx.singleStaticImportDeclaration().typeName().getText()+"."+importDeclCtx.singleStaticImportDeclaration().Identifier().getText());
} ret.put(cl.getName(), cl.getTypeParameters().length);
}
else{ else{
ret.addAll(packages.getClassNames(importDeclCtx.staticImportOnDemandDeclaration().typeName().getText())); ret.putAll(packages.getClassNames(importDeclCtx.staticImportOnDemandDeclaration().typeName().getText()));
} }
} }
return ret; return ret;

View File

@ -49,8 +49,10 @@ public class JavaClassName {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode());
/*
result = prime * result result = prime * result
+ ((packageName == null) ? 0 : packageName.hashCode()); //PackageName does not infect hashCode + ((packageName == null) ? 0 : packageName.hashCode()); //PackageName does not infect hashCode
*/
return result; return result;
} }

View File

@ -8,20 +8,16 @@ import java.util.*;
* Speichert die Klassen f<EFBFBD>r einen bestimmten Projektscope * Speichert die Klassen f<EFBFBD>r einen bestimmten Projektscope
*/ */
public class JavaClassRegistry { public class JavaClassRegistry {
final List<JavaClassName> existingClasses = new ArrayList<>(); final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
public JavaClassRegistry(List<String> initialNames){ public JavaClassRegistry(Map<String, Integer> initialNames){
for(String name : initialNames){ for(String name : initialNames.keySet()){
existingClasses.add(new JavaClassName(name)); existingClasses.put(new JavaClassName(name), initialNames.get(name));
} }
} }
public void add(String className){
existingClasses.add(new JavaClassName(className));
}
public JavaClassName getName(String className) { public JavaClassName getName(String className) {
for(JavaClassName name : existingClasses){ for(JavaClassName name : existingClasses.keySet()){
if(name.equals(new JavaClassName(className)))return name; if(name.equals(new JavaClassName(className)))return name;
} }
throw new NotImplementedException(); throw new NotImplementedException();
@ -34,7 +30,7 @@ public class JavaClassRegistry {
public List<JavaClassName> getAllFromPackage(String packageName) { public List<JavaClassName> getAllFromPackage(String packageName) {
List<JavaClassName> ret = new ArrayList<>(); List<JavaClassName> ret = new ArrayList<>();
for(JavaClassName className : this.existingClasses){ for(JavaClassName className : this.existingClasses.keySet()){
JavaClassName toCompare = new JavaClassName(packageName + "." + JavaClassName.stripClassName(className.toString())); JavaClassName toCompare = new JavaClassName(packageName + "." + JavaClassName.stripClassName(className.toString()));
if(toCompare.toString().equals(className.toString())){ if(toCompare.toString().equals(className.toString())){
ret.add(className); ret.add(className);
@ -44,6 +40,10 @@ public class JavaClassRegistry {
} }
public boolean contains(String whole) { public boolean contains(String whole) {
return existingClasses.contains(new JavaClassName(whole)); return existingClasses.containsKey(new JavaClassName(whole));
}
public int getNumberOfGenerics(String name) {
return existingClasses.get(new JavaClassName(name));
} }
} }

View File

@ -0,0 +1,11 @@
public class LamRunnable{
public LamRunnable(){
Runnable lam = () -> {System.out.println("lambda");};
lam.run();
}
}

View File

@ -0,0 +1,9 @@
package typeinference;
import java.io.File;
public class RunnableTest extends JavaTXCompilerTest{
public RunnableTest() {
this.fileToTest = new File(rootDirectory+"LambdaRunnable.jav");
}
}