diff --git a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java index 46a60139..9a632674 100644 --- a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java +++ b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java @@ -60,4 +60,13 @@ public class CompilationEnvironment { allNames = GatherNames.getNames(tree, new PackageCrawler(librarys)); return new JavaClassRegistry(allNames); } + + public List getAllAvailableClasses() { + List ret = new ArrayList<>(); + for(Class c : new PackageCrawler(librarys).getAllAvailableClasses()){ + ret.add(ASTFactory.createClass(c)); + } + return ret; + } + } diff --git a/src/de/dhbwstuttgart/environment/PackageCrawler.java b/src/de/dhbwstuttgart/environment/PackageCrawler.java index 47b58128..cec63562 100644 --- a/src/de/dhbwstuttgart/environment/PackageCrawler.java +++ b/src/de/dhbwstuttgart/environment/PackageCrawler.java @@ -56,6 +56,16 @@ public class PackageCrawler { return classes; } + public Set> getAllAvailableClasses(){ + Reflections reflections = new Reflections(new ConfigurationBuilder() + .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner()) + .setUrls(urls)); + + Set> classes = reflections.getSubTypesOf(Object.class); + + return classes; + } + public List getClassNames(String packageName){ List nameList = new ArrayList(); Set> classes = getClassesInPackage(packageName); diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 830f9d37..ed9d82e2 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -184,7 +184,7 @@ public class SyntaxTreeGenerator{ block = stmtGen.convert(body.block()); } if(parentClass.equals(new JavaClassName(name))){ - return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations, superClass); + return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations); }else{ return new Method(modifiers, name, retType, modifiers, parameterList,block, gtvDeclarations, header.getStart()); } @@ -222,7 +222,7 @@ public class SyntaxTreeGenerator{ if(ctx.superclass() != null){ superClass = convert(ctx.superclass()); }else{ - superClass = ASTFactory.createObjectClass().getType(); + superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart()); } List fielddecl = convertFields(ctx.classBody(), generics); List methods = convertMethods(ctx.classBody(), name, superClass, generics); @@ -269,7 +269,7 @@ public class SyntaxTreeGenerator{ int modifiers = 0; ParameterList params = new ParameterList(new ArrayList<>(), offset); Block block = new Block(new ArrayList<>(), offset); - return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations, superClass); + return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations); } private RefType convert(Java8Parser.SuperclassContext superclass) { @@ -434,7 +434,7 @@ public class SyntaxTreeGenerator{ }else{ genericParams = createEmptyGenericDeclarationList(ctx.Identifier()); } - RefType superClass = ASTFactory.createObjectClass().getType(); + RefType superClass = ASTFactory.createObjectType(); List fields = convertFields(ctx.interfaceBody()); List methods = convertMethods(ctx.interfaceBody(), name, superClass, generics); diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index c60ae322..b5042fba 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -77,7 +77,7 @@ public class TypeGenerator { public static List convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) { List ret = new ArrayList<>(); if(typeBoundContext == null){ - ret.add(ASTFactory.createObjectClass().getType()); + ret.add(ASTFactory.createObjectType()); return ret; } if(typeBoundContext.typeVariable() != null){ diff --git a/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java b/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java index 0cee932f..c5355ebd 100644 --- a/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java +++ b/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java @@ -19,4 +19,8 @@ public class GenericTypeName extends JavaClassName { + DELIMITER + methodName + DELIMITER + super.toString(); } + + public JavaClassName getParentClass() { + return parentClass; + } } diff --git a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java index 540bc993..5d5fc3e2 100644 --- a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java +++ b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java @@ -60,10 +60,12 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ return this.methods; } + /* public RefType getType() { 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){ //Hier wird immer ein generischer Typ generiert, also mit Type placeholdern List params = new ArrayList<>(); @@ -74,6 +76,10 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ return new RefType(name, params, offset); } + /** + * Die Superklasse im Kontext dieser ClassOrInterface + * Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind + */ public RefType getSuperClass() { return superClass; } diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index 2fdfb04e..bb48be40 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -15,8 +15,8 @@ public class Constructor extends Method { //TODO: Constructor braucht ein super-Statement public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, - GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations, RefType superClass) { - super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations, superClass), gtvDeclarations, offset); + GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations) { + super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations), gtvDeclarations, offset); } @@ -25,7 +25,7 @@ public class Constructor extends Method { * welche die Felder der zugehörigen Klasse dieses * Konstruktor initialisieren */ - protected static Block prepareBlock(Block constructorBlock, List fieldInitializations, RefType superClass){ + protected static Block prepareBlock(Block constructorBlock, List fieldInitializations){ List statements = constructorBlock.getStatements(); statements.add(0, new SuperCall(constructorBlock.getOffset())); return new Block(statements, constructorBlock.getOffset()); diff --git a/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java b/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java index c43fe068..02042ca3 100644 --- a/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java +++ b/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.syntaxtree; import de.dhbwstuttgart.parser.scope.GenericTypeName; +import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import org.antlr.v4.runtime.Token; @@ -53,6 +54,14 @@ public class GenericTypeVar extends SyntaxTreeNode return name; } + public String getParsedName(){ + return name.toString(); + } + + public JavaClassName definingClass(){ + return name.getParentClass(); + } + @Override public void accept(ASTVisitor visitor) { visitor.visit(this); diff --git a/src/de/dhbwstuttgart/syntaxtree/TypeScope.java b/src/de/dhbwstuttgart/syntaxtree/TypeScope.java index 3631eb2e..f651648b 100644 --- a/src/de/dhbwstuttgart/syntaxtree/TypeScope.java +++ b/src/de/dhbwstuttgart/syntaxtree/TypeScope.java @@ -2,6 +2,8 @@ package de.dhbwstuttgart.syntaxtree; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import java.util.Collection; + public interface TypeScope { Iterable getGenerics(); diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java index b3f628a7..046b97b8 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -5,6 +5,7 @@ import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; +import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext; import de.dhbwstuttgart.parser.scope.GenericTypeName; @@ -45,7 +46,11 @@ public class ASTFactory { java.lang.Class superjreClass = jreClass.getSuperclass(); RefType superClass; if(superjreClass != null){ - superClass = (RefType) createType(superjreClass, name, ""); + List params = new ArrayList<>(); + 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!) superClass = (RefType) createType(java.lang.Object.class, name, ""); } @@ -83,13 +88,12 @@ public class ASTFactory { return null; } - return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>(), - createType(inClass.getSuperclass())); + return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>()); } - private static RefType createType(Class classType) { - return createClass(classType).getType(); - } + //private static RefType createType(Class classType) { + // return createClass(classType).getType(); + //} public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){ String name = jreMethod.getName(); @@ -182,6 +186,9 @@ public class ASTFactory { public static ClassOrInterface createObjectClass() { return createClass(Object.class); } + public static RefType createObjectType() { + return new RefType(createClass(Object.class).getClassName(), new NullToken()); + } /* public Constructor createEmptyConstructor(Class parent){ diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index c154e86f..7ad15acc 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -3,11 +3,13 @@ package de.dhbwstuttgart.syntaxtree.factory; import java.util.*; import java.util.stream.Collectors; +import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; @@ -26,19 +28,73 @@ import de.dhbwstuttgart.typeinference.unify.model.SuperType; import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; - public class UnifyTypeFactory { - public static FiniteClosure generateFC(List fromAvailableClasses){ + public static FiniteClosure generateFC(List fromClasses) throws ClassNotFoundException { + /* + TODO: Generics werden zu TPHs + Die transitive Hülle muss funktionieren. + Man darf schreiben List extends AL + und Vector extends List + 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 pairs = new HashSet<>(); - for(ClassOrInterface cl : fromAvailableClasses){ - UnifyType t1 = UnifyTypeFactory.convert(cl.getType()); - UnifyType t2 = UnifyTypeFactory.convert(cl.getSuperClass()); - pairs.add(generateSmallerPair(t1, t2)); + for(ClassOrInterface cly : fromClasses){ + pairs.addAll(getSuperTypes(cly, fromClasses)); } 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 getSuperTypes(ClassOrInterface forType, List availableClasses) throws ClassNotFoundException { + return getSuperTypes(forType, availableClasses, new HashMap<>()); + } + + private static List getSuperTypes(ClassOrInterface forType, List availableClasses, HashMap gtvs) throws ClassNotFoundException { + List 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 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 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 retList = new ArrayList<>(); + retList.add(ret); + retList.addAll(superTypes); + + return retList; + } + public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){ return new UnifyPair(tl, tr, PairOperator.SMALLER); } diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java index 88b2bd4a..2e568e48 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java @@ -1,21 +1,22 @@ package de.dhbwstuttgart.typeinference.assumptions; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; public class FieldAssumption extends Assumption{ - private RefTypeOrTPHOrWildcardOrGeneric receiverType; + private ClassOrInterface receiverClass; private RefTypeOrTPHOrWildcardOrGeneric type; - public FieldAssumption(RefTypeOrTPHOrWildcardOrGeneric receiverType, + public FieldAssumption(ClassOrInterface receiverType, RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){ super(scope); this.type = type; - this.receiverType = receiverType; + this.receiverClass = receiverType; } - public RefTypeOrTPHOrWildcardOrGeneric getReceiverType() { - return receiverType; + public ClassOrInterface getReceiverClass() { + return receiverClass; } public RefTypeOrTPHOrWildcardOrGeneric getType() { diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java index bbeff0d7..af8d6fb7 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.typeinference.assumptions; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.statement.Assign; @@ -10,11 +11,11 @@ import java.util.List; import java.util.stream.Collectors; public class MethodAssumption extends Assumption{ - private RefType receiver; + private ClassOrInterface receiver; private RefTypeOrTPHOrWildcardOrGeneric retType; List params; - public MethodAssumption(RefType receiver, RefTypeOrTPHOrWildcardOrGeneric retType, + public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType, List params, TypeScope scope){ super(scope); this.receiver = receiver; @@ -22,7 +23,14 @@ public class MethodAssumption extends Assumption{ this.params = params; } + /* public RefType getReceiverType() { + + return receiver; + } + */ + + public ClassOrInterface getReceiver(){ return receiver; } diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java b/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java index 90548e6d..737cd0c4 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java @@ -46,7 +46,8 @@ public class TypeInferenceInformation { for(ClassOrInterface cl : classes){ for(Field m : cl.getFieldDecl()){ 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))); } } } diff --git a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java index 3d1058da..043af210 100644 --- a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java +++ b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java @@ -17,6 +17,17 @@ import java.util.Map; public class ConstraintsFactory { + /** + * Erstellt ein Pair Element für den Unify. + * Die Methode löst gleichzeitig GTVs in den Typen t1 und t2 auf. + * @param t1 + * @param t2 + * @param equalsdot + * @param currentScope + * @param additionalScope + * @param resolver + * @return + */ public static Pair createPair(RefTypeOrTPHOrWildcardOrGeneric t1, RefTypeOrTPHOrWildcardOrGeneric t2, PairOperator equalsdot, TypeScope currentScope, TypeScope additionalScope, GenericsResolver resolver){ @@ -30,6 +41,7 @@ public class ConstraintsFactory { return createPair(t1,t2,PairOperator.SMALLERDOT, currentScope, additionalScope, resolver); } + private static RefTypeOrTPHOrWildcardOrGeneric checkGeneric(RefTypeOrTPHOrWildcardOrGeneric type, TypeScope currentScope, TypeScope additionalScope, GenericsResolver resolver){ diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index bf063d71..8062e173 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -6,14 +6,12 @@ import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Null; -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.syntaxtree.type.*; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; @@ -113,8 +111,10 @@ public class TYPEStmt implements StatementVisitor{ for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){ Constraint constraint = new Constraint(); 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( fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); + */ constraint.add(ConstraintsFactory.createPair( fieldVar.getType(),fieldAssumption.getType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); oderConstraints.add(constraint); @@ -122,6 +122,9 @@ public class TYPEStmt implements StatementVisitor{ if(oderConstraints.size() == 0) throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset()); constraintsSet.addOderConstraint(oderConstraints); + + //Wegen dem Problem oben: + throw new NotImplementedException(); } @Override @@ -213,8 +216,15 @@ public class TYPEStmt implements StatementVisitor{ @Override 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 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( - aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info.getCurrentTypeScope(), + aThis.getType(), thisType, PairOperator.EQUALSDOT, info.getCurrentTypeScope(), createNullTypeScope(), getResolverInstance())); } @@ -280,7 +290,18 @@ public class TYPEStmt implements StatementVisitor{ protected Constraint generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver){ Constraint methodConstraint = new Constraint(); - methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), + ClassOrInterface receiverCl = assumption.getReceiver(); + List params = new ArrayList<>(); + for(GenericTypeVar gtv : receiverCl.getGenerics()){ + //if(gtv.definingClass().equals(info.getCurrentClass().getClassName())){ + // 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(ConstraintsFactory.createPair(forMethod.receiver.getType(), receiverType, PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), PairOperator.EQUALSDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); @@ -302,6 +323,7 @@ public class TYPEStmt implements StatementVisitor{ public static List getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { List ret = new ArrayList<>(); + /* if(name.equals("apply")){ List funNParams = new ArrayList<>(); for(int i = 0; i< numArgs + 1 ; i++){ @@ -320,13 +342,14 @@ public class TYPEStmt implements StatementVisitor{ } })); } + */ for(ClassOrInterface cl : info.getAvailableClasses()){ for(Method m : cl.getMethods()){ if(m.getName().equals(name) && m.getParameterList().getFormalparalist().size() == numArgs){ RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType()); - ret.add(new MethodAssumption(cl.getType(), retType, convertParams(m.getParameterList(),info), + ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info), createTypeScope(cl, m))); } } @@ -361,7 +384,7 @@ public class TYPEStmt implements StatementVisitor{ if(cl.getClassName().equals(ofType.getName())){ for(Method m : cl.getConstructors()){ if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){ - ret.add(new MethodAssumption(cl.getType(), ofType, convertParams(m.getParameterList(), + ret.add(new MethodAssumption(cl, ofType, convertParams(m.getParameterList(), info), createTypeScope(cl, m))); } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 9ace0e51..aba3d3f6 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -17,17 +17,18 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; * @author Florian Steurer */ public class FiniteClosure implements IFiniteClosure { - + /** * A map that maps every type to the node in the inheritance graph that contains that type. - */ + */ private HashMap> inheritanceGraph; /** * A map that maps every typename to the nodes of the inheritance graph that contain a type with that name. */ private HashMap>> strInheritanceGraph; - + + /** * The initial pairs of that define the inheritance tree */ @@ -38,7 +39,7 @@ public class FiniteClosure implements IFiniteClosure { */ public FiniteClosure(Set pairs) { this.pairs = new HashSet<>(pairs); - inheritanceGraph = new HashMap>(); + inheritanceGraph = new HashMap>(); // Build the transitive closure of the inheritance tree for(UnifyPair pair : pairs) { @@ -46,7 +47,7 @@ public class FiniteClosure implements IFiniteClosure { continue; // Add nodes if not already in the graph - if(!inheritanceGraph.containsKey(pair.getLhsType())) + if(!inheritanceGraph.containsKey(pair.getLhsType())) inheritanceGraph.put(pair.getLhsType(), new Node(pair.getLhsType())); if(!inheritanceGraph.containsKey(pair.getRhsType())) inheritanceGraph.put(pair.getRhsType(), new Node(pair.getRhsType())); @@ -61,7 +62,7 @@ public class FiniteClosure implements IFiniteClosure { parentNode.getPredecessors().stream().forEach(x -> x.addDescendant(childNode)); childNode.getDescendants().stream().forEach(x -> x.addPredecessor(parentNode)); } - + // Build the alternative representation with strings as keys strInheritanceGraph = new HashMap<>(); for(UnifyType key : inheritanceGraph.keySet()) { @@ -75,7 +76,7 @@ public class FiniteClosure implements IFiniteClosure { /** * Returns all types of the finite closure that are subtypes of the argument. * @return The set of subtypes of the argument. - */ + */ @Override public Set smaller(UnifyType type) { if(type instanceof FunNType) @@ -156,7 +157,7 @@ public class FiniteClosure implements IFiniteClosure { /** * Returns all types of the finite closure that are supertypes of the argument. * @return The set of supertypes of the argument. - */ + */ @Override public Set greater(UnifyType type) { if(type instanceof FunNType) @@ -240,7 +241,7 @@ public class FiniteClosure implements IFiniteClosure { return type.grArg(this); } - @Override + @Override public Set grArg(ReferenceType type) { Set result = new HashSet(); result.add(type); @@ -249,7 +250,7 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(FunNType type) { Set result = new HashSet(); result.add(type); @@ -267,7 +268,7 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(SuperType type) { Set result = new HashSet(); result.add(type); @@ -276,11 +277,11 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(PlaceholderType type) { HashSet result = new HashSet<>(); result.add(type); - return result; + return result; } @Override @@ -288,12 +289,12 @@ public class FiniteClosure implements IFiniteClosure { return type.smArg(this); } - @Override + @Override public Set smArg(ReferenceType type) { Set result = new HashSet(); result.add(type); return result; - } + } @Override public Set smArg(FunNType type) { @@ -316,7 +317,7 @@ public class FiniteClosure implements IFiniteClosure { } - @Override + @Override public Set smArg(SuperType type) { Set result = new HashSet(); result.add(type); @@ -329,20 +330,20 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set smArg(PlaceholderType type) { HashSet result = new HashSet<>(); - result.add(type); + result.add(type); return result; } - @Override - public Set getAllTypesByName(String typeName) { + @Override + public Set getAllTypesByName(String typeName) { if(!strInheritanceGraph.containsKey(typeName)) return new HashSet<>(); return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new)); } - + @Override public Optional getLeftHandedType(String typeName) { if(!strInheritanceGraph.containsKey(typeName)) @@ -392,7 +393,7 @@ public class FiniteClosure implements IFiniteClosure { * @param result Set of all permutations found so far * @param current The permutation of type params that is currently explored */ - protected void permuteParams(ArrayList> candidates, int idx, Set result, UnifyType[] current) { + protected void permuteParams(ArrayList> candidates, int idx, Set result, UnifyType[] current) { if(candidates.size() == idx) { result.add(new TypeParams(Arrays.copyOf(current, current.length))); return; diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java index fd87eecc..f40ecb2f 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java @@ -24,8 +24,10 @@ public final class TypeParams implements Iterable{ */ public TypeParams(List types){ typeParams = new UnifyType[types.size()]; - for(int i=0;i{ if(other.size() != this.size()) 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++) if(!(this.get(i).equals(other.get(i)))) return false;