// 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 de.dhbwstuttgart.typeinference.Menge; 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 Menge genericMethodParameters=new Menge(); // 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 Menge types_in_parameterlist = new Menge(); // 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(Menge genericMethodParameters) // ino.end // ino.method.setGenericMethodParameters.23521.body { this.genericMethodParameters=genericMethodParameters; } // ino.end // ino.method.getGenericMethodParameters.23524.definition public Menge 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; Menge 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(); //Menge Formalparalist aus FormalParameterList wird zwischen gesichert for(Enumeration 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 Menge 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 /** *
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
* @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(Menge 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 Menge 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, Menge 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 /** *
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 /** *
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(Menge classParalist) { /* Menge paralist = new Menge();//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 Menge()); //GenericTypeVar pendantReturnType=ClassHelper.findGenericType(returnType, paralist,genericMethodParameters); if(pendantReturnType!=null){ //Wenn generisch, dann modifizieren setReturnType(pendantReturnType); } // Dann parameterlist untersuchen for(int par=0;par()); //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("")) && ((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(""))) { this.set_Method_Name(""); 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 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 Menge(),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()); //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 Menge()); 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 Menge getChildren() { Menge ret = new Menge(); 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