From 29a17731fd719f49f2023cc13fe91e69ed02e1dc Mon Sep 17 00:00:00 2001
From: JanUlrich <andi@michlaustderaffe.de>
Date: Tue, 18 Apr 2017 21:06:04 +0200
Subject: [PATCH] =?UTF-8?q?NewClass=20Constraints=20generieren=20angef?=
 =?UTF-8?q?=C3=BCgt?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../StatementGenerator.java                   | 12 ++-
 .../SyntaxTreeGenerator.java                  | 28 ++++++-
 .../SyntaxTreeGenerator/TypeGenerator.java    | 43 +++++++++-
 .../syntaxtree/ClassOrInterface.java          | 19 ++++-
 .../syntaxtree/factory/ASTFactory.java        |  6 +-
 .../syntaxtree/statement/MethodCall.java      | 83 +++++++++++++++----
 .../syntaxtree/statement/NewClass.java        | 65 +++++++++++----
 .../syntaxtree/statement/ThisCall.java        |  2 +-
 .../syntaxtree/statement/UnaryExpr.java       |  2 +-
 .../assumptions/TypeInferenceInformation.java | 29 ++-----
 test/javFiles/Generics.jav                    |  6 ++
 test/parser/GeneralParserTest.java            |  2 +-
 12 files changed, 222 insertions(+), 75 deletions(-)

diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java
index 6a5be13b..8d7cff9b 100644
--- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java
+++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java
@@ -60,7 +60,11 @@ public class StatementGenerator {
         }else{
             block = this.convert(methodDeclarationContext.methodBody().block());
         }
-        return new Method(name, retType, modifiers, parameterList,block, gtvDeclarations, methodDeclarationContext.getStart());
+        if(parentClass.equals(new JavaClassName(name))){
+            return new Constructor(name, retType, modifiers, parameterList, block, gtvDeclarations, methodDeclarationContext.getStart());
+        }else{
+            return new Method(name, retType, modifiers, parameterList,block, gtvDeclarations, methodDeclarationContext.getStart());
+        }
     }
 
     private ParameterList convert(Java8Parser.FormalParameterListContext formalParameterListContext) {
@@ -234,7 +238,7 @@ public class StatementGenerator {
         }else throw new NotImplementedException();
 
         ArgumentList argumentList = convert(methodInvocationContext.argumentList());
-        MethodCall ret = new MethodCall(new Receiver(receiver), name, argumentList, methodInvocationContext.getStart());
+        MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()),new Receiver(receiver), name, argumentList, methodInvocationContext.getStart());
         return ret;
     }
 
@@ -695,7 +699,7 @@ public class StatementGenerator {
         }else {
             Java8Parser.MethodInvocation_lf_primaryContext ctxt = e.methodInvocation_lf_primary();
             String methodName = ctxt.Identifier().toString();
-            return new MethodCall(new Receiver(expr), methodName, convert(ctxt.argumentList()), e.getStart());
+            return new MethodCall(TypePlaceholder.fresh(e.getStart()), new Receiver(expr), methodName, convert(ctxt.argumentList()), e.getStart());
         }
     }
 
@@ -776,7 +780,7 @@ public class StatementGenerator {
         }
 
         ArgumentList argumentList = convert(methodInvocationContext.argumentList());
-        MethodCall ret = new MethodCall(new Receiver(receiver), name, argumentList, methodInvocationContext.getStart());
+        MethodCall ret = new MethodCall(TypePlaceholder.fresh(methodInvocationContext.getStart()), new Receiver(receiver), name, argumentList, methodInvocationContext.getStart());
         return ret;
     }
 
diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java
index 68b67fe5..d7e1a331 100644
--- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java
+++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java
@@ -200,11 +200,26 @@ public class SyntaxTreeGenerator{
       }
     }
     JavaClassName name = reg.getName(ctx.Identifier().getText());
+    Token offset = ctx.getStart();
     GenericDeclarationList genericClassParameters = TypeGenerator.convert(ctx.typeParameters(), name, "",reg, generics);
     List<Field> fielddecl = convertFields(ctx.classBody());
     List<Method> methods = convertMethods(ctx.classBody(), name);
