From f00f9c9215097a84392c0260985ac42ef1b171da Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Tue, 14 Nov 2017 19:36:24 +0100 Subject: [PATCH] =?UTF-8?q?Tempor=C3=A4r=20Lauff=C3=A4hige=20Version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../environment/CompilationEnvironment.java | 9 --- .../environment/PackageCrawler.java | 10 --- .../SyntaxTreeGenerator.java | 8 +-- .../SyntaxTreeGenerator/TypeGenerator.java | 2 +- .../parser/scope/GenericTypeName.java | 4 -- .../syntaxtree/ClassOrInterface.java | 8 +-- .../dhbwstuttgart/syntaxtree/Constructor.java | 6 +- .../syntaxtree/GenericTypeVar.java | 9 --- .../dhbwstuttgart/syntaxtree/TypeScope.java | 2 - .../syntaxtree/factory/ASTFactory.java | 19 ++---- .../syntaxtree/factory/UnifyTypeFactory.java | 68 ++----------------- .../assumptions/FieldAssumption.java | 11 ++- .../assumptions/MethodAssumption.java | 12 +--- .../assumptions/TypeInferenceInformation.java | 3 +- .../constraints/ConstraintsFactory.java | 58 ++++++++++++++++ .../typeinference/typeAlgo/TYPEStmt.java | 45 +++--------- .../unify/model/FiniteClosure.java | 45 ++++++------ .../typeinference/unify/model/TypeParams.java | 10 +-- test/javFiles/FC_Matrix.jav | 10 +++ test/typeinference/FCMatrixTest.java | 9 +++ test/typeinference/MatrixTest.java | 9 +++ 21 files changed, 150 insertions(+), 207 deletions(-) create mode 100644 src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java create mode 100644 test/javFiles/FC_Matrix.jav create mode 100644 test/typeinference/FCMatrixTest.java create mode 100644 test/typeinference/MatrixTest.java diff --git a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java index 9a632674..46a60139 100644 --- a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java +++ b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java @@ -60,13 +60,4 @@ 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 cec63562..47b58128 100644 --- a/src/de/dhbwstuttgart/environment/PackageCrawler.java +++ b/src/de/dhbwstuttgart/environment/PackageCrawler.java @@ -56,16 +56,6 @@ 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 ed9d82e2..830f9d37 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); + return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations, superClass); }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 = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart()); + superClass = ASTFactory.createObjectClass().getType(); } 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); + return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations, superClass); } private RefType convert(Java8Parser.SuperclassContext superclass) { @@ -434,7 +434,7 @@ public class SyntaxTreeGenerator{ }else{ genericParams = createEmptyGenericDeclarationList(ctx.Identifier()); } - RefType superClass = ASTFactory.createObjectType(); + RefType superClass = ASTFactory.createObjectClass().getType(); 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 b5042fba..c60ae322 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.createObjectType()); + ret.add(ASTFactory.createObjectClass().getType()); 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 c5355ebd..0cee932f 100644 --- a/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java +++ b/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java @@ -19,8 +19,4 @@ 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 5d5fc3e2..540bc993 100644 --- a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java +++ b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java @@ -60,12 +60,10 @@ 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<>(); @@ -76,10 +74,6 @@ 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 bb48be40..2fdfb04e 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) { - super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations), gtvDeclarations, offset); + GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations, RefType superClass) { + 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 * Konstruktor initialisieren */ - protected static Block prepareBlock(Block constructorBlock, List fieldInitializations){ + protected static Block prepareBlock(Block constructorBlock, List fieldInitializations, RefType superClass){ 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 02042ca3..c43fe068 100644 --- a/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java +++ b/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java @@ -1,7 +1,6 @@ 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; @@ -54,14 +53,6 @@ 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 f651648b..3631eb2e 100644 --- a/src/de/dhbwstuttgart/syntaxtree/TypeScope.java +++ b/src/de/dhbwstuttgart/syntaxtree/TypeScope.java @@ -2,8 +2,6 @@ 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 046b97b8..b3f628a7 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -5,7 +5,6 @@ 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; @@ -46,11 +45,7 @@ public class ASTFactory { java.lang.Class superjreClass = jreClass.getSuperclass(); RefType superClass; if(superjreClass != null){ - 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()); + superClass = (RefType) createType(superjreClass, name, ""); }else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!) superClass = (RefType) createType(java.lang.Object.class, name, ""); } @@ -88,12 +83,13 @@ public class ASTFactory { 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) { - // 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(); @@ -186,9 +182,6 @@ 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 7ad15acc..c154e86f 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -3,13 +3,11 @@ 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; @@ -28,73 +26,19 @@ 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 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 - */ + public static FiniteClosure generateFC(List fromAvailableClasses){ HashSet pairs = new HashSet<>(); - for(ClassOrInterface cly : fromClasses){ - pairs.addAll(getSuperTypes(cly, fromClasses)); + for(ClassOrInterface cl : fromAvailableClasses){ + UnifyType t1 = UnifyTypeFactory.convert(cl.getType()); + UnifyType t2 = UnifyTypeFactory.convert(cl.getSuperClass()); + pairs.add(generateSmallerPair(t1, t2)); } 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 2e568e48..88b2bd4a 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java @@ -1,22 +1,21 @@ 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 ClassOrInterface receiverClass; + private RefTypeOrTPHOrWildcardOrGeneric receiverType; private RefTypeOrTPHOrWildcardOrGeneric type; - public FieldAssumption(ClassOrInterface receiverType, + public FieldAssumption(RefTypeOrTPHOrWildcardOrGeneric receiverType, RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){ super(scope); this.type = type; - this.receiverClass = receiverType; + this.receiverType = receiverType; } - public ClassOrInterface getReceiverClass() { - return receiverClass; + public RefTypeOrTPHOrWildcardOrGeneric getReceiverType() { + return receiverType; } public RefTypeOrTPHOrWildcardOrGeneric getType() { diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java index af8d6fb7..bbeff0d7 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java @@ -1,6 +1,5 @@ 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; @@ -11,11 +10,11 @@ import java.util.List; import java.util.stream.Collectors; public class MethodAssumption extends Assumption{ - private ClassOrInterface receiver; + private RefType receiver; private RefTypeOrTPHOrWildcardOrGeneric retType; List params; - public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType, + public MethodAssumption(RefType receiver, RefTypeOrTPHOrWildcardOrGeneric retType, List params, TypeScope scope){ super(scope); this.receiver = receiver; @@ -23,14 +22,7 @@ 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 737cd0c4..90548e6d 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java @@ -46,8 +46,7 @@ public class TypeInferenceInformation { for(ClassOrInterface cl : classes){ for(Field m : cl.getFieldDecl()){ if(m.getName().equals(name)){ - - ret.add(new FieldAssumption(cl, checkGTV(m.getType()), new TypeScopeContainer(cl, m))); + ret.add(new FieldAssumption(cl.getType(), 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 new file mode 100644 index 00000000..3d1058da --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java @@ -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; + } + } + +} diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index e45f7326..bf063d71 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -6,12 +6,14 @@ 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.*; +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.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; @@ -111,10 +113,8 @@ 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,9 +122,6 @@ 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 @@ -216,15 +213,8 @@ 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(), thisType, PairOperator.EQUALSDOT, info.getCurrentTypeScope(), + aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info.getCurrentTypeScope(), createNullTypeScope(), getResolverInstance())); } @@ -290,21 +280,10 @@ public class TYPEStmt implements StatementVisitor{ protected Constraint generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver){ Constraint methodConstraint = new Constraint(); - 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(new Pair(forMethod.receiver.getType(), receiverType, - PairOperator.SMALLERDOT); - methodConstraint.add(new Pair(assumption.getReturnType(), forMethod.getType(), - PairOperator.EQUALSDOT)); + methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), + PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); + methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), + PairOperator.EQUALSDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info, resolver)); return methodConstraint; } @@ -323,7 +302,6 @@ 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++){ @@ -342,14 +320,13 @@ 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, retType, convertParams(m.getParameterList(),info), + ret.add(new MethodAssumption(cl.getType(), retType, convertParams(m.getParameterList(),info), createTypeScope(cl, m))); } } @@ -384,7 +361,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, ofType, convertParams(m.getParameterList(), + ret.add(new MethodAssumption(cl.getType(), 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 aba3d3f6..9ace0e51 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -17,18 +17,17 @@ 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 */ @@ -39,7 +38,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) { @@ -47,7 +46,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())); @@ -62,7 +61,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()) { @@ -76,7 +75,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) @@ -157,7 +156,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) @@ -241,7 +240,7 @@ public class FiniteClosure implements IFiniteClosure { return type.grArg(this); } - @Override + @Override public Set grArg(ReferenceType type) { Set result = new HashSet(); result.add(type); @@ -250,7 +249,7 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(FunNType type) { Set result = new HashSet(); result.add(type); @@ -268,7 +267,7 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(SuperType type) { Set result = new HashSet(); result.add(type); @@ -277,11 +276,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 @@ -289,12 +288,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) { @@ -317,7 +316,7 @@ public class FiniteClosure implements IFiniteClosure { } - @Override + @Override public Set smArg(SuperType type) { Set result = new HashSet(); result.add(type); @@ -330,20 +329,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)) @@ -393,7 +392,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 f40ecb2f..fd87eecc 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java @@ -24,10 +24,8 @@ 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; diff --git a/test/javFiles/FC_Matrix.jav b/test/javFiles/FC_Matrix.jav new file mode 100644 index 00000000..c5e5becc --- /dev/null +++ b/test/javFiles/FC_Matrix.jav @@ -0,0 +1,10 @@ +import java.util.Vector; +import java.util.AbstractList; + +class Matrix extends Vector> { + + methode(Matrix m) { + Vector> i; + methode(i); + } + } \ No newline at end of file diff --git a/test/typeinference/FCMatrixTest.java b/test/typeinference/FCMatrixTest.java new file mode 100644 index 00000000..1172ff09 --- /dev/null +++ b/test/typeinference/FCMatrixTest.java @@ -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"); + } +} \ No newline at end of file diff --git a/test/typeinference/MatrixTest.java b/test/typeinference/MatrixTest.java new file mode 100644 index 00000000..8cc587c9 --- /dev/null +++ b/test/typeinference/MatrixTest.java @@ -0,0 +1,9 @@ +package typeinference; + +import java.io.File; + +public class MatrixTest extends JavaTXCompilerTest{ + public MatrixTest() { + this.fileToTest = new File(rootDirectory+"Matrix.jav"); + } +} \ No newline at end of file