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.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;
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 SyntaxTreeNode implements IItemWithOffset, TypeScope
{
	public final Block block;
	public final int modifier;
	public final String name;
	private ParameterList parameterlist = new ParameterList(new ArrayList<>(), new NullToken());
	private ExceptionList exceptionlist;
	private GenericDeclarationList generics;
	private final RefTypeOrTPHOrWildcardOrGeneric returnType;

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

	public ParameterList getParameterList() {
		return parameterlist;
	}

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

	@Override
	public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
		return this.returnType;
	}

	@Override
	public void accept(ASTVisitor visitor) {
		visitor.visit(this);
	}

	@Override
	public Token getOffset() {
		return null;
	}

	public String getName() {
		return name;
	}
}