+    List<Constructor> konstruktoren = new ArrayList<>();
+    for(int i = 0; i<methods.size();i++){
+      Method m = methods.get(i);
+      if(m instanceof Constructor){
+        methods.remove(i);
+        konstruktoren.add((Constructor) m);
+      }
+    }
+    if(konstruktoren.size()<1){//Standardkonstruktor anfügen:
+      konstruktoren.add(
+              generateStandardConstructor(
+                      ctx.Identifier().getText(),
+                      genericClassParameters, offset)
+          );
+    }
 
-    Token offset = ctx.getStart();
     RefType superClass ;
     if(ctx.superclass() != null){
       superClass = convert(ctx.superclass());
@@ -213,7 +228,16 @@ public class SyntaxTreeGenerator{
     }
     Boolean isInterface = false;
     List<RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces = null;
-    return new ClassOrInterface(modifiers, name, fielddecl, methods, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
+    return new ClassOrInterface(modifiers, name, fielddecl, methods, konstruktoren, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
+  }
+
+  private Constructor generateStandardConstructor(String className, GenericDeclarationList classGenerics, Token offset){
+    RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
+    int modifiers = 0;
+    ParameterList params = new ParameterList(new ArrayList<>(), offset);
+    //TODO: Konstruktor muss Felder initialisieren:
+    Block block = new Block(new ArrayList<>(), offset);
+    return new Constructor(className, classType, modifiers, params, block, classGenerics, offset);
   }
 
   private RefType convert(Java8Parser.SuperclassContext superclass) {
diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java
index 43609a08..d418b3cc 100644
--- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java
+++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java
@@ -7,6 +7,7 @@ import de.dhbwstuttgart.syntaxtree.GTVDeclarationContext;
 import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
 import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
 import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
+import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
 import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
 import de.dhbwstuttgart.syntaxtree.type.RefType;
 import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
@@ -23,8 +24,23 @@ import java.util.List;
 public class TypeGenerator {
 
     public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.UnannClassOrInterfaceTypeContext unannClassOrInterfaceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) {
-        String name = unannClassOrInterfaceTypeContext.getText();
-        return convertTypeName(name,unannClassOrInterfaceTypeContext.getStart(), reg, generics);
+        String name;
+        if(unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType() != null){
+            name = unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().Identifier().getText();
+            }
+        Java8Parser.TypeArgumentsContext arguments;
+        if(unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType() != null){
+            name = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().Identifier().getText();
+            arguments = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
+        }else{// if(unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType() != null){
+            name = unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().getText();
+            arguments = unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
+        }
+        if(arguments == null){
+            return convertTypeName(name,unannClassOrInterfaceTypeContext.getStart(), reg, generics);
+        }else{
+            return null;
+        }
     }
 
     public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.UnannTypeContext unannTypeContext, JavaClassRegistry reg, GenericsRegistry genericsRegistry) {
@@ -78,6 +94,11 @@ public class TypeGenerator {
     }
 
     public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(String name, Token offset, JavaClassRegistry reg, GenericsRegistry generics){
+        return convertTypeName(name, null, offset, reg, generics);
+    }
+
+    public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(
+            String name, Java8Parser.TypeArgumentsContext typeArguments, Token offset, JavaClassRegistry reg, GenericsRegistry generics){
         if(!reg.contains(name)){ //Dann könnte es ein Generische Type sein:
             if(generics.keySet().contains(name)){
                 return new GenericRefType(new GenericTypeName(generics.get(name),name), offset);
@@ -85,7 +106,23 @@ public class TypeGenerator {
                 throw new TypeinferenceException("Der Typ "+ name + " ist nicht vorhanden",offset);
             }
         }
-        return new RefType(reg.getName(name), offset);
+        if(typeArguments == null){
+            return new RefType(reg.getName(name), offset);
+        }else{
+            return new RefType(reg.getName(name), convert(typeArguments, reg, generics), offset);
+        }
     }
 
+    public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.TypeArgumentsContext typeArguments,
+                                       JavaClassRegistry reg, GenericsRegistry generics){
+        List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
+        for(Java8Parser.TypeArgumentContext arg : typeArguments.typeArgumentList().typeArgument()){
+            if(arg.wildcard() != null){
+                throw new NotImplementedException();
+            }else{
+                ret.add(convert(arg.referenceType(), reg, generics));
+            }
+        }
+        return ret;
+    }
 }
diff --git a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java
index ca654563..38281048 100755
--- a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java
+++ b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java
@@ -4,6 +4,7 @@ import de.dhbwstuttgart.core.IItemWithOffset;
 import de.dhbwstuttgart.syntaxtree.type.RefType;
 import de.dhbwstuttgart.typecheck.JavaClassName;
 import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
+import de.dhbwstuttgart.typeinference.constraints.Constraint;
 import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
 import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
 import org.antlr.v4.runtime.Token;
@@ -24,8 +25,9 @@ public class ClassOrInterface extends GTVDeclarationContext implements IItemWith
   private RefTypeOrTPHOrWildcardOrGeneric superClass;
   protected boolean isInterface;
   private List<? extends RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces;
-  
-  public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, List<Method> methods, GenericDeclarationList genericClassParameters,
+  private List<Constructor> constructors;
+
+  public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters,
                           RefTypeOrTPHOrWildcardOrGeneric superClass, Boolean isInterface, List<? extends RefTypeOrTPHOrWildcardOrGeneric> implementedInterfaces, Token offset){
     super(offset);
       this.modifiers = modifiers;
@@ -47,6 +49,7 @@ public class ClassOrInterface extends GTVDeclarationContext implements IItemWith
       this.implementedInterfaces = implementedInterfaces;
     }
     this.methods = methods;
+    this.constructors = constructors;
   }
   
   // Gets class name
