Temporär Lauffähige Version

This commit is contained in:
JanUlrich 2017-11-14 19:36:24 +01:00
parent b2825e2fa1
commit f00f9c9215
21 changed files with 150 additions and 207 deletions

View File

@ -60,13 +60,4 @@ public class CompilationEnvironment {
allNames = GatherNames.getNames(tree, new PackageCrawler(librarys)); allNames = GatherNames.getNames(tree, new PackageCrawler(librarys));
return new JavaClassRegistry(allNames); return new JavaClassRegistry(allNames);
} }
public List<ClassOrInterface> getAllAvailableClasses() {
List<ClassOrInterface> ret = new ArrayList<>();
for(Class c : new PackageCrawler(librarys).getAllAvailableClasses()){
ret.add(ASTFactory.createClass(c));
}
return ret;
}
} }

View File

@ -56,16 +56,6 @@ public class PackageCrawler {
return classes; return classes;
} }
public Set<Class<?>> getAllAvailableClasses(){
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
.setUrls(urls));
Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);
return classes;
}
public List<String> getClassNames(String packageName){ public List<String> getClassNames(String packageName){
List<String> nameList = new ArrayList(); List<String> nameList = new ArrayList();
Set<Class<?>> classes = getClassesInPackage(packageName); Set<Class<?>> classes = getClassesInPackage(packageName);

View File

@ -184,7 +184,7 @@ public class SyntaxTreeGenerator{
block = stmtGen.convert(body.block()); block = stmtGen.convert(body.block());
} }
if(parentClass.equals(new JavaClassName(name))){ if(parentClass.equals(new JavaClassName(name))){
return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations); return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations, superClass);
}else{ }else{
return new Method(modifiers, name, retType, modifiers, parameterList,block, gtvDeclarations, header.getStart()); return new Method(modifiers, name, retType, modifiers, parameterList,block, gtvDeclarations, header.getStart());
} }
@ -222,7 +222,7 @@ public class SyntaxTreeGenerator{
if(ctx.superclass() != null){ if(ctx.superclass() != null){
superClass = convert(ctx.superclass()); superClass = convert(ctx.superclass());
}else{ }else{
superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart()); superClass = ASTFactory.createObjectClass().getType();
} }
List<Field> fielddecl = convertFields(ctx.classBody(), generics); List<Field> fielddecl = convertFields(ctx.classBody(), generics);
List<Method> methods = convertMethods(ctx.classBody(), name, superClass, generics); List<Method> methods = convertMethods(ctx.classBody(), name, superClass, generics);
@ -269,7 +269,7 @@ public class SyntaxTreeGenerator{
int modifiers = 0; int modifiers = 0;
ParameterList params = new ParameterList(new ArrayList<>(), offset); ParameterList params = new ParameterList(new ArrayList<>(), offset);
Block block = new Block(new ArrayList<>(), offset); Block block = new Block(new ArrayList<>(), offset);
return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations); return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations, superClass);
} }
private RefType convert(Java8Parser.SuperclassContext superclass) { private RefType convert(Java8Parser.SuperclassContext superclass) {
@ -434,7 +434,7 @@ public class SyntaxTreeGenerator{
}else{ }else{
genericParams = createEmptyGenericDeclarationList(ctx.Identifier()); genericParams = createEmptyGenericDeclarationList(ctx.Identifier());
} }
RefType superClass = ASTFactory.createObjectType(); RefType superClass = ASTFactory.createObjectClass().getType();
List<Field> fields = convertFields(ctx.interfaceBody()); List<Field> fields = convertFields(ctx.interfaceBody());
List<Method> methods = convertMethods(ctx.interfaceBody(), name, superClass, generics); List<Method> methods = convertMethods(ctx.interfaceBody(), name, superClass, generics);

View File

@ -77,7 +77,7 @@ public class TypeGenerator {
public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) { public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
if(typeBoundContext == null){ if(typeBoundContext == null){
ret.add(ASTFactory.createObjectType()); ret.add(ASTFactory.createObjectClass().getType());
return ret; return ret;
} }
if(typeBoundContext.typeVariable() != null){ if(typeBoundContext.typeVariable() != null){

View File

@ -19,8 +19,4 @@ public class GenericTypeName extends JavaClassName {
+ DELIMITER + methodName + DELIMITER + methodName
+ DELIMITER + super.toString(); + DELIMITER + super.toString();
} }
public JavaClassName getParentClass() {
return parentClass;
}
} }

View File

@ -60,12 +60,10 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
return this.methods; return this.methods;
} }
/*
public RefType getType() { public RefType getType() {
return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset());
} }
*/
//TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt
public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){ public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){
//Hier wird immer ein generischer Typ generiert, also mit Type placeholdern //Hier wird immer ein generischer Typ generiert, also mit Type placeholdern
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
@ -76,10 +74,6 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
return new RefType(name, params, offset); return new RefType(name, params, offset);
} }
/**
* Die Superklasse im Kontext dieser ClassOrInterface
* Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind
*/
public RefType getSuperClass() { public RefType getSuperClass() {
return superClass; return superClass;
} }

