diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index 34e821f1..e8929729 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -14,6 +14,7 @@ import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.Pair; +import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; import de.dhbwstuttgart.typeinference.unify.TypeUnify; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; @@ -29,15 +30,13 @@ public class JavaTXCompiler { protected List sourceFiles = new ArrayList<>(); public ResultSet typeInference(){ - ConstraintSet cons = new ConstraintSet<>(); List allClasses = new ArrayList<>(); for(SourceFile sf : sourceFiles){ allClasses.addAll(sf.getClasses()); } FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses); - for(SourceFile sf : sourceFiles){ - cons.addAll(sf.getConstraints(sf.getTypeInferenceInformation(sourceFiles))); - } + ConstraintSet cons = new ConstraintSet<>(); + cons = new TYPE(sourceFiles).getConstraints(); ConstraintSet unifyCons = UnifyTypeFactory.convert(cons); TypeUnify unify = new TypeUnify(); diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/AssignToLocal.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/AssignToLocal.java new file mode 100644 index 00000000..c505bfb6 --- /dev/null +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/AssignToLocal.java @@ -0,0 +1,20 @@ +package de.dhbwstuttgart.parser.SyntaxTreeGenerator; + +import de.dhbwstuttgart.syntaxtree.StatementVisitor; +import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide; +import de.dhbwstuttgart.syntaxtree.statement.Expression; +import de.dhbwstuttgart.syntaxtree.statement.LocalVar; + +public class AssignToLocal extends AssignLeftSide { + public final LocalVar localVar; + + public AssignToLocal(LocalVar leftSide) { + super(leftSide.getType(), leftSide.getOffset()); + localVar = leftSide; + } + + @Override + public void accept(StatementVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index 03c72738..89bc4374 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -288,12 +288,15 @@ public class StatementGenerator { } private Statement convert(Java8Parser.AssignmentContext stmt) { - Expression leftHandSide = convert(stmt.leftHandSide()); + AssignLeftSide leftHandSide = convert(stmt.leftHandSide()); return new Assign(leftHandSide, convert(stmt.expression()), stmt.getStart()); } - private Expression convert(Java8Parser.LeftHandSideContext leftHandSide) { - return generateLocalOrFieldVarOrClassName(leftHandSide.getText(), leftHandSide.getStart()); + private AssignLeftSide convert(Java8Parser.LeftHandSideContext leftHandSide) { + Expression leftSide = generateLocalOrFieldVarOrClassName(leftHandSide.getText(), leftHandSide.getStart()); + if(leftSide instanceof FieldVar)return new AssignToField((FieldVar) leftSide); + else if (leftSide instanceof LocalVar)return new AssignToLocal((LocalVar) leftSide); + else throw new NotImplementedException(); } private Statement convert(Java8Parser.IfThenStatementContext stmt){ @@ -412,7 +415,8 @@ public class StatementGenerator { }else{ initValue = convert(varDecl.variableInitializer().expression()); } - ret.add(new Assign(new LocalVar(name.getText(), type, name.getSymbol()), initValue, name.getSymbol())); + ret.add(new Assign(new AssignToLocal(new LocalVar(name.getText(), type, name.getSymbol())) + , initValue, name.getSymbol())); } } return ret; @@ -426,9 +430,9 @@ public class StatementGenerator { }else{ initValue = convert(varDecl.variableInitializer().expression()); } - return (new Assign( + return (new Assign(new AssignToField( new FieldVar(new This(varDecl.getStart()), name.getText(), - new Void(varDecl.getStart()), varDecl.getStart()), + new Void(varDecl.getStart()), varDecl.getStart())), initValue, name.getSymbol())); } diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 941e7032..b6e85c9a 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -290,7 +290,7 @@ public class SyntaxTreeGenerator{ if(ctx.superclass() != null){ superClass = convert(ctx.superclass()); }else{ - superClass = new ASTFactory(reg).createObjectClass().getType(); + superClass = ASTFactory.createObjectClass().getType(); } Boolean isInterface = false; List implementedInterfaces = convert(ctx.superinterfaces(), generics); @@ -474,7 +474,7 @@ public class SyntaxTreeGenerator{ }else{ genericParams = createEmptyGenericDeclarationList(ctx.Identifier()); } - RefType superClass = new ASTFactory(reg).createObjectClass().getType(); + RefType superClass = ASTFactory.createObjectClass().getType(); List extendedInterfaces = convert(ctx.extendsInterfaces(), generics); diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index c1f608de..b5f72532 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -76,7 +76,7 @@ public class TypeGenerator { public static List convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) { if(typeBoundContext == null){ List ret = new ArrayList<>(); - ret.add(new ASTFactory(reg).createObjectClass().getType()); + ret.add(ASTFactory.createObjectClass().getType()); return ret; } diff --git a/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java b/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java index 420b8257..20e895b4 100644 --- a/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java +++ b/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java @@ -1,5 +1,7 @@ package de.dhbwstuttgart.syntaxtree; +import de.dhbwstuttgart.exceptions.NotImplementedException; +import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Null; @@ -61,7 +63,8 @@ public abstract class AbstractASTWalker implements ASTVisitor{ private void visitMethod(Method method){ method.getType().accept(this); method.getParameterList().accept(this); - method.block.accept(this); + if(method.block != null) + method.block.accept(this); } @Override @@ -250,4 +253,14 @@ public abstract class AbstractASTWalker implements ASTVisitor{ public void visit(Literal literal) { } + + @Override + public void visit(AssignToField assignLeftSide) { + assignLeftSide.field.accept(this); + } + + @Override + public void visit(AssignToLocal assignLeftSide) { + assignLeftSide.localVar.accept(this); + } } diff --git a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java index 1733a3ac..8c8dd698 100755 --- a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java +++ b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java @@ -58,14 +58,6 @@ public class ClassOrInterface extends SyntaxTreeNode { return this.methods; } - public ConstraintSet getConstraints(TypeInferenceInformation info) { - ConstraintSet ret = new ConstraintSet(); - for(Method m : this.getMethods()){ - ret.addAll(m.getConstraints(info, this)); - } - return ret; - } - public RefType getType() { return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); } diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index 219aeefe..9f085051 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -6,6 +6,7 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; +import de.dhbwstuttgart.typeinference.typeAlgo.TYPEStmt; import org.antlr.v4.runtime.Token; import de.dhbwstuttgart.syntaxtree.statement.Block; @@ -19,7 +20,7 @@ public class Constructor extends Method { /** * Das sind die Statements, welche die Felder der zugehörigen Klasse dieses Konstruktor initialisieren */ - private final List fieldInitializations; + public final List fieldInitializations; public Constructor(String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations) { super(name, returnType, modifiers, parameterList, codeInsideConstructor, gtvDeclarations, offset); @@ -27,15 +28,6 @@ public class Constructor extends Method { this.fieldInitializations = fieldInitializations; } - public ConstraintSet getConstraints(TypeInferenceInformation info, ClassOrInterface currentClass) { - TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, null); - TYPE methodScope = new TYPE(blockInfo); - for(Statement stmt : fieldInitializations)stmt.accept(methodScope); - ConstraintSet ret = super.getConstraints(info, currentClass); - ret.addAll(methodScope.getConstraints()); - return ret; - } - @Override public void accept(ASTVisitor visitor) { visitor.visit(this); diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index 065945ee..67d81cb4 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -8,6 +8,7 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; +import de.dhbwstuttgart.typeinference.typeAlgo.TYPEStmt; import org.antlr.v4.runtime.Token; import de.dhbwstuttgart.core.IItemWithOffset; @@ -36,14 +37,6 @@ public class Method extends Field implements IItemWithOffset, TypeScope this.generics = gtvDeclarations; } - public ConstraintSet getConstraints(TypeInferenceInformation info, ClassOrInterface currentClass) { - if(block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints - TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, this); - TYPE methodScope = new TYPE(blockInfo); - block.accept(methodScope); - return methodScope.getConstraints(); - } - public ParameterList getParameterList() { return parameterlist; } diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index 2278a00e..91c9b514 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -13,8 +13,8 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; public class SourceFile extends SyntaxTreeNode{ private String pkgName; - private final List KlassenVektor; - private final List imports; + public final List KlassenVektor; + public final List imports; /** * Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei. @@ -36,23 +36,6 @@ public class SourceFile extends SyntaxTreeNode{ return this.imports; } - public ConstraintSet getConstraints(TypeInferenceInformation info) { - ConstraintSet ret = new ConstraintSet(); - for (ClassOrInterface cl : this.KlassenVektor) { - ret.addAll(cl.getConstraints(info)); - } - return ret; - } - - public TypeInferenceInformation getTypeInferenceInformation(List sourceFiles){ - Set classes = new HashSet<>(); - for(SourceFile sourceFile : sourceFiles){ - classes.addAll(sourceFile.KlassenVektor); - } - - return new TypeInferenceInformation(classes); - } - public List getClasses() { return KlassenVektor; } diff --git a/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java b/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java index cb4a5c7b..dce80777 100644 --- a/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java +++ b/src/de/dhbwstuttgart/syntaxtree/StatementVisitor.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.syntaxtree; +import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Null; @@ -58,4 +59,8 @@ public interface StatementVisitor { void visit(Null aNull); void visit(Literal literal); + + void visit(AssignToField assignLeftSide); + + void visit(AssignToLocal assignLeftSide); } diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java index e46eec3a..68a15342 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -25,15 +25,9 @@ import org.antlr.v4.runtime.Token; * dass alle Imports und Typnamen korrekt sind und müssen diese nicht überprüfen. */ public class ASTFactory { - private final JavaClassRegistry names; - - public ASTFactory(JavaClassRegistry scope){ - names = scope; - } - - public ClassOrInterface createClass(java.lang.Class jreClass){ - JavaClassName name = names.getName(jreClass.getName()); + public static ClassOrInterface createClass(java.lang.Class jreClass){ + JavaClassName name = new JavaClassName(jreClass.getName()); List methoden = new ArrayList<>(); List konstruktoren = new ArrayList<>(); for(java.lang.reflect.Constructor constructor : jreClass.getConstructors()){ @@ -63,13 +57,13 @@ public class ASTFactory { return new ClassOrInterface(modifier, name, felder, methoden, konstruktoren, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset); } - private de.dhbwstuttgart.syntaxtree.Constructor createConstructor(Constructor constructor, Class inClass) { + private static de.dhbwstuttgart.syntaxtree.Constructor createConstructor(Constructor constructor, Class inClass) { String name = constructor.getName(); - RefTypeOrTPHOrWildcardOrGeneric returnType = createType(inClass, names.getName(inClass.getName()), name); + RefTypeOrTPHOrWildcardOrGeneric returnType = createType(inClass, new JavaClassName(inClass.getName()), name); Parameter[] jreParams = constructor.getParameters(); List params = new ArrayList<>(); for(Parameter jreParam : jreParams){ - RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam.getType(),names.getName(inClass.getName()), name); + RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam.getType(),new JavaClassName(inClass.getName()), name); params.add(new FormalParameter(jreParam.getName(),paramType, new NullToken())); } ParameterList parameterList = new ParameterList(params, new NullToken()); @@ -81,14 +75,14 @@ public class ASTFactory { return new de.dhbwstuttgart.syntaxtree.Constructor(name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>()); } - public 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(); RefTypeOrTPHOrWildcardOrGeneric returnType; - returnType = createType(jreMethod.getReturnType(),names.getName(inClass.getName()), name); + returnType = createType(jreMethod.getReturnType(),new JavaClassName(inClass.getName()), name); Parameter[] jreParams = jreMethod.getParameters(); List params = new ArrayList<>(); for(Parameter jreParam : jreParams){ - RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam.getType(),names.getName(inClass.getName()), name); + RefTypeOrTPHOrWildcardOrGeneric paramType = createType(jreParam.getType(),new JavaClassName(inClass.getName()), name); params.add(new FormalParameter(jreParam.getName(),paramType, new NullToken())); } ParameterList parameterList = new ParameterList(params, new NullToken()); @@ -100,7 +94,7 @@ public class ASTFactory { return new Method(name,returnType, modifier, parameterList, block, gtvDeclarations, offset); } - public GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName){ + public static GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName){ List gtvs = new ArrayList<>(); for(TypeVariable jreTV : typeParameters){ de.dhbwstuttgart.syntaxtree.GenericTypeVar gtv = createGeneric(jreTV, jreTV.getName(), context, methodName); @@ -120,23 +114,23 @@ public class ASTFactory { } */ - public RefTypeOrTPHOrWildcardOrGeneric createType(java.lang.reflect.Type type, JavaClassName parentClass, String parentMethod){ + public static RefTypeOrTPHOrWildcardOrGeneric createType(java.lang.reflect.Type type, JavaClassName parentClass, String parentMethod){ if(type.getTypeName().equals("void")){ return new Void(new NullToken()); }else if(type.getTypeName().equals("int")){ - return new RefType(this.names.getName("java.lang.Integer"), new ArrayList<>(), new NullToken()); + return new RefType(new JavaClassName("java.lang.Integer"), new ArrayList<>(), new NullToken()); }else if(type.getTypeName().equals("byte")){ - return new RefType(this.names.getName("java.lang.Byte"), new ArrayList<>(), new NullToken()); + return new RefType(new JavaClassName("java.lang.Byte"), new ArrayList<>(), new NullToken()); }else if(type.getTypeName().equals("boolean")){ - return new RefType(this.names.getName("java.lang.Boolean"), new ArrayList<>(), new NullToken()); + return new RefType(new JavaClassName("java.lang.Boolean"), new ArrayList<>(), new NullToken()); }else if(type.getTypeName().equals("char")){ - return new RefType(this.names.getName("java.lang.Char"), new ArrayList<>(), new NullToken()); + return new RefType(new JavaClassName("java.lang.Char"), new ArrayList<>(), new NullToken()); }else if(type.getTypeName().equals("short")){ - return new RefType(this.names.getName("java.lang.Short"), new ArrayList<>(), new NullToken()); + return new RefType(new JavaClassName("java.lang.Short"), new ArrayList<>(), new NullToken()); }else if(type.getTypeName().equals("double")){ - return new RefType(this.names.getName("java.lang.Double"), new ArrayList<>(), new NullToken()); + return new RefType(new JavaClassName("java.lang.Double"), new ArrayList<>(), new NullToken()); }else if(type.getTypeName().equals("long")){ - return new RefType(this.names.getName("java.lang.Long"), new ArrayList<>(), new NullToken()); + return new RefType(new JavaClassName("java.lang.Long"), new ArrayList<>(), new NullToken()); }else{ if(type instanceof TypeVariable){ //GTVDeclarationContext via "(TypeVariable) type).getGenericDeclaration()" @@ -150,13 +144,13 @@ public class ASTFactory { params.add(createType(t, parentClass, parentMethod)); } } - RefType ret = new RefType(this.names.getName(type.getTypeName()), params, new NullToken()); + RefType ret = new RefType(new JavaClassName(type.getTypeName()), params, new NullToken()); return ret; } } - public de.dhbwstuttgart.syntaxtree.GenericTypeVar createGeneric(TypeVariable jreTypeVar, String jreTVName, Class context, String parentMethod){ - JavaClassName parentClass = names.getName(context.getName()); + public static de.dhbwstuttgart.syntaxtree.GenericTypeVar createGeneric(TypeVariable jreTypeVar, String jreTVName, Class context, String parentMethod){ + JavaClassName parentClass = new JavaClassName(context.getName()); List genericBounds = new ArrayList<>(); java.lang.reflect.Type[] bounds = jreTypeVar.getBounds(); if(bounds.length > 0){ @@ -169,8 +163,8 @@ public class ASTFactory { , genericBounds, new NullToken(), new NullToken()); } - public ClassOrInterface createObjectClass() { - return this.createClass(Object.class); + public static ClassOrInterface createObjectClass() { + return createClass(Object.class); } /* diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java b/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java index 471093fb..ed385c25 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java @@ -8,13 +8,16 @@ import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import org.antlr.v4.runtime.Token; - +/* +Aufbau: +rightSide = leftSide + */ public class Assign extends Statement { public final Expression rightSide; - public final Expression lefSide; + public final AssignLeftSide lefSide; - public Assign(Expression leftHandSide, Expression value, Token offset) { + public Assign(AssignLeftSide leftHandSide, Expression value, Token offset) { super(leftHandSide.getType(), offset); this.rightSide = value; this.lefSide = leftHandSide; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/AssignLeftSide.java b/src/de/dhbwstuttgart/syntaxtree/statement/AssignLeftSide.java new file mode 100644 index 00000000..13fec3f8 --- /dev/null +++ b/src/de/dhbwstuttgart/syntaxtree/statement/AssignLeftSide.java @@ -0,0 +1,12 @@ +package de.dhbwstuttgart.syntaxtree.statement; + +import de.dhbwstuttgart.syntaxtree.StatementVisitor; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import org.antlr.v4.runtime.Token; + +public abstract class AssignLeftSide extends TypableStatement{ + + public AssignLeftSide(RefTypeOrTPHOrWildcardOrGeneric type, Token offset) { + super(type, offset); + } +} diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/AssignToField.java b/src/de/dhbwstuttgart/syntaxtree/statement/AssignToField.java new file mode 100644 index 00000000..931443d1 --- /dev/null +++ b/src/de/dhbwstuttgart/syntaxtree/statement/AssignToField.java @@ -0,0 +1,16 @@ +package de.dhbwstuttgart.syntaxtree.statement; + +import de.dhbwstuttgart.syntaxtree.StatementVisitor; + +public class AssignToField extends AssignLeftSide{ + public final FieldVar field; + public AssignToField(FieldVar fieldVar) { + super(fieldVar.getType(), fieldVar.getOffset()); + field = fieldVar; + } + + @Override + public void accept(StatementVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Expression.java b/src/de/dhbwstuttgart/syntaxtree/statement/Expression.java index 902a832d..0413e124 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Expression.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Expression.java @@ -9,24 +9,9 @@ import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import org.antlr.v4.runtime.Token; -public abstract class Expression extends SyntaxTreeNode +public abstract class Expression extends TypableStatement { - private RefTypeOrTPHOrWildcardOrGeneric type; - public Expression(RefTypeOrTPHOrWildcardOrGeneric type, Token offset){ - super(offset); - if(type == null)throw new NullPointerException(); - this.type = type; - } - - public RefTypeOrTPHOrWildcardOrGeneric getType(){ - return type; - } - - public abstract void accept(StatementVisitor visitor); - - @Override - public void accept(ASTVisitor visitor) { - this.accept((StatementVisitor)visitor); + super(type, offset); } } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/TypableStatement.java b/src/de/dhbwstuttgart/syntaxtree/statement/TypableStatement.java new file mode 100644 index 00000000..a2166d2d --- /dev/null +++ b/src/de/dhbwstuttgart/syntaxtree/statement/TypableStatement.java @@ -0,0 +1,28 @@ +package de.dhbwstuttgart.syntaxtree.statement; + +import de.dhbwstuttgart.syntaxtree.ASTVisitor; +import de.dhbwstuttgart.syntaxtree.StatementVisitor; +import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import org.antlr.v4.runtime.Token; + +public abstract class TypableStatement extends SyntaxTreeNode{ + private RefTypeOrTPHOrWildcardOrGeneric type; + + public TypableStatement(RefTypeOrTPHOrWildcardOrGeneric type, Token offset){ + super(offset); + if(type == null)throw new NullPointerException(); + this.type = type; + } + + public RefTypeOrTPHOrWildcardOrGeneric getType(){ + return type; + } + + public abstract void accept(StatementVisitor visitor); + + @Override + public void accept(ASTVisitor visitor) { + this.accept((StatementVisitor)visitor); + } +} diff --git a/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java b/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java index 0adac8a8..e38c0230 100644 --- a/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java +++ b/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.syntaxtree.visual; import de.dhbwstuttgart.exceptions.NotImplementedException; +import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; @@ -83,7 +84,8 @@ public class OutputGenerator implements ASTVisitor { method.getType().accept(this); out.append(" " + method.getName()); method.getParameterList().accept(this); - method.block.accept(this); + if(method.block != null) + method.block.accept(this); out.append("\n"); } @@ -330,4 +332,14 @@ public class OutputGenerator implements ASTVisitor { public void visit(Literal literal) { } + + @Override + public void visit(AssignToField assignLeftSide) { + assignLeftSide.field.accept(this); + } + + @Override + public void visit(AssignToLocal assignLeftSide) { + assignLeftSide.localVar.accept(this); + } } \ No newline at end of file diff --git a/src/de/dhbwstuttgart/typecheck/GenericTypeName.java b/src/de/dhbwstuttgart/typecheck/GenericTypeName.java index dd14ff6c..9a19c478 100644 --- a/src/de/dhbwstuttgart/typecheck/GenericTypeName.java +++ b/src/de/dhbwstuttgart/typecheck/GenericTypeName.java @@ -15,13 +15,9 @@ public class GenericTypeName extends JavaClassName { this.methodName = genericContext.parentMethod; } - public String toString(){ + public String getUniqueIdentifier() { return parentClass.toString() + DELIMITER + methodName + DELIMITER + super.toString(); } - - public String getShortName() { - return super.toString(); - } } diff --git a/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java index 13c2f152..046ae735 100644 --- a/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java +++ b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java @@ -1,15 +1,12 @@ package de.dhbwstuttgart.typedeployment; -import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.syntaxtree.*; -import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.constraints.Pair; import org.antlr.v4.runtime.Token; -import java.lang.reflect.Type; import java.util.*; /** @@ -59,9 +56,15 @@ public class TypeInsertFactory { } } } - if(insertPoint == null){ //Dann muss es ein TPH sein, welcher nicht im Result auftaucht - insertPoint = new TypeInsertPoint(offset, ((TypePlaceholder) type).getName()); - additionalInserts.add(((TypePlaceholder) type)); + if(insertPoint == null ){ //Dann muss es ein TPH sein, welcher nicht im Result auftaucht + if(type instanceof TypePlaceholder){ + insertPoint = new TypeInsertPoint(offset, ((TypePlaceholder) type).getName()); + additionalInserts.add(((TypePlaceholder) type)); + }else if(type instanceof GenericRefType){ + insertPoint = new TypeInsertPoint(offset, ((GenericRefType) type).getName().toString()); + }else if(type instanceof RefType){ + insertPoint = new TypeInsertPoint(offset, ((RefType) type).getName().toString()); + }else throw new NotImplementedException(); } //Alle Bounds finden: @@ -90,8 +93,8 @@ public class TypeInsertFactory { } if(! inside)newGenerics.add(new GenericInsertPair(additionalTPH, null)); } - - ret.add(createGenericInsert(newGenerics, cl, m)); + if(newGenerics.size() > 0) + ret.add(createGenericInsert(newGenerics, cl, m)); //return ret; return new TypeInsert(insertPoint, ret); diff --git a/src/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java b/src/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java index 88e7ad68..7d0f557d 100644 --- a/src/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java +++ b/src/de/dhbwstuttgart/typedeployment/TypeInsertPlacer.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.typedeployment; import de.dhbwstuttgart.syntaxtree.*; +import de.dhbwstuttgart.syntaxtree.statement.AssignLeftSide; import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.ResultSet; @@ -26,36 +27,11 @@ public class TypeInsertPlacer extends AbstractASTWalker{ TypeInsertPlacerClass cl = new TypeInsertPlacerClass(classOrInterface, withResults); this.inserts.addAll(cl.inserts); } - - /* - List ret = new ArrayList<>(); - - for(ClassOrInterface cl : forSourcefile.getClasses()){ - //Felder: - for(Field field : cl.getFieldDecl()){ - - } - - for(Method m : cl.getMethods()){ - if(m.getReturnType() instanceof TypePlaceholder)for(Set pairs : withResults.results) { - ret.add(createInsertPoints( - m.getReturnType(), m.getReturnType().getOffset(), cl, m, pairs)); - } - - for(FormalParameter param : m.getParameterList().getFormalparalist()){ - if(param.getType() instanceof TypePlaceholder)for(Set pairs : withResults.results) - ret.add(createInsertPoints( - param.getType(), param.getType().getOffset(), cl, m, pairs)); - } - } - } - return ret; - */ } class TypeInsertPlacerClass extends AbstractASTWalker{ - private final ResultSet results; - private final ClassOrInterface cl; + protected final ResultSet results; + protected final ClassOrInterface cl; public final Set inserts = new HashSet<>(); TypeInsertPlacerClass(ClassOrInterface forClass, ResultSet withResults){ @@ -66,7 +42,9 @@ class TypeInsertPlacerClass extends AbstractASTWalker{ @Override public void visit(Method method) { - TypeInsertPlacerMethod mWalker = new TypeInsertPlacerMethod(method); + for(Set pairs : results.results) + inserts.add(TypeInsertFactory.createInsertPoints( + method.getReturnType(), method.getReturnType().getOffset(), cl, null, pairs)); super.visit(method); } @@ -79,15 +57,14 @@ class TypeInsertPlacerClass extends AbstractASTWalker{ } super.visit(field); } -} - -class TypeInsertPlacerMethod extends AbstractASTWalker{ - TypeInsertPlacerMethod(Method forMethod){ - forMethod.accept(this); - } @Override public void visit(ParameterList params) { + for(FormalParameter param : params){ + for(Set pairs : results.results) + inserts.add(TypeInsertFactory.createInsertPoints( + param.getType(), param.getType().getOffset(), cl, null, pairs)); + } super.visit(params); } @@ -95,5 +72,4 @@ class TypeInsertPlacerMethod extends AbstractASTWalker{ public void visit(LambdaExpression lambdaExpression) { //Lambda-Ausdrücke brauchen keine Typeinsetzungen } - -} \ No newline at end of file +} diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java index 646222eb..2a9ef6d0 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java @@ -1,307 +1,77 @@ package de.dhbwstuttgart.typeinference.typeAlgo; -//import com.sun.org.apache.xpath.internal.Arg; -import de.dhbwstuttgart.exceptions.NotImplementedException; -import de.dhbwstuttgart.exceptions.TypeinferenceException; -import de.dhbwstuttgart.parser.NullToken; +import de.dhbwstuttgart.exceptions.DebugException; 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.typeinference.assumptions.FieldAssumption; -import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; +import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; +import de.dhbwstuttgart.syntaxtree.statement.Statement; +import de.dhbwstuttgart.typecheck.JavaClassName; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; -import de.dhbwstuttgart.typeinference.constraints.Constraint; +import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; -import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory; -import de.dhbwstuttgart.typeinference.constraints.Pair; -import de.dhbwstuttgart.typeinference.unify.model.PairOperator; - import java.util.*; -import java.util.stream.Collectors; -public class TYPE implements StatementVisitor{ +public class TYPE { - private final TypeInferenceBlockInformation info; - private final ConstraintSet constraintsSet = new ConstraintSet(); + private final List sfs; - public TYPE(TypeInferenceBlockInformation info){ - this.info = info; + public TYPE(List sourceFiles){ + sfs = sourceFiles; } + public ConstraintSet getConstraints() { - return constraintsSet; - } - - @Override - public void visit(LambdaExpression lambdaExpression) { - TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken()); - List lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList()); - //lambdaParams.add(tphRetType); - lambdaParams.add(0,tphRetType); - constraintsSet.addUndConstraint( - ConstraintsFactory.createPair(lambdaExpression.getType(), - new FunN(lambdaParams),PairOperator.EQUALSDOT,info)); - constraintsSet.addUndConstraint( - ConstraintsFactory.createPair(lambdaExpression.getReturnType(), - tphRetType,info)); - - //Constraints des Bodys generieren: - TYPE lambdaScope = new TYPE(new TypeInferenceBlockInformation(info, lambdaExpression)); - lambdaExpression.methodBody.accept(lambdaScope); - constraintsSet.addAll(lambdaScope.getConstraints()); - } - - @Override - public void visit(Assign assign) { - assign.lefSide.accept(this); - assign.rightSide.accept(this); - constraintsSet.addUndConstraint(ConstraintsFactory.createPair( - assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT, info)); - } - - @Override - public void visit(Binary binary) { - throw new NotImplementedException(); - } - - @Override - public void visit(Block block) { - for(Statement stmt : block.getStatements()){ - stmt.accept(this); - } - } - - @Override - public void visit(CastExpr castExpr) { - throw new NotImplementedException(); - } - - @Override - public void visit(EmptyStmt emptyStmt) { - //Nothing :) - } - - @Override - public void visit(FieldVar fieldVar) { - fieldVar.receiver.accept(this); - Set oderConstraints = new HashSet<>(); - for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){ - Constraint constraint = new Constraint(); - constraint.add(ConstraintsFactory.createPair( - fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info)); - constraint.add(ConstraintsFactory.createPair( - fieldVar.getType(),fieldAssumption.getType(), info)); - oderConstraints.add(constraint); - } - if(oderConstraints.size() == 0) - throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset()); - constraintsSet.addOderConstraint(oderConstraints); - } - - @Override - public void visit(ForStmt forStmt) { - throw new NotImplementedException(); - } - - @Override - public void visit(IfStmt ifStmt) { - throw new NotImplementedException(); - } - - @Override - public void visit(InstanceOf instanceOf) { - throw new NotImplementedException(); - } - - @Override - public void visit(LocalVar localVar) { - // Es werden nur bei Feldvariablen Constraints generiert. Lokale Variablen sind eindeutig - } - - @Override - public void visit(LocalVarDecl localVarDecl) { - //Hier ist nichts zu tun. Allen lokalen Variablen bekommen beim parsen schon den korrekten Typ - } - - @Override - public void visit(MethodCall methodCall) { - methodCall.receiver.accept(this); - constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info)); - //Overloading: - Set methodConstraints = new HashSet<>(); - for(MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)){ - methodConstraints.add(generateConstraint(methodCall, m, info)); - } - if(methodConstraints.size()<1){ - throw new TypeinferenceException("Methode "+methodCall.name+" ist nicht vorhanden!",methodCall.getOffset()); - } - constraintsSet.addOderConstraint(methodConstraints); - } - - @Override - public void visit(NewClass methodCall) { - constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info)); - //Overloading: - Set methodConstraints = new HashSet<>(); - for(MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())){ - methodConstraints.add(generateConstructorConstraint(methodCall, m, info)); - } - if(methodConstraints.size()<1){ - throw new TypeinferenceException("Konstruktor in Klasse "+methodCall.getType().toString()+" ist nicht vorhanden!",methodCall.getOffset()); - } - constraintsSet.addOderConstraint(methodConstraints); - } - - @Override - public void visit(NewArray newArray) { - throw new NotImplementedException(); - } - - @Override - public void visit(Receiver receiver) { - receiver.expr.accept(this); - } - - @Override - public void visit(Return returnExpr) { - returnExpr.retexpr.accept(this); - constraintsSet.addUndConstraint(ConstraintsFactory.createPair( - returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT, info)); - } - - @Override - public void visit(ReturnVoid aReturn) { - visit((Return) aReturn); - } - - @Override - public void visit(StaticClassName staticClassName) { - throw new NotImplementedException(); - } - - @Override - public void visit(Super aSuper) { - throw new NotImplementedException(); - } - - @Override - public void visit(This aThis) { - constraintsSet.addUndConstraint(ConstraintsFactory.createPair( aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info)); - } - - @Override - public void visit(UnaryPlus unaryPlus) { - throw new NotImplementedException(); - } - - @Override - public void visit(WhileStmt whileStmt) { - throw new NotImplementedException(); - } - - @Override - public void visit(DoStmt whileStmt) { - throw new NotImplementedException(); - } - - @Override - public void visit(Null aNull) { - throw new NotImplementedException(); - } - - @Override - public void visit(Literal literal) { - throw new NotImplementedException(); - } - - /* - METHOD CALL Section: - */ - - protected Constraint generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info){ - Constraint methodConstraint = new Constraint(); - methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), PairOperator.SMALLERDOT, info)); - methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), PairOperator.EQUALSDOT, info)); - methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info)); - return methodConstraint; - } - - protected Set generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption, TypeInferenceBlockInformation info) { - Set ret = new HashSet<>(); - for(int i = 0;i 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++){ - funNParams.add(TypePlaceholder.fresh(new NullToken())); - } - ret.add(new MethodAssumption(new FunN(funNParams), funNParams.get(0), funNParams.subList(1, funNParams.size()))); + private ConstraintSet getConstraintsClass(ClassOrInterface cl, TypeInferenceInformation info) { + ConstraintSet ret = new ConstraintSet(); + for(Method m : cl.getMethods()){ + ret.addAll(getConstraintsMethod(m,info, cl)); } - 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()); + for(Constructor m : cl.getConstructors()){ + ret.addAll(getConstraintsConstructor(m,info, cl)); + } + return ret; + } - ret.add(new MethodAssumption(cl.getType(), retType, convertParams(m.getParameterList(),info))); + private TypeInferenceInformation getTypeInferenceInformation() { + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + Set classes = new HashSet<>(); + for(SourceFile sourceFile : sfs){ + for(JavaClassName importName : sourceFile.imports){ + System.out.println(importName); + try { + classes.add(ASTFactory.createClass(classLoader.loadClass(importName.toString()))); + } catch (ClassNotFoundException e) { + throw new DebugException("Klasse " + importName + " konnte nicht geladen werden"); } } + classes.addAll(sourceFile.KlassenVektor); } + + return new TypeInferenceInformation(classes); + } + + private ConstraintSet getConstraintsMethod(Method m, TypeInferenceInformation info, ClassOrInterface currentClass) { + if(m.block == null)return new ConstraintSet(); //Abstrakte Methoden generieren keine Constraints + TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, m); + TYPEStmt methodScope = new TYPEStmt(blockInfo); + m.block.accept(methodScope); + return methodScope.getConstraints(); + } + + private ConstraintSet getConstraintsConstructor(Constructor m, TypeInferenceInformation info, ClassOrInterface currentClass) { + TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, null); + TYPEStmt methodScope = new TYPEStmt(blockInfo); + for(Statement stmt : m.fieldInitializations)stmt.accept(methodScope); + ConstraintSet ret = this.getConstraintsMethod(m, info, currentClass); + ret.addAll(methodScope.getConstraints()); return ret; } - - public static List getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) { - return getMethods(name, arglist.getArguments().size(), info); - } - - protected static List convertParams(ParameterList parameterList, TypeInferenceBlockInformation info){ - List params = new ArrayList<>(); - for(FormalParameter fp : parameterList.getFormalparalist()){ - params.add(info.checkGTV(fp.getType())); - } - return params; - } - - public ConstraintSet getArgumentListConstraints(MethodCall forMethod, TypeInferenceBlockInformation info) { - TYPE ret = new TYPE(info); - for(int i = 0;i getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList){ - List ret = new ArrayList<>(); - for(ClassOrInterface cl : info.getAvailableClasses()){ - if(cl.getClassName().equals(ofType.getName())){ - for(Method m : cl.getConstructors()){ - if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){ - ret.add(new MethodAssumption(ofType, ofType, convertParams(m.getParameterList(), info))); - } - } - } - } - return ret; - } - - protected Constraint generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption, TypeInferenceBlockInformation info){ - Constraint methodConstraint = new Constraint(); - methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forConstructor.getType(), PairOperator.SMALLERDOT, info)); - methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info)); - return methodConstraint; - } - } diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java new file mode 100644 index 00000000..34f17a56 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -0,0 +1,322 @@ +package de.dhbwstuttgart.typeinference.typeAlgo; + +//import com.sun.org.apache.xpath.internal.Arg; + +import de.dhbwstuttgart.exceptions.NotImplementedException; +import de.dhbwstuttgart.exceptions.TypeinferenceException; +import de.dhbwstuttgart.parser.NullToken; +import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +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.typeinference.assumptions.FieldAssumption; +import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; +import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; +import de.dhbwstuttgart.typeinference.constraints.Constraint; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory; +import de.dhbwstuttgart.typeinference.constraints.Pair; +import de.dhbwstuttgart.typeinference.unify.model.PairOperator; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class TYPEStmt implements StatementVisitor{ + + private final TypeInferenceBlockInformation info; + private final ConstraintSet constraintsSet = new ConstraintSet(); + + public TYPEStmt(TypeInferenceBlockInformation info){ + this.info = info; + } + + public ConstraintSet getConstraints() { + return constraintsSet; + } + + @Override + public void visit(LambdaExpression lambdaExpression) { + TypePlaceholder tphRetType = TypePlaceholder.fresh(new NullToken()); + List lambdaParams = lambdaExpression.params.getFormalparalist().stream().map((formalParameter -> formalParameter.getType())).collect(Collectors.toList()); + //lambdaParams.add(tphRetType); + lambdaParams.add(0,tphRetType); + constraintsSet.addUndConstraint( + ConstraintsFactory.createPair(lambdaExpression.getType(), + new FunN(lambdaParams),PairOperator.EQUALSDOT,info)); + constraintsSet.addUndConstraint( + ConstraintsFactory.createPair(lambdaExpression.getReturnType(), + tphRetType,info)); + + //Constraints des Bodys generieren: + TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression)); + lambdaExpression.methodBody.accept(lambdaScope); + constraintsSet.addAll(lambdaScope.getConstraints()); + } + + @Override + public void visit(Assign assign) { + assign.lefSide.accept(this); + assign.rightSide.accept(this); + constraintsSet.addUndConstraint(ConstraintsFactory.createPair( + assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT, info)); + } + + @Override + public void visit(Binary binary) { + throw new NotImplementedException(); + } + + @Override + public void visit(Block block) { + for(Statement stmt : block.getStatements()){ + stmt.accept(this); + } + } + + @Override + public void visit(CastExpr castExpr) { + throw new NotImplementedException(); + } + + @Override + public void visit(EmptyStmt emptyStmt) { + //Nothing :) + } + + @Override + public void visit(FieldVar fieldVar) { + fieldVar.receiver.accept(this); + Set oderConstraints = new HashSet<>(); + for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){ + Constraint constraint = new Constraint(); + constraint.add(ConstraintsFactory.createPair( + fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info)); + constraint.add(ConstraintsFactory.createPair( + fieldVar.getType(),fieldAssumption.getType(), info)); + oderConstraints.add(constraint); + } + if(oderConstraints.size() == 0) + throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset()); + constraintsSet.addOderConstraint(oderConstraints); + } + + @Override + public void visit(ForStmt forStmt) { + throw new NotImplementedException(); + } + + @Override + public void visit(IfStmt ifStmt) { + throw new NotImplementedException(); + } + + @Override + public void visit(InstanceOf instanceOf) { + throw new NotImplementedException(); + } + + @Override + public void visit(LocalVar localVar) { + // Es werden nur bei Feldvariablen Constraints generiert. Lokale Variablen sind eindeutig + } + + @Override + public void visit(LocalVarDecl localVarDecl) { + //Hier ist nichts zu tun. Allen lokalen Variablen bekommen beim parsen schon den korrekten Typ + } + + @Override + public void visit(MethodCall methodCall) { + methodCall.receiver.accept(this); + constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info)); + //Overloading: + Set methodConstraints = new HashSet<>(); + for(MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)){ + methodConstraints.add(generateConstraint(methodCall, m, info)); + } + if(methodConstraints.size()<1){ + throw new TypeinferenceException("Methode "+methodCall.name+" ist nicht vorhanden!",methodCall.getOffset()); + } + constraintsSet.addOderConstraint(methodConstraints); + } + + @Override + public void visit(NewClass methodCall) { + constraintsSet.addAll(this.getArgumentListConstraints(methodCall, info)); + //Overloading: + Set methodConstraints = new HashSet<>(); + for(MethodAssumption m : this.getConstructors(info, (RefType) methodCall.getType(), methodCall.getArgumentList())){ + methodConstraints.add(generateConstructorConstraint(methodCall, m, info)); + } + if(methodConstraints.size()<1){ + throw new TypeinferenceException("Konstruktor in Klasse "+methodCall.getType().toString()+" ist nicht vorhanden!",methodCall.getOffset()); + } + constraintsSet.addOderConstraint(methodConstraints); + } + + @Override + public void visit(NewArray newArray) { + throw new NotImplementedException(); + } + + @Override + public void visit(Receiver receiver) { + receiver.expr.accept(this); + } + + @Override + public void visit(Return returnExpr) { + returnExpr.retexpr.accept(this); + constraintsSet.addUndConstraint(ConstraintsFactory.createPair( + returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT, info)); + } + + @Override + public void visit(ReturnVoid aReturn) { + visit((Return) aReturn); + } + + @Override + public void visit(StaticClassName staticClassName) { + throw new NotImplementedException(); + } + + @Override + public void visit(Super aSuper) { + throw new NotImplementedException(); + } + + @Override + public void visit(This aThis) { + constraintsSet.addUndConstraint(ConstraintsFactory.createPair( aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info)); + } + + @Override + public void visit(UnaryPlus unaryPlus) { + throw new NotImplementedException(); + } + + @Override + public void visit(WhileStmt whileStmt) { + throw new NotImplementedException(); + } + + @Override + public void visit(DoStmt whileStmt) { + throw new NotImplementedException(); + } + + @Override + public void visit(Null aNull) { + throw new NotImplementedException(); + } + + @Override + public void visit(Literal literal) { + throw new NotImplementedException(); + } + + @Override + public void visit(AssignToField assignLeftSide) { + //Hier ist kein Code nötig. Es werden keine extra Constraints generiert + } + + @Override + public void visit(AssignToLocal assignLeftSide) { + //Hier ist kein Code nötig. Es werden keine extra Constraints generiert + } + + /* + METHOD CALL Section: + */ + + protected Constraint generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info){ + Constraint methodConstraint = new Constraint(); + methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), PairOperator.SMALLERDOT, info)); + methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), PairOperator.EQUALSDOT, info)); + methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info)); + return methodConstraint; + } + + protected Set generateParameterConstraints(MethodCall foMethod, MethodAssumption assumption, TypeInferenceBlockInformation info) { + Set ret = new HashSet<>(); + for(int i = 0;i 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++){ + funNParams.add(TypePlaceholder.fresh(new NullToken())); + } + ret.add(new MethodAssumption(new FunN(funNParams), funNParams.get(0), funNParams.subList(1, funNParams.size()))); + } + 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))); + } + } + } + return ret; + } + + public static List getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) { + return getMethods(name, arglist.getArguments().size(), info); + } + + protected static List convertParams(ParameterList parameterList, TypeInferenceBlockInformation info){ + List params = new ArrayList<>(); + for(FormalParameter fp : parameterList.getFormalparalist()){ + params.add(info.checkGTV(fp.getType())); + } + return params; + } + + public ConstraintSet getArgumentListConstraints(MethodCall forMethod, TypeInferenceBlockInformation info) { + TYPEStmt ret = new TYPEStmt(info); + for(int i = 0;i getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList){ + List ret = new ArrayList<>(); + for(ClassOrInterface cl : info.getAvailableClasses()){ + if(cl.getClassName().equals(ofType.getName())){ + for(Method m : cl.getConstructors()){ + if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){ + ret.add(new MethodAssumption(ofType, ofType, convertParams(m.getParameterList(), info))); + } + } + } + } + return ret; + } + + protected Constraint generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption, TypeInferenceBlockInformation info){ + Constraint methodConstraint = new Constraint(); + methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forConstructor.getType(), PairOperator.SMALLERDOT, info)); + methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info)); + return methodConstraint; + } + +} diff --git a/test/javFiles/Import.jav b/test/javFiles/Import.jav new file mode 100644 index 00000000..c48082ba --- /dev/null +++ b/test/javFiles/Import.jav @@ -0,0 +1,8 @@ +import java.util.Vector; + +class Import { + void methode(){ + Vector v; + v.add(v); + } +} \ No newline at end of file diff --git a/test/javFiles/Matrix.jav b/test/javFiles/Matrix.jav index 7096ba0c..65dc465a 100644 --- a/test/javFiles/Matrix.jav +++ b/test/javFiles/Matrix.jav @@ -1,14 +1,13 @@ -class Matrix extends Menge> { +import java.util.Vector; + +class Matrix extends Vector> { Matrix mul_rec(Matrix m) { - v1; - v1 = new Menge(); - v2; - v2 = new Menge(); - i; - i = 0; + auto v1 = new Vector(); + auto v2 = new Vector(); + auto i = 0; while(i < m.size()) { - v; + auto v; v = m.elementAt(i); v2.addElement(v.remove(v.size()-1)); i++; @@ -21,14 +20,14 @@ class Matrix extends Menge> { ret = new Matrix(); i = 0; while (i < this.size()) { - ret.addElement(new Menge()); + ret.addElement(new Vector()); i++; } } i = 0; while (i < this.size()) { int erg = 0; - j; + auto j; j = 0; while (j < v2.size()) { erg = erg + this.elementAt(i).elementAt(j).intValue() diff --git a/test/javFiles/mathStruc.jav b/test/javFiles/mathStruc.jav index 45121c5e..adcdf649 100644 --- a/test/javFiles/mathStruc.jav +++ b/test/javFiles/mathStruc.jav @@ -1,8 +1,6 @@ class mathStruc { -a = new mathStruc(); - mathStruc(A a) { } A model(){ A a; return a; } diff --git a/test/typeinference/JavaTXCompilerTest.java b/test/typeinference/JavaTXCompilerTest.java index a129b13e..ad6eb143 100644 --- a/test/typeinference/JavaTXCompilerTest.java +++ b/test/typeinference/JavaTXCompilerTest.java @@ -42,6 +42,7 @@ public class JavaTXCompilerTest extends JavaTXCompiler { //filesToTest.add(new File(rootDirectory+"Generics.jav")); //filesToTest.add(new File(rootDirectory+"MethodsEasy.jav")); //filesToTest.add(new File(rootDirectory+"Matrix.jav")); + //filesToTest.add(new File(rootDirectory+"Import.jav")); for(File f : filesToTest){ SourceFile sf = this.parse(f); System.out.println(ASTTypePrinter.print(this.sourceFiles.get(sourceFiles.size()-1)));