@@ -75,14 +78,22 @@ public class ClassOrInterface extends GTVDeclarationContext implements IItemWith
   }
 
   public RefType getType() {
-    return new RefType(this.getClassName(), this.getOffset());
+    return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset());
+  }
+
+  public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){
+    return new RefType(name, offset);
   }
 
   public RefTypeOrTPHOrWildcardOrGeneric getSuperClass() {
     return superClass;
   }
 
-  public Iterable<? extends GenericTypeVar> getGenerics() {
+  public GenericDeclarationList getGenerics() {
     return this.genericClassParameters;
   }
+
+  public List<? extends Method> getConstructors() {
+    return constructors;
+  }
 }
diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java
index c12dbd46..7a355c60 100644
--- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java
+++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java
@@ -35,8 +35,9 @@ public class ASTFactory {
 	public ClassOrInterface createClass(java.lang.Class jreClass){
 		JavaClassName name = names.getName(jreClass.getName());
 		List<Method> methoden = new ArrayList<>();
+		List<de.dhbwstuttgart.syntaxtree.Constructor> konstruktoren = new ArrayList<>();
 		for(java.lang.reflect.Constructor constructor : jreClass.getConstructors()){
-            methoden.add(createConstructor(constructor, jreClass));
+			konstruktoren.add(createConstructor(constructor, jreClass));
 		}
 		for(java.lang.reflect.Method method : jreClass.getMethods()){
 			methoden.add(createMethod(method, jreClass));
@@ -58,7 +59,8 @@ public class ASTFactory {
         GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null);
 
         Token offset = new NullToken(); //Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
-		return new ClassOrInterface(modifier, name, felder, methoden, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset);
+
+		return new ClassOrInterface(modifier, name, felder, methoden, konstruktoren, genericDeclarationList, superClass,isInterface, implementedInterfaces, offset);
 	}
 
     private de.dhbwstuttgart.syntaxtree.Constructor createConstructor(Constructor constructor, Class inClass) {
diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java
index 0c2accd5..30a8dfc8 100755
--- a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java
+++ b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java
@@ -1,18 +1,24 @@
 package de.dhbwstuttgart.syntaxtree.statement;
 
 import de.dhbwstuttgart.exceptions.TypeinferenceException;
+import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
+import de.dhbwstuttgart.syntaxtree.FormalParameter;
+import de.dhbwstuttgart.syntaxtree.Method;
+import de.dhbwstuttgart.syntaxtree.ParameterList;
+import de.dhbwstuttgart.syntaxtree.type.RefType;
+import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
 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.assumptions.MethodAssumption;
+import de.dhbwstuttgart.typeinference.constraints.Pair;
 import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
 import org.antlr.v4.runtime.Token;
 
 import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
 
-import java.util.HashSet;
-import java.util.Set;
+import java.util.*;
 
 
 public class MethodCall extends Statement
@@ -21,8 +27,8 @@ public class MethodCall extends Statement
     private Receiver receiver;
     private ArgumentList arglist;
 
-    public MethodCall(Receiver receiver, String methodName, ArgumentList argumentList, Token offset){
-		super(TypePlaceholder.fresh(offset),offset);
+    public MethodCall(RefTypeOrTPHOrWildcardOrGeneric retType, Receiver receiver, String methodName, ArgumentList argumentList, Token offset){
+		super(retType,offset);
 		this.arglist = argumentList;
         this.name = methodName;
         this.receiver = receiver;
@@ -31,21 +37,11 @@ public class MethodCall extends Statement
     @Override
     public ConstraintSet getConstraints(TypeInferenceBlockInformation info) {
         ConstraintSet ret = receiver.getConstraints(info);
-        ret.addAll(receiver.getConstraints(info));
-        for(int i = 0;i<arglist.getArguments().size();i++){
-            ret.addAll(arglist.getArguments().get(i).getConstraints(info));
-        }
+        ret.addAll(this.getArgumentListConstraints(info));
         //Overloading:
         Set<Constraint> methodConstraints = new HashSet<>();
-        for(MethodAssumption m : info.getMethods(name, arglist)){
-            Constraint methodConstraint = new Constraint();
-            methodConstraint.add(ConstraintsFactory.createPair(receiver.getType(), m.getReceiverType(), PairOperator.SMALLERDOT, info));
-            methodConstraint.add(ConstraintsFactory.createPair(m.getReturnType(), this.getType(), PairOperator.SMALLERDOT, info));
-            for(int i = 0;i<arglist.getArguments().size();i++){
-                methodConstraint.add(ConstraintsFactory.createPair(m.getArgTypes().get(i),
-                        arglist.getArguments().get(i).getType(), PairOperator.SMALLERDOT, info));
-            }
-            methodConstraints.add(methodConstraint);
+        for(MethodAssumption m : this.getMethods(name, arglist, info)){
+            methodConstraints.add(generateConstraint(m, info));
         }
         if(methodConstraints.size()<1){
             throw new TypeinferenceException("Methode "+name+" ist nicht vorhanden!",getOffset());
@@ -53,4 +49,57 @@ public class MethodCall extends Statement
         ret.addOderConstraint(methodConstraints);
         return ret;
     }
+
+    protected Constraint<Pair> generateConstraint(MethodAssumption forMethod, TypeInferenceBlockInformation info){
+        Constraint methodConstraint = new Constraint();
+        methodConstraint.add(ConstraintsFactory.createPair(receiver.getType(), forMethod.getReceiverType(), PairOperator.SMALLERDOT, info));
+        methodConstraint.add(ConstraintsFactory.createPair(forMethod.getReturnType(), this.getType(), PairOperator.SMALLERDOT, info));
+        methodConstraint.addAll(generateParameterConstraints(forMethod, info));
+        return methodConstraint;
+    }
+
+    protected Set<Pair> generateParameterConstraints(MethodAssumption forMethod, TypeInferenceBlockInformation info) {
+        Set<Pair> ret = new HashSet<>();
+        for(int i = 0;i<arglist.getArguments().size();i++){
+            ret.add(ConstraintsFactory.createPair(forMethod.getArgTypes().get(i),
+                    arglist.getArguments().get(i).getType(), PairOperator.SMALLERDOT, info));
+        }
+        return ret;
+    }
+
+
+    public List<MethodAssumption> getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) {
+        List<MethodAssumption> ret = new ArrayList<>();
+        for(ClassOrInterface cl : info.getAvailableClasses()){
+            for(Method m : cl.getMethods()){
+                if(m.getName().equals(name) &&
+                        m.getParameterList().getFormalparalist().size() == arglist.getArguments().size()){
+                    RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType());
+
+                    ret.add(new MethodAssumption(cl.getType(), retType, convertParams(m.getParameterList(),info)));
+                }
+            }
+        }
+        return ret;
+    }
+
+    protected List<RefTypeOrTPHOrWildcardOrGeneric> convertParams(ParameterList parameterList, TypeInferenceBlockInformation info){
+        List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
+        for(FormalParameter fp : parameterList.getFormalparalist()){
+            params.add(info.checkGTV(fp.getType()));
+        }
+        return params;
+    }
+
+    public ArgumentList getArgumentList() {
+        return arglist;
+    }
+
+    public ConstraintSet getArgumentListConstraints(TypeInferenceBlockInformation info) {
+        ConstraintSet ret = new ConstraintSet();
+        for(int i = 0;i<arglist.getArguments().size();i++){
+            ret.addAll(arglist.getArguments().get(i).getConstraints(info));
+        }
+        return ret;
+    }
 }
diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java b/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java
index 17e3e078..7cc707d6 100755
--- a/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java
+++ b/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java
@@ -1,25 +1,28 @@
 package de.dhbwstuttgart.syntaxtree.statement;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
+import de.dhbwstuttgart.exceptions.TypeinferenceException;
+import de.dhbwstuttgart.parser.NullToken;
+import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
+import de.dhbwstuttgart.syntaxtree.Method;
 import de.dhbwstuttgart.syntaxtree.type.RefType;
 import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
+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 org.antlr.v4.runtime.Token;
 import sun.reflect.generics.reflectiveObjects.NotImplementedException;
 
 
-public class NewClass extends Statement
+public class NewClass extends MethodCall
 {
-    public NewClass(int offset,int variableLength)
-    {
-        super(null,null);
-    }
-
-    private ArgumentList arglist;
-	private boolean isStatement = false;
-
     /**
      *
      * @param newClass Typ der Instanzierten Klasse
@@ -27,19 +30,49 @@ public class NewClass extends Statement
      * @param start
      */
     public NewClass(RefType newClass, ArgumentList args, Token start) {
-        super(newClass, start);
-        this.arglist = args;
+        super(newClass, new Receiver(new EmptyStmt(start)), "new "+newClass.getName().toString(), args, start);
     }
 
-
-    public ArgumentList getArgumentList()
-    {
-       return this.arglist;
+    public List<MethodAssumption> getConstructors(TypeInferenceBlockInformation info, RefType ofType, ArgumentList argList){
+        List<MethodAssumption> 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;
     }
 
+    @Override
+    protected Constraint<Pair> generateConstraint(MethodAssumption forMethod, TypeInferenceBlockInformation info){
+        Constraint methodConstraint = new Constraint();
+        methodConstraint.add(ConstraintsFactory.createPair(forMethod.getReturnType(), this.getType(), PairOperator.SMALLERDOT, info));
+        methodConstraint.addAll(generateParameterConstraints(forMethod, info));
+        return methodConstraint;
+    }
+
+    @Override
+    public List<MethodAssumption> getMethods(String name, ArgumentList arglist, TypeInferenceBlockInformation info) {
+        return getConstructors(info, (RefType) this.getType(), arglist);
+    }
 
     @Override
     public ConstraintSet getConstraints(TypeInferenceBlockInformation info) {
-        throw new NotImplementedException();
+        ConstraintSet ret = new ConstraintSet();
+        ret.addAll(this.getArgumentListConstraints(info));
+        //Overloading:
+        Set<Constraint> methodConstraints = new HashSet<>();
+        for(MethodAssumption m : this.getConstructors(info, (RefType) this.getType(), this.getArgumentList())){
+            methodConstraints.add(generateConstraint(m, info));
+        }
+        if(methodConstraints.size()<1){
+            throw new TypeinferenceException("Konstruktor in Klasse "+this.getType().toString()+" ist nicht vorhanden!",getOffset());
+        }
+        ret.addOderConstraint(methodConstraints);
+        return ret;
     }
 }
diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/ThisCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/ThisCall.java
index 8dea4bbd..e82405c0 100644
--- a/src/de/dhbwstuttgart/syntaxtree/statement/ThisCall.java
+++ b/src/de/dhbwstuttgart/syntaxtree/statement/ThisCall.java
@@ -8,7 +8,7 @@ public class ThisCall extends MethodCall
 {
     public ThisCall(Receiver receiver, ArgumentList arglist, int offset)
     {
-		super(null, null, null, null);
+		super(null, null, null, null, null);
 
 	}
     
diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/UnaryExpr.java b/src/de/dhbwstuttgart/syntaxtree/statement/UnaryExpr.java
index 06899933..2157560c 100755
--- a/src/de/dhbwstuttgart/syntaxtree/statement/UnaryExpr.java
+++ b/src/de/dhbwstuttgart/syntaxtree/statement/UnaryExpr.java
@@ -9,6 +9,6 @@ public abstract class UnaryExpr extends MethodCall
 
     public UnaryExpr(Token offset)
     {
-        super(null,null,null,null);
+        super(null,null,null,null,null);
     }
 }
diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java b/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java
index ec3ecb26..fe1c0cc9 100644
--- a/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java
+++ b/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java
@@ -2,14 +2,14 @@ package de.dhbwstuttgart.typeinference.assumptions;
 
 import de.dhbwstuttgart.exceptions.NotImplementedException;
 import de.dhbwstuttgart.parser.NullToken;
-import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
-import de.dhbwstuttgart.syntaxtree.Field;
-import de.dhbwstuttgart.syntaxtree.FormalParameter;
-import de.dhbwstuttgart.syntaxtree.Method;
+import de.dhbwstuttgart.syntaxtree.*;
 import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
 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.constraints.Constraint;
+import de.dhbwstuttgart.typeinference.constraints.Pair;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -32,7 +32,7 @@ public class TypeInferenceInformation {
         classes = availableClasses;
     }
 
-    private RefTypeOrTPHOrWildcardOrGeneric checkGTV(RefTypeOrTPHOrWildcardOrGeneric type){
+    public RefTypeOrTPHOrWildcardOrGeneric checkGTV(RefTypeOrTPHOrWildcardOrGeneric type){
         if(type instanceof GenericRefType){
             return TypePlaceholder.fresh(new NullToken());
         }else{
@@ -40,25 +40,6 @@ public class TypeInferenceInformation {
         }
     }
 
-    public List<MethodAssumption> getMethods(String name, ArgumentList arglist) {
-        List<MethodAssumption> ret = new ArrayList<>();
-        for(ClassOrInterface cl : classes){
-            for(Method m : cl.getMethods()){
-                if(m.getName().equals(name) &&
-                        m.getParameterList().getFormalparalist().size() == arglist.getArguments().size()){
-                    RefTypeOrTPHOrWildcardOrGeneric retType = checkGTV(m.getType());
-
-                    List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
-                    for(FormalParameter fp : m.getParameterList().getFormalparalist()){
-                        params.add(checkGTV(fp.getType()));
-                    }
-                    ret.add(new MethodAssumption(cl.getType(), retType, params));
-                }
-            }
-        }
-        return ret;
-    }
-
     public List<FieldAssumption> getFields(String name){
         List<FieldAssumption> ret = new ArrayList<>();
         for(ClassOrInterface cl : classes){
diff --git a/test/javFiles/Generics.jav b/test/javFiles/Generics.jav
index 703ba6c2..9e4361a9 100644
--- a/test/javFiles/Generics.jav
+++ b/test/javFiles/Generics.jav
@@ -4,3 +4,9 @@ class Generics<B> {
         return mt1(a, a);
     }
 }
+
+class Test {
+    methode(String s){
+        return new Generics<String>().mt1(s,s);
+    }
+}
diff --git a/test/parser/GeneralParserTest.java b/test/parser/GeneralParserTest.java
index 4617b8a5..53cb6f7b 100644
--- a/test/parser/GeneralParserTest.java
+++ b/test/parser/GeneralParserTest.java
@@ -30,7 +30,7 @@ public class GeneralParserTest{
 		filenames.add("ImportTest.jav");
 		filenames.add("CastTest.jav");
 		filenames.add("StatementsTest.jav");
-		filenames.add("Methods.jav");
+		//filenames.add("Methods.jav");
 		filenames.add("ImportTestGeneric.jav");
 		filenames.add("CastTest.jav");
 		//filenames.add("BoundedParameter.jav");