View File

@ -15,8 +15,8 @@ public class Constructor extends Method {
//TODO: Constructor braucht ein super-Statement //TODO: Constructor braucht ein super-Statement
public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor,
GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations) { GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations, RefType superClass) {
super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations), gtvDeclarations, offset); super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations, superClass), gtvDeclarations, offset);
} }
@ -25,7 +25,7 @@ public class Constructor extends Method {
* welche die Felder der zugehörigen Klasse dieses * welche die Felder der zugehörigen Klasse dieses
* Konstruktor initialisieren * Konstruktor initialisieren
*/ */
protected static Block prepareBlock(Block constructorBlock, List<Statement> fieldInitializations){ protected static Block prepareBlock(Block constructorBlock, List<Statement> fieldInitializations, RefType superClass){
List<Statement> statements = constructorBlock.getStatements(); List<Statement> statements = constructorBlock.getStatements();
statements.add(0, new SuperCall(constructorBlock.getOffset())); statements.add(0, new SuperCall(constructorBlock.getOffset()));
return new Block(statements, constructorBlock.getOffset()); return new Block(statements, constructorBlock.getOffset());

View File

@ -1,7 +1,6 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.parser.scope.GenericTypeName; import de.dhbwstuttgart.parser.scope.GenericTypeName;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
@ -54,14 +53,6 @@ public class GenericTypeVar extends SyntaxTreeNode
return name; return name;
} }
public String getParsedName(){
return name.toString();
}
public JavaClassName definingClass(){
return name.getParentClass();
}
@Override @Override
public void accept(ASTVisitor visitor) { public void accept(ASTVisitor visitor) {
visitor.visit(this); visitor.visit(this);

View File

@ -2,8 +2,6 @@ package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import java.util.Collection;
public interface TypeScope { public interface TypeScope {
Iterable<? extends GenericTypeVar> getGenerics(); Iterable<? extends GenericTypeVar> getGenerics();

View File

@ -5,7 +5,6 @@ import java.lang.reflect.Constructor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext;
import de.dhbwstuttgart.parser.scope.GenericTypeName; import de.dhbwstuttgart.parser.scope.GenericTypeName;
@ -46,11 +45,7 @@ public class ASTFactory {
java.lang.Class superjreClass = jreClass.getSuperclass(); java.lang.Class superjreClass = jreClass.getSuperclass();
RefType superClass; RefType superClass;
if(superjreClass != null){ if(superjreClass != null){
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); superClass = (RefType) createType(superjreClass, name, "");
for(TypeVariable tv : superjreClass.getTypeParameters()){
params.add(new RefType(new GenericTypeName(new GenericContext( name, null),tv.getName()), new NullToken()));
}
superClass = new RefType(new JavaClassName(superjreClass.getName()), params, new NullToken());
}else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!) }else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!)
superClass = (RefType) createType(java.lang.Object.class, name, ""); superClass = (RefType) createType(java.lang.Object.class, name, "");
} }
@ -88,12 +83,13 @@ public class ASTFactory {
return null; return null;
} }
return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>()); return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>(),
createType(inClass.getSuperclass()));
} }
//private static RefType createType(Class classType) { private static RefType createType(Class classType) {
// return createClass(classType).getType(); return createClass(classType).getType();
//} }
public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){ public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){
String name = jreMethod.getName(); String name = jreMethod.getName();
@ -186,9 +182,6 @@ public class ASTFactory {
public static ClassOrInterface createObjectClass() { public static ClassOrInterface createObjectClass() {
return createClass(Object.class); return createClass(Object.class);
} }
public static RefType createObjectType() {
return new RefType(createClass(Object.class).getClassName(), new NullToken());
}
/* /*
public Constructor createEmptyConstructor(Class parent){ public Constructor createEmptyConstructor(Class parent){

View File

@ -3,13 +3,11 @@ package de.dhbwstuttgart.syntaxtree.factory;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
@ -28,73 +26,19 @@ import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
public class UnifyTypeFactory { public class UnifyTypeFactory {
public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses) throws ClassNotFoundException { public static FiniteClosure generateFC(List<ClassOrInterface> fromAvailableClasses){
/*
TODO: Generics werden zu TPHs
Die transitive Hülle muss funktionieren.
Man darf schreiben List<A> extends AL<A>
und Vector<B> extends List<B>
hier muss dann aber dennoch die Vererbung V < L < AL
hergestellt werden.
In einem solchen Vererbungsbaum dürfen die TPH auch die gleichen Namen haben.
Generell dürfen sie immer die gleichen Namen haben.
TODO: die transitive Hülle bilden
*/
HashSet<UnifyPair> pairs = new HashSet<>(); HashSet<UnifyPair> pairs = new HashSet<>();
for(ClassOrInterface cly : fromClasses){ for(ClassOrInterface cl : fromAvailableClasses){
pairs.addAll(getSuperTypes(cly, fromClasses)); UnifyType t1 = UnifyTypeFactory.convert(cl.getType());
UnifyType t2 = UnifyTypeFactory.convert(cl.getSuperClass());
pairs.add(generateSmallerPair(t1, t2));
} }
return new FiniteClosure(pairs); return new FiniteClosure(pairs);
} }
/**
* Bildet eine Kette vom übergebenen Typ bis hin zum höchsten bekannten Typ
* Als Generics werden TPHs benutzt, welche der Unifikationsalgorithmus korrekt interpretieren muss.
* Die verwendeten TPHs werden in der Kette nach oben gereicht, so erhält der selbe GTV immer den selben TPH
* @param forType
* @return
*/
private static List<UnifyPair> getSuperTypes(ClassOrInterface forType, List<ClassOrInterface> availableClasses) throws ClassNotFoundException {
return getSuperTypes(forType, availableClasses, new HashMap<>());
}
private static List<UnifyPair> getSuperTypes(ClassOrInterface forType, List<ClassOrInterface> availableClasses, HashMap<String, PlaceholderType> gtvs) throws ClassNotFoundException {
List<UnifyType> params = new ArrayList<>();
//Generics mit gleichem Namen müssen den selben TPH bekommen
for(GenericTypeVar gtv : forType.getGenerics()){
if(!gtvs.containsKey(gtv.getParsedName()))
gtvs.put(gtv.getParsedName(), PlaceholderType.freshPlaceholder());
params.add(gtvs.get(gtv.getParsedName()));
}
Optional<ClassOrInterface> hasSuperclass = availableClasses.stream().filter(cl -> forType.getSuperClass().getName().equals(cl.getClassName())).findAny();
ClassOrInterface superClass;
if(!hasSuperclass.isPresent()) //TODO: Wenn es die Object-Klasse ist, dann ist es in Ordnung, ansonsten Fehler ausgeben:
{
superClass = ASTFactory.createClass(ClassLoader.getSystemClassLoader().loadClass(forType.getSuperClass().getName().toString()));
}else{
superClass = hasSuperclass.get();
}
List<UnifyPair> superTypes;
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
superTypes = Arrays.asList(generateSmallerPair(convert(ASTFactory.createObjectType()), convert(ASTFactory.createObjectType())));
}else{
superTypes = getSuperTypes(superClass, availableClasses, gtvs);
}
TypeParams paramList = new TypeParams(params);
UnifyType t1 = new ReferenceType(forType.getClassName().toString(), paramList);
UnifyType t2 = superTypes.get(0).getLhsType();
UnifyPair ret = generateSmallerPair(t1, t2);
List<UnifyPair> retList = new ArrayList<>();
retList.add(ret);
retList.addAll(superTypes);
return retList;
}
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){ public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){
return new UnifyPair(tl, tr, PairOperator.SMALLER); return new UnifyPair(tl, tr, PairOperator.SMALLER);
} }

