package de.dhbwstuttgart.syntaxtree;

import java.util.ArrayList;

import de.dhbwstuttgart.parser.NullToken;
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.assumptions.TypeInferenceInformation;
import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory;
import de.dhbwstuttgart.typeinference.constraints.Pair;
import org.antlr.v4.runtime.Token;

import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.syntaxtree.statement.Block;

/**
 * Stellt eine Methode dar. Problem: Parser kann nicht zwischen Methode und
 * Konstruktor unterscheiden. Daher kann diese Klasse beides sein. Dies wird mit
 * dem ParserPostProcessing behoben.
 * 
 * @author janulrich
 *
 */
public class Method extends Field implements IItemWithOffset
{
	private Block block;
	private ParameterList parameterlist = new ParameterList(new ArrayList<>(), new NullToken());
	private ExceptionList exceptionlist;
	private GenericDeclarationList generics;

	public Method(String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block block,
				  GenericDeclarationList gtvDeclarations, Token offset) {
		super(name, returnType, modifiers, offset);
		this.parameterlist = parameterList;
		this.block = block;
		this.generics = gtvDeclarations;
	}

	public ConstraintSet getConstraints(TypeInferenceInformation info, ClassOrInterface currentClass) {
		ConstraintSet ret = new ConstraintSet();
		TypeInferenceBlockInformation blockInfo = new TypeInferenceBlockInformation(info.getAvailableClasses(), currentClass, this);
		ret.addAll(block.getConstraints(blockInfo));
		/*
		ret.addUndConstraint(
				ConstraintsFactory.createPair(block.getType(), this.getType(), blockInfo));
		*/
		return ret;
	}

	public ParameterList getParameterList() {
		return parameterlist;
	}
	
	//erweitert Sebastian Ritt
	public Block get_Block() {
		return block; 
	}


	public Iterable<? extends GenericTypeVar> getGenerics() {
		return generics;
	}
}
