package de.dhbwstuttgart.syntaxtree.statement;

import de.dhbwstuttgart.typeinference.ConstraintSet;
import de.dhbwstuttgart.typeinference.OderConstraint;
import de.dhbwstuttgart.typeinference.Pair;
import de.dhbwstuttgart.typeinference.UndConstraint;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import org.antlr.v4.runtime.Token;

import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;



public class MethodCall extends Statement
{
    private final String name;
    private Receiver receiver;
    private ArgumentList arglist;

    public MethodCall(Receiver receiver, String methodName, ArgumentList argumentList, Token offset){
		super(TypePlaceholder.fresh(offset),offset);
		this.arglist = argumentList;
        this.name = methodName;
        this.receiver = receiver;
	}

    @Override
    public ConstraintSet getConstraints(TypeInferenceInformation info) {
        ConstraintSet ret = receiver.getConstraints(info);
        //Overloading:
        OderConstraint overloading = new OderConstraint();
        for(MethodAssumption m : info.getMethods(name, arglist)){
            UndConstraint methodConstraints = new UndConstraint();
            methodConstraints.addConstraint(receiver.getType(), m.getReceiverType());
            methodConstraints.addConstraint(m.getReturnType(), this.getType());
            for(int i = 0;i<arglist.getArguments().size();i++){
                methodConstraints.addConstraint(m.getArgTypes().get(i),
                        arglist.getArguments().get(i).getType());
            }
        }
        ret.add(overloading);
        return ret;
    }
}