View File

@ -1,22 +1,21 @@
package de.dhbwstuttgart.typeinference.assumptions; package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class FieldAssumption extends Assumption{ public class FieldAssumption extends Assumption{
private ClassOrInterface receiverClass; private RefTypeOrTPHOrWildcardOrGeneric receiverType;
private RefTypeOrTPHOrWildcardOrGeneric type; private RefTypeOrTPHOrWildcardOrGeneric type;
public FieldAssumption(ClassOrInterface receiverType, public FieldAssumption(RefTypeOrTPHOrWildcardOrGeneric receiverType,
RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){ RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){
super(scope); super(scope);
this.type = type; this.type = type;
this.receiverClass = receiverType; this.receiverType = receiverType;
} }
public ClassOrInterface getReceiverClass() { public RefTypeOrTPHOrWildcardOrGeneric getReceiverType() {
return receiverClass; return receiverType;
} }
public RefTypeOrTPHOrWildcardOrGeneric getType() { public RefTypeOrTPHOrWildcardOrGeneric getType() {

View File

@ -1,6 +1,5 @@
package de.dhbwstuttgart.typeinference.assumptions; package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.statement.Assign; import de.dhbwstuttgart.syntaxtree.statement.Assign;
@ -11,11 +10,11 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class MethodAssumption extends Assumption{ public class MethodAssumption extends Assumption{
private ClassOrInterface receiver; private RefType receiver;
private RefTypeOrTPHOrWildcardOrGeneric retType; private RefTypeOrTPHOrWildcardOrGeneric retType;
List<RefTypeOrTPHOrWildcardOrGeneric> params; List<RefTypeOrTPHOrWildcardOrGeneric> params;
public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType, public MethodAssumption(RefType receiver, RefTypeOrTPHOrWildcardOrGeneric retType,
List<RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope){ List<RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope){
super(scope); super(scope);
this.receiver = receiver; this.receiver = receiver;
@ -23,14 +22,7 @@ public class MethodAssumption extends Assumption{
this.params = params; this.params = params;
} }
/*
public RefType getReceiverType() { public RefType getReceiverType() {
return receiver;
}
*/
public ClassOrInterface getReceiver(){
return receiver; return receiver;
} }

View File

@ -46,8 +46,7 @@ public class TypeInferenceInformation {
for(ClassOrInterface cl : classes){ for(ClassOrInterface cl : classes){
for(Field m : cl.getFieldDecl()){ for(Field m : cl.getFieldDecl()){
if(m.getName().equals(name)){ if(m.getName().equals(name)){
ret.add(new FieldAssumption(cl.getType(), checkGTV(m.getType()), new TypeScopeContainer(cl, m)));
ret.add(new FieldAssumption(cl, checkGTV(m.getType()), new TypeScopeContainer(cl, m)));
} }
} }
} }

View File

@ -0,0 +1,58 @@
package de.dhbwstuttgart.typeinference.constraints;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ConstraintsFactory {
public static Pair createPair(RefTypeOrTPHOrWildcardOrGeneric t1, RefTypeOrTPHOrWildcardOrGeneric t2,
PairOperator equalsdot, TypeScope currentScope, TypeScope additionalScope,
GenericsResolver resolver){
//Check whether Generics are in the same class and resolve all other generics:
return new Pair(checkGeneric(t1, currentScope, additionalScope,resolver),
checkGeneric(t2, currentScope,additionalScope, resolver), equalsdot);
}
public static Pair createPair(RefTypeOrTPHOrWildcardOrGeneric t1,
RefTypeOrTPHOrWildcardOrGeneric t2, TypeScope currentScope, TypeScope additionalScope,
GenericsResolver resolver){
return createPair(t1,t2,PairOperator.SMALLERDOT, currentScope, additionalScope, resolver);
}
private static RefTypeOrTPHOrWildcardOrGeneric checkGeneric(RefTypeOrTPHOrWildcardOrGeneric type,
TypeScope currentScope, TypeScope additionalScope,
GenericsResolver resolver){
if(type instanceof GenericRefType){
//TODO: Für Generics müssen auch noch Constraints generiert werden
for(GenericTypeVar genericTypeVar : currentScope.getGenerics()){
if(genericTypeVar.getName().toString().equals(((GenericRefType)type).getName().toString())){
return new RefType(((GenericRefType)type).getName(),type.getOffset());
}
}
//Nicht in den Generics in diesem Kontext enthalten:
TypePlaceholder ret = null;
for(GenericTypeVar genericTypeVar : additionalScope.getGenerics()){
if(genericTypeVar.getName().equals(((GenericRefType)type).getName())){
ret = resolver.resolve(genericTypeVar);
}
}
if(ret == null)
throw new DebugException("Der Generic " + ((GenericRefType) type).getName() + " kommt in keine TypeScope vor!");
return ret;
}else{
return type;
}
}
}

View File

@ -6,12 +6,14 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.parser.antlr.Java8Parser;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.FunN;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
@ -111,10 +113,8 @@ public class TYPEStmt implements StatementVisitor{
for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){ for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){
Constraint constraint = new Constraint(); Constraint constraint = new Constraint();
GenericsResolver resolver = getResolverInstance(); GenericsResolver resolver = getResolverInstance();
/*TODO Hier muss der Typ der Klasse ermittelt werden. In diesem müssen Generics mit TPHs ausgetauscht werden
constraint.add(ConstraintsFactory.createPair( constraint.add(ConstraintsFactory.createPair(
fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver));
*/
constraint.add(ConstraintsFactory.createPair( constraint.add(ConstraintsFactory.createPair(
fieldVar.getType(),fieldAssumption.getType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); fieldVar.getType(),fieldAssumption.getType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver));
oderConstraints.add(constraint); oderConstraints.add(constraint);
@ -122,9 +122,6 @@ public class TYPEStmt implements StatementVisitor{
if(oderConstraints.size() == 0) if(oderConstraints.size() == 0)
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset()); throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints); constraintsSet.addOderConstraint(oderConstraints);
//Wegen dem Problem oben:
throw new NotImplementedException();
} }
@Override @Override
@ -216,15 +213,8 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(This aThis) { public void visit(This aThis) {
//Im Falle von this, müssen die Generics in der Klasse als RefTypes behandelt werden.
ClassOrInterface currentClass = info.getCurrentClass();
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : currentClass.getGenerics()){
params.add(new GenericRefType(gtv.getName(), aThis.getOffset()));
}
RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset());
constraintsSet.addUndConstraint(ConstraintsFactory.createPair( constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
aThis.getType(), thisType, PairOperator.EQUALSDOT, info.getCurrentTypeScope(), aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info.getCurrentTypeScope(),
createNullTypeScope(), getResolverInstance())); createNullTypeScope(), getResolverInstance()));
} }
@ -290,21 +280,10 @@ public class TYPEStmt implements StatementVisitor{
protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption, protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver){ TypeInferenceBlockInformation info, GenericsResolver resolver){
Constraint methodConstraint = new Constraint(); Constraint methodConstraint = new Constraint();
ClassOrInterface receiverCl = assumption.getReceiver(); methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(),
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver));
for(GenericTypeVar gtv : receiverCl.getGenerics()){ methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(),
//if(gtv.definingClass().equals(info.getCurrentClass().getClassName())){ PairOperator.EQUALSDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver));
// params.add(new GenericRefType(gtv.getName(), forMethod.getOffset()));
//}else{
//Die Generics werden alle zu TPHs umgewandelt.
params.add(TypePlaceholder.fresh(forMethod.getOffset()));
//}
}
RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType,
PairOperator.SMALLERDOT);
methodConstraint.add(new Pair(assumption.getReturnType(), forMethod.getType(),
PairOperator.EQUALSDOT));
methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info, resolver)); methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info, resolver));
return methodConstraint; return methodConstraint;
} }
@ -323,7 +302,6 @@ public class TYPEStmt implements StatementVisitor{
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
List<MethodAssumption> ret = new ArrayList<>(); List<MethodAssumption> ret = new ArrayList<>();
/*
if(name.equals("apply")){ if(name.equals("apply")){
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
for(int i = 0; i< numArgs + 1 ; i++){ for(int i = 0; i< numArgs + 1 ; i++){
@ -342,14 +320,13 @@ public class TYPEStmt implements StatementVisitor{
} }
})); }));
} }
*/
for(ClassOrInterface cl : info.getAvailableClasses()){ for(ClassOrInterface cl : info.getAvailableClasses()){
for(Method m : cl.getMethods()){ for(Method m : cl.getMethods()){
if(m.getName().equals(name) && if(m.getName().equals(name) &&
m.getParameterList().getFormalparalist().size() == numArgs){ m.getParameterList().getFormalparalist().size() == numArgs){
RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType()); RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType());
ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info), ret.add(new MethodAssumption(cl.getType(), retType, convertParams(m.getParameterList(),info),
createTypeScope(cl, m))); createTypeScope(cl, m)));
} }
} }
@ -384,7 +361,7 @@ public class TYPEStmt implements StatementVisitor{
if(cl.getClassName().equals(ofType.getName())){ if(cl.getClassName().equals(ofType.getName())){
for(Method m : cl.getConstructors()){ for(Method m : cl.getConstructors()){
if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){ if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){
ret.add(new MethodAssumption(cl, ofType, convertParams(m.getParameterList(), ret.add(new MethodAssumption(cl.getType(), ofType, convertParams(m.getParameterList(),
info), createTypeScope(cl, m))); info), createTypeScope(cl, m)));
} }
} }

View File

@ -17,18 +17,17 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
* @author Florian Steurer * @author Florian Steurer
*/ */
public class FiniteClosure implements IFiniteClosure { public class FiniteClosure implements IFiniteClosure {
/** /**
* A map that maps every type to the node in the inheritance graph that contains that type. * A map that maps every type to the node in the inheritance graph that contains that type.
*/ */
private HashMap<UnifyType, Node<UnifyType>> inheritanceGraph; private HashMap<UnifyType, Node<UnifyType>> inheritanceGraph;
/** /**
* A map that maps every typename to the nodes of the inheritance graph that contain a type with that name. * A map that maps every typename to the nodes of the inheritance graph that contain a type with that name.
*/ */
private HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph; private HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph;
/** /**
* The initial pairs of that define the inheritance tree * The initial pairs of that define the inheritance tree
*/ */
@ -39,7 +38,7 @@ public class FiniteClosure implements IFiniteClosure {
*/ */
public FiniteClosure(Set<UnifyPair> pairs) { public FiniteClosure(Set<UnifyPair> pairs) {
this.pairs = new HashSet<>(pairs); this.pairs = new HashSet<>(pairs);
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>(); inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
// Build the transitive closure of the inheritance tree // Build the transitive closure of the inheritance tree
for(UnifyPair pair : pairs) { for(UnifyPair pair : pairs) {
@ -47,7 +46,7 @@ public class FiniteClosure implements IFiniteClosure {
continue; continue;
// Add nodes if not already in the graph // Add nodes if not already in the graph
if(!inheritanceGraph.containsKey(pair.getLhsType())) if(!inheritanceGraph.containsKey(pair.getLhsType()))
inheritanceGraph.put(pair.getLhsType(), new Node<UnifyType>(pair.getLhsType())); inheritanceGraph.put(pair.getLhsType(), new Node<UnifyType>(pair.getLhsType()));
if(!inheritanceGraph.containsKey(pair.getRhsType())) if(!inheritanceGraph.containsKey(pair.getRhsType()))
inheritanceGraph.put(pair.getRhsType(), new Node<UnifyType>(pair.getRhsType())); inheritanceGraph.put(pair.getRhsType(), new Node<UnifyType>(pair.getRhsType()));
@ -62,7 +61,7 @@ public class FiniteClosure implements IFiniteClosure {
parentNode.getPredecessors().stream().forEach(x -> x.addDescendant(childNode)); parentNode.getPredecessors().stream().forEach(x -> x.addDescendant(childNode));
childNode.getDescendants().stream().forEach(x -> x.addPredecessor(parentNode)); childNode.getDescendants().stream().forEach(x -> x.addPredecessor(parentNode));
} }
// Build the alternative representation with strings as keys // Build the alternative representation with strings as keys
strInheritanceGraph = new HashMap<>(); strInheritanceGraph = new HashMap<>();
for(UnifyType key : inheritanceGraph.keySet()) { for(UnifyType key : inheritanceGraph.keySet()) {
@ -76,7 +75,7 @@ public class FiniteClosure implements IFiniteClosure {
/** /**
* Returns all types of the finite closure that are subtypes of the argument. * Returns all types of the finite closure that are subtypes of the argument.
* @return The set of subtypes of the argument. * @return The set of subtypes of the argument.
*/ */
@Override @Override
public Set<UnifyType> smaller(UnifyType type) { public Set<UnifyType> smaller(UnifyType type) {
if(type instanceof FunNType) if(type instanceof FunNType)
@ -157,7 +156,7 @@ public class FiniteClosure implements IFiniteClosure {
/** /**
* Returns all types of the finite closure that are supertypes of the argument. * Returns all types of the finite closure that are supertypes of the argument.
* @return The set of supertypes of the argument. * @return The set of supertypes of the argument.
*/ */
@Override @Override
public Set<UnifyType> greater(UnifyType type) { public Set<UnifyType> greater(UnifyType type) {
if(type instanceof FunNType) if(type instanceof FunNType)
@ -241,7 +240,7 @@ public class FiniteClosure implements IFiniteClosure {
return type.grArg(this); return type.grArg(this);
} }
@Override @Override
public Set<UnifyType> grArg(ReferenceType type) { public Set<UnifyType> grArg(ReferenceType type) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
@ -250,7 +249,7 @@ public class FiniteClosure implements IFiniteClosure {
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(FunNType type) { public Set<UnifyType> grArg(FunNType type) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
@ -268,7 +267,7 @@ public class FiniteClosure implements IFiniteClosure {
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(SuperType type) { public Set<UnifyType> grArg(SuperType type) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
@ -277,11 +276,11 @@ public class FiniteClosure implements IFiniteClosure {
return result; return result;
} }
@Override @Override
public Set<UnifyType> grArg(PlaceholderType type) { public Set<UnifyType> grArg(PlaceholderType type) {
HashSet<UnifyType> result = new HashSet<>(); HashSet<UnifyType> result = new HashSet<>();
result.add(type); result.add(type);
return result; return result;
} }
@Override @Override
@ -289,12 +288,12 @@ public class FiniteClosure implements IFiniteClosure {
return type.smArg(this); return type.smArg(this);
} }
@Override @Override
public Set<UnifyType> smArg(ReferenceType type) { public Set<UnifyType> smArg(ReferenceType type) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
return result; return result;
} }
@Override @Override
public Set<UnifyType> smArg(FunNType type) { public Set<UnifyType> smArg(FunNType type) {
@ -317,7 +316,7 @@ public class FiniteClosure implements IFiniteClosure {
} }
@Override @Override
public Set<UnifyType> smArg(SuperType type) { public Set<UnifyType> smArg(SuperType type) {
Set<UnifyType> result = new HashSet<UnifyType>(); Set<UnifyType> result = new HashSet<UnifyType>();
result.add(type); result.add(type);
@ -330,20 +329,20 @@ public class FiniteClosure implements IFiniteClosure {
return result; return result;
} }
@Override @Override
public Set<UnifyType> smArg(PlaceholderType type) { public Set<UnifyType> smArg(PlaceholderType type) {
HashSet<UnifyType> result = new HashSet<>(); HashSet<UnifyType> result = new HashSet<>();
result.add(type); result.add(type);
return result; return result;
} }
@Override @Override
public Set<UnifyType> getAllTypesByName(String typeName) { public Set<UnifyType> getAllTypesByName(String typeName) {
if(!strInheritanceGraph.containsKey(typeName)) if(!strInheritanceGraph.containsKey(typeName))
return new HashSet<>(); return new HashSet<>();
return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new)); return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new));
} }
@Override @Override
public Optional<UnifyType> getLeftHandedType(String typeName) { public Optional<UnifyType> getLeftHandedType(String typeName) {
if(!strInheritanceGraph.containsKey(typeName)) if(!strInheritanceGraph.containsKey(typeName))
@ -393,7 +392,7 @@ public class FiniteClosure implements IFiniteClosure {
* @param result Set of all permutations found so far * @param result Set of all permutations found so far
* @param current The permutation of type params that is currently explored * @param current The permutation of type params that is currently explored
*/ */
protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) { protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
if(candidates.size() == idx) { if(candidates.size() == idx) {
result.add(new TypeParams(Arrays.copyOf(current, current.length))); result.add(new TypeParams(Arrays.copyOf(current, current.length)));
return; return;

View File

@ -24,10 +24,8 @@ public final class TypeParams implements Iterable<UnifyType>{
*/ */
public TypeParams(List<UnifyType> types){ public TypeParams(List<UnifyType> types){
typeParams = new UnifyType[types.size()]; typeParams = new UnifyType[types.size()];
for(int i=0;i<types.size();i++){ for(int i=0;i<types.size();i++)
typeParams[i] = types.get(i); typeParams[i] = types.get(i);
if(types.get(i)==null)throw new NullPointerException();
}
// Hashcode calculation is expensive and must be cached. // Hashcode calculation is expensive and must be cached.
hashCode = Arrays.deepHashCode(typeParams); hashCode = Arrays.deepHashCode(typeParams);
@ -151,11 +149,7 @@ public final class TypeParams implements Iterable<UnifyType>{
if(other.size() != this.size()) if(other.size() != this.size())
return false; return false;
for(int i = 0; i < this.size(); i++){
if(this.get(i) == null)
System.out.print("s");
}
for(int i = 0; i < this.size(); i++) for(int i = 0; i < this.size(); i++)
if(!(this.get(i).equals(other.get(i)))) if(!(this.get(i).equals(other.get(i))))
return false; return false;

View File

@ -0,0 +1,10 @@
import java.util.Vector;
import java.util.AbstractList;
class Matrix extends Vector<Vector<Integer>> {
methode(Matrix m) {
Vector<Vector<Integer>> i;
methode(i);
}
}

View File

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

View File

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