// ino.module.Method.8564.package 
package de.dhbwstuttgart.syntaxtree;
// ino.end
// ino.module.Method.8564.import 
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;

import de.dhbwstuttgart.logger.Logger;

import de.dhbwstuttgart.bytecode.ClassFile;
import de.dhbwstuttgart.core.IItemWithOffset;
import de.dhbwstuttgart.core.MyCompiler;
import de.dhbwstuttgart.myexception.JVMCodeException;
import de.dhbwstuttgart.myexception.SCMethodException;
import de.dhbwstuttgart.myexception.SCStatementException;
import de.dhbwstuttgart.parser.JavaClassName;
import de.dhbwstuttgart.syntaxtree.misc.DeclId;
import de.dhbwstuttgart.syntaxtree.modifier.Modifiers;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.SingleConstraint;
import de.dhbwstuttgart.typeinference.TypeInsertable;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions;
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint;




// ino.class.Method.23482.declaration 
/**
 * 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, TypeInsertable
// ino.end
// ino.class.Method.23482.body
{
    // ino.attribute.block.23488.declaration 
    private Block         block;
    // ino.end
    // ino.attribute.parameterlist.23491.declaration 
    public ParameterList parameterlist = new ParameterList();
    // ino.end
    // ino.attribute.exceptionlist.23494.declaration 
    private ExceptionList exceptionlist;
    // ino.end
    // ino.attribute.returntype.23497.declaration 
    private Type          returntype;
    // ino.end
    
    // ino.attribute.genericMethodParameters.23500.decldescription type=javadoc
    /**
     * HOTI 4.5.06
     * Dieser Vektor beinhaltet alle Generischen Typen und v.a. die
     * F-Bounded-Generics, die die Methode besitzt
     * size()==0, falls es keine gibt
     */
    // ino.end
    // ino.attribute.genericMethodParameters.23500.declaration 
    //private Vector<GenericTypeVar> genericMethodParameters=new Vector<GenericTypeVar>();
    // ino.end
    
    // ino.attribute.overloadedID.23503.declaration 
    private int           overloadedID;
    // ino.end
    // ino.attribute.isAbstract.23506.declaration 
    private boolean isAbstract = false;
    // ino.end
    // ino.attribute.types_in_parameterlist.23509.declaration 
    private Vector<String>        types_in_parameterlist = new Vector<String>();
    // ino.end
    // ino.attribute.m_LineNumber.23512.declaration 
    private int m_LineNumber = MyCompiler.NO_LINENUMBER;
    // ino.end
    private int m_Offset = -1; //hinzugef�gt hoth: 07.04.2006
    // ino.attribute.inferencelog.23515.declaration 
    protected static Logger inferencelog = Logger.getLogger("inference");
    // ino.end
    // ino.attribute.parserlog.23518.declaration 
    protected static Logger parserlog = Logger.getLogger("parser");
    // ino.end
    
    public Method(int offset){
    	super(offset);
    }
    
    public Method(String name, Type returnType, ParameterList parameterList, Block block, GenericDeclarationList gtvDeclarations, int offset){
    	this(offset);
    	/*
    	if(parameterList != null)parameterList.parserPostProcessing(this);
    	if(block != null)block.parserPostProcessing(this);
    	if(gtvDeclarations != null)gtvDeclarations.parserPostProcessing(this);
    	*/
    	this.set_Method_Name(name);
    	this.setParameterList(parameterList);
    	this.set_Block(block);
    	this.setGenericParameter(gtvDeclarations);
    	this.setReturnType(returnType);
    }
    
    /*
    // ino.method.setGenericMethodParameters.23521.definition 
    public void setGenericMethodParameters(Vector<GenericTypeVar> genericMethodParameters)
    // ino.end
    // ino.method.setGenericMethodParameters.23521.body 
    {
        this.genericMethodParameters=genericMethodParameters;
    }
    // ino.end
    // ino.method.getGenericMethodParameters.23524.definition 
    public Vector<GenericTypeVar> getGenericMethodParameters()
    // ino.end
    // ino.method.getGenericMethodParameters.23524.body 
    {
        return(genericMethodParameters);
    }
    // ino.end
    */
    /*
    // ino.method.sc_init_parameterlist.23530.definition 
    public void sc_init_parameterlist(boolean ext)
    // ino.end
    // ino.method.sc_init_parameterlist.23530.body 
    {
        DeclId hilf=null;
        Vector<FormalParameter> list;
        FormalParameter para;
        String typeofpara;
        int i=1;
        if(this.getParameterList()!=null) //es gibt Parameter, dann:
        {
        hilf=declid.elementAt(0);
        if(ext)
            parserlog.debug("Semantik-Check hat in Methode "+hilf.get_Name()+" bergabewerte gefunden:"); 
        list=this.getParameterList().sc_get_Formalparalist();  //Vector Formalparalist aus FormalParameterList wird zwischen gesichert
        for(Enumeration<FormalParameter> el2=list.elements(); el2.hasMoreElements();)
        {
            para=el2.nextElement();
            typeofpara=para.getTypeName();
            if(ext)
                parserlog.debug("       "+i+". Parameter hat Typ "+typeofpara);
            types_in_parameterlist.addElement(typeofpara); //Typ der Parameter werden im Vector abgelegt
            i++;
        }
        }
        else //keine Parameter vorhanden:
        {
        if(ext)
        {
            hilf=declid.elementAt(0);
            parserlog.debug("Semantik-Check hat in Methode "+hilf.get_Name()+" keine bergabewerte gefunden.");
        }
        }
        if(ext)
        {
            parserlog.debug("Semantik-Check hat in Methode "+hilf.get_Name()+" "+ types_in_parameterlist.size()+" bergabeparameter gefunden."); 
            parserlog.debug("             namentlich: "+types_in_parameterlist.toString());
        }
    }
    // ino.end
     */
    // ino.method.getTypeName.23533.defdescription type=line
    // Eine der beiden Funktionen ist ueberflssig. Wer sich daran strt kann die        
    // get_ReturnType() auf eigene Gefahr lschen. 
    // ino.end
  
    // ino.method.getTypeName.23533.definition 
    public JavaClassName getTypeName()
    // ino.end
    // ino.method.getTypeName.23533.body 
    {
    if( this.getType() == null )
        return null;
    else
        return this.getType().getName();
    }
    // ino.end

    // ino.method.get_Block.23536.definition 
    public Block get_Block()
    // ino.end
    // ino.method.get_Block.23536.body 
    {
    return block;
    }
    // ino.end
 
    // ino.method.setReturnType.23539.defdescription type=javadoc
    /**
     * <br/>Author: Jrg Buerle
     * @param type
     */
    // ino.end
    // ino.method.setReturnType.23539.definition 
    private void setReturnType(Type type)
    // ino.end
    // ino.method.setReturnType.23539.body 
    {
        this.returntype = type;
    }
    // ino.end

    // ino.method.set_Block.23542.definition 
    public void set_Block( Block blo)
    // ino.end
    // ino.method.set_Block.23542.body 
    {
    	if(blo.getType() == null)blo.setType(this.returntype);
    	this.block = blo;
    }
    // ino.end

    // ino.method.set_Modifiers.23545.definition 
    public void set_Modifiers(Modifiers modif)
    // ino.end
    // ino.method.set_Modifiers.23545.body 
    {
    declid.firstElement().set_Modifiers(modif);
        //  this.modi = modif;
    }
    // ino.end

    // ino.method.set_ExceptionList.23548.definition 
    public void set_ExceptionList(ExceptionList exlist)
    // ino.end
    // ino.method.set_ExceptionList.23548.body 
    {
    this.exceptionlist = exlist;
    }
    // ino.end

    // ino.method.setParameterList.23551.definition 
    public void setParameterList( ParameterList paralist )
    // ino.end
    // ino.method.setParameterList.23551.body 
    { 
        this.parameterlist = paralist;
    }
    // ino.end

    // ino.method.getParameterList.23554.definition 
    public ParameterList getParameterList( )
    // ino.end
    // ino.method.getParameterList.23554.body 
    { 
        // otth: gibt die Parameterliste zurueck
        return this.parameterlist;
    }
    // ino.end
    
    // ino.method.getParameterCount.23557.defdescription type=javadoc
    /**
     * Author: Jrg Buerle<br/>
     * @return Die Anzahl der Methoden-Paramater
     */
    // ino.end
    // ino.method.getParameterCount.23557.definition 
    public int getParameterCount()
    // ino.end
    // ino.method.getParameterCount.23557.body 
    {
        if(this.getParameterList() == null)
            return 0;
        else
            return this.getParameterList().getParameterCount();
    }
    // ino.end

    // ino.method.get_ExceptionList.23560.definition 
    public ExceptionList get_ExceptionList()
    // ino.end
    // ino.method.get_ExceptionList.23560.body 
    {
        // otth: gibt die Exceptionliste zurueck
        return this.exceptionlist;
    }
    // ino.end
    
    // ino.method.getOverloadedID.23563.definition 
    public int getOverloadedID()
    // ino.end
    // ino.method.getOverloadedID.23563.body 
    {
        return(overloadedID);
    }
    // ino.end

    // ino.method.setOverloadedID.23566.definition 
    public void setOverloadedID(int overloadedID)
    // ino.end
    // ino.method.setOverloadedID.23566.body 
    {
        this.overloadedID=overloadedID;
    }
    // ino.end
    

    
    
    // ino.method.get_codegen_Param_Type.23572.definition 
    public String get_codegen_Param_Type(Vector paralist)
    // ino.end
    // ino.method.get_codegen_Param_Type.23572.body 
    {
        String ret = new String();
        if(this.getParameterList() == null)
        {
            ret += "()";
        } 
        else
        {
            ret += this.getParameterList().get_codegen_ParameterList(paralist);
        }
        if(this.getType() == null)
        {
            ret += "V";
        } 
        else
        {
            ret += this.getType().get_codegen_Type(paralist);
        }
        return ret;
    }
    // ino.end
    
    
    
    // ino.method.get_Method_Name.23575.definition 
    public String get_Method_Name()
    // ino.end
    // ino.method.get_Method_Name.23575.body 
    {
        DeclId hilf=declid.elementAt(0);
        return hilf.get_Name();
    }
    // ino.end

    // ino.method.get_Type_Paralist.23578.definition 
    public Vector get_Type_Paralist()
    // ino.end
    // ino.method.get_Type_Paralist.23578.body 
    {
        return types_in_parameterlist;
    }
    // ino.end
    
    
    
    // ino.method.codegen.23581.definition 
    public void codegen(ClassFile classfile, Vector paralist)
    throws JVMCodeException
    // ino.end
    // ino.method.codegen.23581.body 
    {
        classfile.add_method(declid.firstElement().get_Name(), this.get_codegen_Param_Type(paralist), this.getParameterList(), this.getType(), block, declid.firstElement().get_access_flags(), paralist, isAbstract);
    }
    // ino.end

    // ino.method.getLineNumber.23584.definition 
    public int getLineNumber()
    // ino.end
    // ino.method.getLineNumber.23584.body 
    {
        return m_LineNumber;
    }
    // ino.end
    
    // ino.method.setLineNumber.23587.definition 
    public void setLineNumber(int lineNumber)
    // ino.end
    // ino.method.setLineNumber.23587.body 
    {
        m_LineNumber = lineNumber;
    }
    // ino.end
    
    // ino.method.getOffset.23590.defdescription type=line
    // hinzugef�gt hoth: 07.04.2006
    // ino.end
    // ino.method.getOffset.23590.definition 
    public int getOffset()
    // ino.end
    // ino.method.getOffset.23590.body 
    {
        return m_Offset;
    }
    // ino.end
    
    // ino.method.getVariableLength.23593.definition 
    public int getVariableLength()
    // ino.end
    // ino.method.getVariableLength.23593.body 
    {
        return get_Method_Name().length();
    }
    // ino.end
    
   // ino.method.setOffset.23596.defdescription type=line
   // hinzugef�gt hoth: 07.04.2006
   // ino.end
    // ino.method.setOffset.23596.definition 
    public void setOffset(int Offset)
    // ino.end
    // ino.method.setOffset.23596.body 
    {
        m_Offset = Offset;
    }
    // ino.end

    
    // ino.method.getTypeLineNumber.23602.defdescription type=javadoc
    /**
     * <br>Author: Jrg Buerle
     * @return
     */
    // ino.end
    // ino.method.getTypeLineNumber.23602.definition 
    public int getTypeLineNumber()
    // ino.end
    // ino.method.getTypeLineNumber.23602.body 
    {
        return this.getLineNumber();
    }
    // ino.end

    // ino.method.toString.23605.defdescription type=javadoc
    /**
     * <br/>Author: Martin Pl�micke
     * @return
     */
    // ino.end
    // ino.method.toString.23605.definition 
    public String toString()
    // ino.end
    // ino.method.toString.23605.body 
    {
        return this.getType() + " "+ this.get_Name() +( (block!=null)?block.toString():"");
    }
    // ino.end
    
    // ino.method.setAbstract.23608.defdescription type=javadoc
    /**
     * Legt fuer die ByteCodeGen fest, ob Bytecode
     * innerhalb der Methode generiert wird.
     */
    // ino.end
    // ino.method.setAbstract.23608.definition 
    public void setAbstract(boolean b)
    // ino.end
    // ino.method.setAbstract.23608.body 
    {
        isAbstract = b;
    }
    // ino.end
    
    // ino.method.isAbstract.23611.defdescription type=javadoc
    /**
     * Gibt zurueck, ob ByteCode innerhabl der Methode
     * generiert wird.
     */
    // ino.end
    // ino.method.isAbstract.23611.definition 
    public boolean isAbstract()
    // ino.end
    // ino.method.isAbstract.23611.body 
    {
        return isAbstract;
    }
    
    @Override
    public void wandleRefTypeAttributes2GenericAttributes(Vector<Type> classParalist)
    {
    	/*
    	Vector<Type> paralist = new Vector<Type>();//Mit den Generischen Typen der Methode
    	paralist.addAll(classParalist);
    	paralist.addAll(this.genericMethodParameters);
    	
        // Zuerst Returntype untersuchen
        Type returnType=getType();
        Type pendantReturnType = null;
        if(returnType instanceof RefType)pendantReturnType = ((RefType)returnType).findGenericType(paralist, new Vector<GenericTypeVar>());
        //GenericTypeVar pendantReturnType=ClassHelper.findGenericType(returnType, paralist,genericMethodParameters);
        if(pendantReturnType!=null){    //Wenn generisch, dann modifizieren
            setReturnType(pendantReturnType);
        }                                       
        
        // Dann parameterlist untersuchen
        for(int par=0;par<getParameterCount();par++){
            FormalParameter fp=parameterlist.formalparameter.get(par);
            Type fpType=fp.getType();
            // Nur wenn es sich um ein RefType-Field handelt
            Type pendantPara = null;
            if(fpType instanceof RefType)pendantPara = ((RefType)fpType).findGenericType(paralist, new Vector<GenericTypeVar>());
            //GenericTypeVar pendantPara=ClassHelper.findGenericType(fpType,paralist,genericMethodParameters);
            if(pendantPara!=null){  //Wenn generisch, dann modifizieren
                fp.setType(pendantPara);
            }                       
        }
        
        // Zuletzt alle Lokalen Variablendeklarationen durchgehen
        if(block!=null){
            block.wandleRefTypeAttributes2GenericAttributes(paralist,genericMethodParameters);
        }
        */
    }
    
    public void set_Method_Name(String string)
    {
    	if(declid.size()==0)declid.add(0, new DeclId(string));
        declid.set(0,new DeclId(string));
    }
    
   
    
	public ConstraintsSet TYPE(TypeAssumptions ass) {
		ConstraintsSet ret = new ConstraintsSet();
		TypeAssumptions localAss = new TypeAssumptions();
		localAss.add(ass); //Die globalen Assumptions anh�ngen
		//Generische Parameterdeklarationen den Assumptions anf�gen:
		for(GenericTypeVar gtv : this.getGenericParameter()){
			localAss.add(gtv.createAssumptions());
		}
		for(GenericTypeVar gtv : this.getGenericParameter()){
			ret.add(gtv.TYPE(localAss));
		}
		
		//TypeCheck, falls es sich um einen RefType handelt:
		this.returntype = this.returntype.checkTYPE(localAss, this);
		/*
		if(this.returntype!=null && (this.returntype instanceof RefType)&&
				!(this.returntype instanceof mycompiler.mytype.Void)){//Sonderfall der Methode: Ihr Typ darf Void definiert werden.
			Type replaceType = null;
			replaceType = ass.getTypeFor((RefType)this.returntype);
			if(replaceType == null)throw new TypeinferenceException("Der Typ "+this.getType().getName()+" ist nicht korrekt",this);
			this.returntype = replaceType;
		}
		*/
		//Die Parameter zu den Assumptions hinzuf�gen:
		if(this.parameterlist!=null)for(FormalParameter param : this.parameterlist){
			
			param.setType(param.getType().checkTYPE(localAss, this));
			/*
			if(param.getType() instanceof RefType)
			{
				Type replaceType = null;
				replaceType = ass.getTypeFor((RefType)param.getType());
				if(replaceType == null)
					throw new TypeinferenceException("Der Typ "+param.getType().getName()+" ist nicht korrekt",param);
				param.setType(replaceType);
			}
			*/
			
			localAss.addAssumption(new ParameterAssumption(param));
		}
		ret.add(this.block.TYPEStmt(localAss));
		//eine Verkn�pfung mit der Type Assumption aus dem Assumption Set und dem ermittelten Typ der Methode:
		ret.add(new SingleConstraint(this.block.getType().TYPE(localAss, this), this.returntype.TYPE(localAss, this)));
		return ret;
	}
    
	/**
	 * @author Andreas Stadelmeier, a10023
	 * @return die TypInformationen der Statements dieser Methode.
	 */
	public String getTypeInformation(){
		if(this.parameterlist!=null)return "Methode "+this.get_Name()+ " Parameter: "+this.parameterlist.getTypeInformation()+", Block: "+this.block.getTypeInformation();
		return "Methode "+this.get_Name()+" : "+this.getType()+", Block: "+this.block.getTypeInformation();
	}
	
	@Override
	public JavaCodeResult printJavaCode(ResultSet resultSet) {
		JavaCodeResult ret = new JavaCodeResult();
		ret.attach(this.getType().printJavaCode(resultSet)).attach(" ").attach(this.get_Method_Name()).attach("(").attach(this.getParameterList().printJavaCode(resultSet)).attach(")\n"); 
		ret.attach(this.block.printJavaCode(resultSet));

		return ret;
	}
	
	/**
	 * Liefert die MethodAssumption zu dieser Methode
	 */
	@Override
	public TypeAssumptions createTypeAssumptions(Class classmember) {
		Class parentClass = classmember;//this.getParentClass();
		TypeAssumptions ret = new TypeAssumptions();
		ret.addAssumption(new MethodAssumption(this, parentClass));
		return ret;
		/*
		TypeAssumptions assumptions = new TypeAssumptions();
		this.assumedType = null;
		//if((this.get_Method_Name().equals(classmember.getName()) || this.get_Method_Name().equals("<init>")) && ((this.getType().equals(new mycompiler.mytype.Void(0))) || this.getType() instanceof TypePlaceholder)){
		if((this.get_Method_Name().equals(classmember.getName()) || this.get_Method_Name().equals("<init>"))) {
			this.set_Method_Name("<init>");
			this.assumedType = new RefType(classmember.getName(),0);
			this.setReturnType(this.assumedType);
			this.assumedType = new RefType("void",0);
			//Return constructorReturnStatement = new Return(0,0);
			//constructorReturnStatement.retexpr = 
			//this.block.statements.add(constructorReturnStatement);
		}
		//hoth: 06.04.2006
		//durchlaufe Block und suche nach Objektvariablen fuer Offset-Markierung
		Iterator<CTypeAssumption> fieldVarIterator = assumptions.iterator();
		while (fieldVarIterator.hasNext()) 
		{
		//Wenn ObjektVariable
		CTypeAssumption dieAssum = fieldVarIterator.next();
		if(dieAssum instanceof CInstVarTypeAssumption)
		{
			Class.isFirstLocalVarDecl=false; 
			if(this.get_Block() != null)
				this.get_Block().addOffsetsToAssumption(dieAssum,dieAssum.getIdentifier(),true);  
		}
		}
		
		//methodList.addElement(method);
		
		//F�r V_fields_methods:
		CMethodTypeAssumption methodAssum = new CMethodTypeAssumption(classmember.getType(), this.get_Method_Name(), this.getType(), this.getParameterCount(),this.getLineNumber(),this.getOffset(),new Vector<Integer>(),this.getGenericMethodParameters());  // Typannahme bauen...
		
		
		//Methode in V_Fields_methods ablegen
		//Dabei wird die OverloadedMethodID ermittelt !!
		//=> Method setzenuct
		
		
		assumptions.add(methodAssum);               
		this.setOverloadedID(methodAssum.getHashSetKey().getOverloadedMethodID());                
		
		
		//F�r die V_i:
		CTypeAssumptionSet localAssum = new CTypeAssumptionSet();
		
		//Bauen...
		ParameterList parameterList = this.getParameterList();
		if(parameterList!=null){
		for(int i=0; i<parameterList.sc_get_Formalparalist().size(); i++){
		FormalParameter para = parameterList.sc_get_Formalparalist().elementAt(i);
		// F�r V_fields_methods:
		CParaTypeAssumption paraAssum = new CParaTypeAssumption(classmember.getName(), this.get_Method_Name(), this.getParameterCount(), this.getOverloadedID(),para.get_Name(), para.getType(), para.getLineNumber(),para.getOffset(),new Vector<Integer>());
		//fuege Offsets fuer Parameter hinzu, hoth: 06.04.2006
		Class.isFirstLocalVarDecl=false;
	
			if(this.get_Block() != null)
				this.get_Block().addOffsetsToAssumption(paraAssum,paraAssum.getIdentifier(),true);
	
			methodAssum.addParaAssumption(paraAssum);
	
			// F�r die V_i:
			CLocalVarTypeAssumption varAssum = new CLocalVarTypeAssumption(classmember.getName(), this.get_Method_Name(), this.getParameterCount(), this.getOverloadedID(),"1", para.get_Name(),para.getType(), para.getLineNumber(),para.getOffset(),new Vector<Integer>());
			localAssum.addElement(varAssum);
			//rememberLocals.addElement(varAssum);
		}
		}               
		//...und hinzuf�gen:
	
		assumptions.add(localAssum);//Assumptions f�r lokale Variablen den Assumptions hinzuf�gen
		
		//Hier wird der Typ der als Assumption eingetragen wird in die Variable assumedType dieser Klasse geschrieben:
		if(this.assumedType == null) // Falls der Typ nicht schon gesetzt ist. Das ist der Fall, falls die Methode ein Konstruktor ist
			this.assumedType = methodAssum.getAssumedType();
		
		return assumptions;
		*/
	}
	
	
	@Override
	public void parserPostProcessing(SyntaxTreeNode parent){
		if(this.getType()==null)this.setType(TypePlaceholder.fresh(this));
		//Bei dem Elterntyp der Methode darf es sich nur um eine Klasse handeln, daher Cast ohne Pr�fung:
		//Class parentClass = (Class)parent;
		if(this.returntype == null)this.returntype = TypePlaceholder.fresh(this);
		super.parserPostProcessing(parent);
		/*
		this.returntype.parserPostProcessing(this);
		if(this.parameterlist != null){
			for(FormalParameter fp : this.parameterlist){
				fp.parserPostProcessing(this);
			}
		}
		for(GenericTypeVar gtv : this.getGenericParameter()){
			gtv.parserPostProcessing(this);
		}
		*/
	}
	
	@Override
	public Vector<SyntaxTreeNode> getChildren() {
		Vector<SyntaxTreeNode> ret = new Vector<SyntaxTreeNode>();
		ret.add(this.block);
		ret.add(this.parameterlist);
		ret.addAll(this.getGenericParameter());
		ret.add(this.returntype);
		return ret;
	}
	
	@Override
	public void setType(Type t){
		// Methode und Block teilen sich einen ReturnType:
		//this.block.setType(t);
		this.returntype = t;
		this.returntype.parent = this; //TODO: Dieser Hack sollte nicht n�tig sein. (Parser �ndern)
	}
	
	/**
	 * Der Typ einer Methode ist ihr Returntype
	 */
	@Override
	public Type getType(){
		//Methode und Block teilen sich einen ReturnType:
		return this.returntype;
	}
	
	public static Method createEmptyMethod(String withSignature, Class parent){
		Method ret = new Method(0);
		DeclId DImethod = new DeclId();
		DImethod.set_Name(withSignature);
		ret.set_DeclId(DImethod);
		Block tempBlock = new Block();
		//tempBlock.setType(new RefType(parent.getName(),0));
		ret.set_Block(tempBlock);
		ret.parserPostProcessing(parent);
		return ret;
	}
	
	@Override
	public boolean equals(Object obj){
		if(!(obj instanceof Method))return false;
		Method equals = (Method) obj;
		if((this.returntype!=null && equals.returntype==null))return false;
		if((this.returntype==null && equals.returntype!=null))return false;
		if(this.returntype!=null && equals.returntype!=null)if(!this.returntype.equals(equals.returntype))return false;
		if(!this.parameterlist.equals(equals.parameterlist))return false;
		return super.equals(obj);
	}
	
	
}
// ino.end