// ino.module.MethodCall.8639.package package mycompiler.mystatement; // ino.end // ino.module.MethodCall.8639.import import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import mycompiler.mybytecode.ClassFile; import mycompiler.mybytecode.CodeAttribute; import mycompiler.mybytecode.JVMCode; import mycompiler.myclass.Class; import mycompiler.myclass.ClassBody; import mycompiler.myclass.DeclId; import mycompiler.myclass.FormalParameter; import mycompiler.myclass.Method; import mycompiler.myclass.ParameterList; import mycompiler.myclass.UsedId; import mycompiler.myexception.CTypeReconstructionException; import mycompiler.myexception.JVMCodeException; import mycompiler.myexception.SCExcept; import mycompiler.myexception.SCStatementException; import mycompiler.mytype.BoundedGenericTypeVar; import mycompiler.mytype.GenericTypeVar; import mycompiler.mytype.Pair; import mycompiler.mytype.RefType; import mycompiler.mytype.Type; import mycompiler.mytype.TypePlaceholder; import mycompiler.mytype.Void; import mycompiler.mytypereconstruction.CIntersectionType; import mycompiler.mytypereconstruction.CMultiplyTuple; import mycompiler.mytypereconstruction.CSubstitution; import mycompiler.mytypereconstruction.CSubstitutionGenVar; import mycompiler.mytypereconstruction.CSupportData; import mycompiler.mytypereconstruction.CTriple; import mycompiler.mytypereconstruction.CTypeReconstructionResult; import mycompiler.mytypereconstruction.set.CMultiplyTupleSet; import mycompiler.mytypereconstruction.set.CSubstitutionSet; import mycompiler.mytypereconstruction.set.CTripleSet; import mycompiler.mytypereconstruction.set.CTypeAssumptionSet; import mycompiler.mytypereconstruction.typeassumption.CMethodTypeAssumption; import mycompiler.mytypereconstruction.typeassumption.CParaTypeAssumption; import mycompiler.mytypereconstruction.typeassumption.CTypeAssumption; import mycompiler.mytypereconstruction.typeassumptionkey.CMethodKey; import mycompiler.mytypereconstruction.unify.FC_TTO; import mycompiler.mytypereconstruction.unify.Unify; import org.apache.log4j.Logger; // ino.end import sun.reflect.generics.reflectiveObjects.NotImplementedException; import typinferenz.ConstraintsSet; import typinferenz.FreshTypeVariable; import typinferenz.JavaCodeResult; import typinferenz.Overloading; import typinferenz.ResultSet; import typinferenz.TypeAssumptions; // ino.class.MethodCall.25623.declaration public class MethodCall extends Expr // ino.end // ino.class.MethodCall.25623.body { // ino.method.MethodCall.25627.definition public MethodCall(int offset, int variableLength) // ino.end // ino.method.MethodCall.25627.body { super(offset,variableLength); } // ino.end // ino.attribute.OK.25630.declaration private static final int OK = 0; // ino.end // ino.attribute.UNIFY_ERROR.25633.declaration private static final int UNIFY_ERROR = 1; // ino.end // ino.attribute.METHOD_NOT_FOUND_ERROR.25636.declaration private static final int METHOD_NOT_FOUND_ERROR = 2; // ino.end // ino.attribute.receiver.25639.declaration /** * Diese Variable speichert die Expression, welche die Klasse von welcher die Methode aufgerufen wird darstellt. */ private Receiver receiver; // ino.end // ino.attribute.arglist.25642.declaration private ArgumentList arglist=null; // ino.end private Vector exprtypes=new Vector(); //hier werden die Typen der �bergabewerten von sc_check eingetragen. // ino.attribute.class_name.25645.declaration private String class_name; //hier steht in welcher Klasse die Methode deklariert ist. // ino.end // ino.attribute.called_method.25648.declaration private Method called_method=null; //hier steht nach Ende von sc_check die aufgerufene Methode. // ino.end // ino.attribute.uebernachdurch.25651.declaration private Hashtable uebernachdurch; // ino.end // ino.attribute.finde_method.25654.declaration private Vector> finde_method=new Vector>(); // ino.end // ino.attribute.counter.25657.declaration private int counter; // ino.end // ino.attribute.methodsFittingMethodCall.25660.decldescription type=javadoc /** * Da der SemanticCheck nicht mehr ausgeführt wird, werden hier die bei der * Typrekonstruktion gefundenen Methoden abgespeichert. Problem ist hier jedoch, * dass der receiver in diesem Moment noch nicht fest steht. Deshalb wird je * Receiver ein Methodcall abgelegt. Dieser kann dann mit bspw. * methodsFittingMethodCAll.get("Vector") abgerufen werden. */ // ino.end // ino.attribute.methodsFittingMethodCall.25660.declaration private Hashtable methodsFittingMethodCall=new Hashtable(); // ino.end // ino.attribute.parserlog.25663.declaration protected static Logger parserlog = Logger.getLogger("parser"); // ino.end // ino.method.set_ArgumentList.25666.definition public void set_ArgumentList(ArgumentList al) // ino.end // ino.method.set_ArgumentList.25666.body { this.arglist = al; } // ino.end // ino.method.getArgumentList.25669.definition public ArgumentList getArgumentList() // ino.end // ino.method.getArgumentList.25669.body { if(this.arglist==null)return this.arglist = new ArgumentList(); return this.arglist; } // ino.end // ino.method.get_Receiver.25672.definition public Receiver get_Receiver() // ino.end // ino.method.get_Receiver.25672.body { return receiver; } // ino.end // ino.method.get_Name.25675.definition public String get_Name() // ino.end // ino.method.get_Name.25675.body { return this.usedid.name.firstElement(); } // ino.end public void set_Name(String name){ this.usedid = new UsedId(name, 0); } // ino.method.sc_check.25678.definition public void sc_check(Vector classname, Hashtable ch, Hashtable bh, boolean ext, Hashtable parach, Hashtable parabh) throws SCStatementException // ino.end // ino.method.sc_check.25678.body { if(ext) parserlog.debug(" --- MethodCall ---"); parserlog.debug("ch: "+ch.toString()); SCStatementException except=null; // 1. Vector expr wird nun durchgegangen, um die Typen der �bergabewerte zu erhalten parserlog.debug(" ---- 1. Vector expr wird nun durchgegangen, um die Typen der �bergabewerte zu erhalten ---- "); if(arglist!=null) { for(Enumeration el2 = arglist.expr.elements(); el2.hasMoreElements();) { Expr e=(Expr)el2.nextElement(); try { e.sc_check(classname,ch,bh,ext, parach, parabh); } catch(SCStatementException ex) { if(except==null) except=ex; else { Vector v; SCExcept hilf; v=ex.get_exlist(); for(Enumeration el=v.elements();el.hasMoreElements();) { hilf=el.nextElement(); except.addException(hilf); } } } if(except!=null) throw except; if(ext) parserlog.debug("Es wird in den Vector exprtypes ein Element eingefuegt vom Typ: "+e.getTypeName()); exprtypes.addElement(e.getTypeName()); } } // 2. �berpr�fung des Methodennamens parserlog.debug(" ---- 2. �berpr�fung des Methodennamens ---- "); Vector name = usedid.get_Name(); Vector typen = new Vector(); Class klasse = null; //Klasse wird auf null gesetzt um zuerst in der aktuellen Klasse zu checken Hashtable parahilf=null; for(Enumeration el = name.elements(); el.hasMoreElements();) { String name1 = (String) el.nextElement(); Class hilfe; String hilfstr=null; if(name1.equals("System")) { if(ext) parserlog.debug("Semantikcheck wird an CODEGEN weitergeleitet."); typen.addElement("System"); break; } if(klasse!=null) //hier geht's rein, wenn eine Instanzvariable gefunden wurde { if(!el.hasMoreElements()) //es folgen keine weiteren Strings mehr -> name1 muss der Methoden-Name sein. { if(ext) inferencelog.debug("Checke Methode " + name1 + " in Klasse " + this.getType().getName()); this.setType(new Type(klasse.is_member(name1),getOffset())); if(this.getType()==null) { if(ext) parserlog.debug("Methode "+name1+" nicht gefunden.sc_check-->MethodCall.sc_check()"); SCExcept exc =new SCExcept(); exc.set_error("Methode " + name1 + " in Klasse " + klasse.getName() + " nicht gefunden!"); exc.set_statement("MethodCall"); SCStatementException ex = new SCStatementException(); ex.addException(exc); throw ex; } else { if(ext) parserlog.debug("Methode "+name1+" gefunden."); class_name=klasse.getName(); // System.out.println("typen: "+typen.toString()+" type: "+ type+" parach: "+parach.toString()+" parabh: "+parabh.toString()); if(parahilf != null){ if(parahilf.containsKey(name1)) this.setType((Type)parahilf.get(name1)); } parserlog.debug("typen: "+typen.toString()+", (ret.)type: "+ this.getType().getName()+", parach: "); parserlog.debug(string_rec(parach)); parserlog.debug(", parabh: "); parserlog.debug(string_rec(parabh)); parserlog.debug("name1 "+name1 +" hilfstr "+hilfstr); typen.addElement(this.getType().getName()); } sc_check_get_Method(classname,name1,ext,parach,parabh); } else //es folgen Strings -> weitere Klassen m�ssen auf die Methode �berpr�ft werden { if(ext) parserlog.debug("Checke Variable "+name1+"in Klasse "+this.getType().getName()+"."); this.setType(new Type(klasse.is_member(name1),getOffset())); if(this.getType()==null) { if(ext) parserlog.debug("Variable "+name1+" nicht gefunden.sc_check-->MethodCall.sc_check()"); SCExcept exc=new SCExcept(); exc.set_error("Variable "+name1+" wurde in Klasse "+klasse.getName()+" nicht gefunden."); exc.set_statement("MethodCall"); SCStatementException ex = new SCStatementException(); ex.addException(exc); throw ex; } else { parserlog.debug(this.getType().getName()+" ******** 1"); typen.addElement(this.getType().getName()); if(ext) parserlog.debug("Variable "+name1+" gefunden."); } for(Enumeration el1 = classname.elements();el1.hasMoreElements();) { hilfe=el1.nextElement(); hilfstr=hilfe.getName(); if(this.getType().equals(hilfstr)) klasse = hilfe; } } } else if(!el.hasMoreElements()) //es steht nur der Methoden-Aufruf im Vector name, { //also MUSS die Methode in dieser Klasse deklariert sein if(ch.containsKey(name1)) { this.setType(new Type((String)ch.get(name1),getOffset())); if(ext) parserlog.debug("Methode " + name1 + " in Class gefunden vom Typ: " + this.getType().getName()); class_name=(String)ch.get("###_classname"); typen.addElement(this.getType().getName()); try { sc_check_get_Method(classname,name1, ext,parach,parabh); //hier geht's weiter!!! } catch(SCStatementException ex) { throw ex; } } else { if(ext) parserlog.error("Methode "+name1+" nicht in Class gefunden.sc_check-->MethodCall.sc_check()"); SCExcept exc= new SCExcept(); exc.set_error("Methode "+name1+" nicht gefunden."); exc.set_statement("MethodCall"); SCStatementException ex=new SCStatementException(); ex.addException(exc); throw ex; } } else if(bh.containsKey(name1)) //es folgen Strings im Vector, also handelt es sich um eine Instanzvar. { //wir m�ssen im Blockhash nach der zugeh�rigen Klasse suchen. this.setType(new Type((String)bh.get(name1),getOffset())); //Attribut "type" von Basisklasse Expr if(ext) parserlog.debug("Variable " + name1 + " im Block gefunden."); for(Enumeration el1 = classname.elements();el1.hasMoreElements();) { hilfe = el1.nextElement(); hilfstr = hilfe.getName(); if(this.getType().getName().equals(hilfstr)) klasse = hilfe; } if(parabh.containsKey(name1)) parahilf =(Hashtable) parabh.get(name1); typen.addElement(this.getType().getName()); parserlog.debug(this.getType().getName()+" ******** 2 parahilf:"); parserlog.debug(string_rec(parahilf)); } else if(ch.containsKey(name1)) //im Blockhash wurde der String nicht gefunden, also { //m�ssen wir im Classhash nach der zugeh�rigen Klasse suchen. this.setType(new Type((String)ch.get(name1),getOffset())); //Attribut "type" von Basisklasse Expr if(ext) parserlog.debug("Variable " + name1 + " im ClassBody gefunden."); for(Enumeration el1 = classname.elements();el1.hasMoreElements();) { hilfe = el1.nextElement(); hilfstr = hilfe.getName(); if(this.getType().getName().equals(hilfstr)) klasse = hilfe; } if(parach.containsKey(name1)) parahilf =(Hashtable) parach.get(name1); typen.addElement(this.getType().getName()); parserlog.debug(this.getType().getName()+" ******** 3 parahilf:"); parserlog.debug(string_rec(parahilf)); } else { if(ext) parserlog.debug("Methoden-Aufruf "+name1+" nicht gefunden.sc_check-->MethodCall.sc_check()"); SCExcept exc = new SCExcept(); exc.set_error(name1+ " weder in Blockhash noch in Classhash gefunden."); exc.set_statement("MethodCall"); SCStatementException ex = new SCStatementException(); ex.addException(exc); throw ex; } } usedid.set_Typen(typen); // 3. Ueberpruefung, welche Methode den/die richtigen �bergabeparmeter hat // findet in der Funktion void sc_check_get_Method() statt } // ino.end // ino.method.sc_check_get_Method.25681.definition public void sc_check_get_Method(Vector classlist, String methodname, boolean ext,Hashtable parach, Hashtable parabh) throws SCStatementException // ino.end // ino.method.sc_check_get_Method.25681.body { Class hilf; String hilfclassname; ClassBody hilfbody; Vector varundmeth; Object typecheck; Vector method=new Vector(); Method moeglich; String vergleich; String classname; int no_of_exprtypes; Vector paralist; no_of_exprtypes=exprtypes.size(); //Hier wird die Anzahl der �bergabeparameter festgestellt if(ext) parserlog.debug("Semantik-Check ist in sc_check_get_Method: Die Methode hat "+no_of_exprtypes+" �bergabewerte."); for(Enumeration el=classlist.elements();el.hasMoreElements();) //wir suchen alle Methoden mit dem gleichen { //Namen, wie die aufgerufene Methode, die in der Klasse vorkommen hilf=el.nextElement(); hilfclassname=hilf.getName(); if(hilfclassname.equals(class_name)) { hilfbody=hilf.get_ClassBody(); varundmeth=hilfbody.get_FieldDeclVector(); for(Enumeration el1=varundmeth.elements();el1.hasMoreElements();) { typecheck=el1.nextElement(); if(typecheck instanceof Method) { moeglich=(Method)typecheck; vergleich=moeglich.get_Method_Name(); if(vergleich.equals(methodname)) { paralist=moeglich.get_Type_Paralist(); if(ext) parserlog.error("Es wurde eine Methode mit dem gleichen Namen gefunden. Sie hat "+paralist.size()+" �bergabewerte"); if(paralist.size()==no_of_exprtypes)//Es werden nur noch Methoden hier hinzugefuegt, die die richtige Parameteranzahl { //haben. last1 07.03.02 method.addElement(moeglich); } } } } if(hilf.does_Class_extend()) //hat die Klasse geerbt suchen wir in der Basisklasse nach weiteren { //Methoden mit dem selben Namen classname=hilf.get_Superclass_Name(); sc_init_extended_fcts(method,classlist,methodname,classname,ext); } } } //Jetzt befinden sich im Vector method alle Funktionen mit dem richtigen Namen und der richtigen Anzahl an Parametern!, die //m�glich sind => Wir koennen also die �bergabewerte pruefen for(int i=0;exprtypes.size()>i;i++) //l�uft so ab: F�r jeden �bergabeparameter wird die Funktion { //sc_check_uebergabe aufgerufen try { sc_check_uebergabe(classlist,method,ext,i,parach, parabh); } catch(SCStatementException ex) { throw ex; } finde_method.addElement(uebernachdurch); if (ext) parserlog.debug("Wir sind dabei, die Hashtables in den Vector zu schreiben."); } //jetzt muss noch die passende Methode rausgefischt werden Hashtable zumueberpruefen; String intnummern; Method passt; int indexnr=0; boolean best=false; int vererbschritte=0; int zaehlen=0; Vector aussuchen=new Vector(); for(int j=0;exprtypes.size()>j;j++) { if(ext) parserlog.debug("Hashtable Nr. "+j+" wird gecheckt."); zumueberpruefen=finde_method.elementAt(j); //wir benutzen dazu die in sc_check_uebergabe for(int k=0;k<10;k++) //erstellten Hashtables, ist die Schl�ssel-Nr. { //m�glichst klein, ist die Methode in der Hash- intnummern=String.valueOf(k); //table die bestpassende. if(j==0) { if(zumueberpruefen.containsKey(intnummern)) { if(ext) parserlog.debug("Methode wird in den Moeglichkeits-Vector aufgenommen!"); aussuchen.addElement(zumueberpruefen.get(intnummern)); if(best==false) { best=true; vererbschritte=k; } } } else { if(zumueberpruefen.containsKey(intnummern)) { passt=zumueberpruefen.get(intnummern); aussuchen.indexOf(passt); if(indexnr!=zaehlen&&k classlist,Vector method,boolean ext,int paranum, Hashtable parach, Hashtable parabh) throws SCStatementException // ino.end // ino.method.sc_check_uebergabe.25684.body { Vector parameterlist; String soll,ist; boolean found=false; Class hilfscl; Method moeglich; //String geerbt; String intnummern; uebernachdurch=new Hashtable(); if(ext) parserlog.debug("Semantik-Check pr�ft "+paranum+". �bergabewert."); int vectorlaenge=method.size(); for(int zaehl=0;zaehl e = classlist.elements();e.hasMoreElements();){ hilfscl = e.nextElement(); if(hilfscl.getName().equals(this.class_name)){ if(hilfscl.get_ParaHash().containsValue(soll)){ soll=ist; } } } /******/ if(ist.equals(soll)) //hier wird untersucht, ob die �bergabetypen passen { found=true; intnummern="0"; uebernachdurch.put(intnummern,moeglich); //passen sie sofort -> Eintragung der Methode in Hashtable if(ext) //unter Schl�ssel "0" parserlog.debug("Semantik-Check hat "+paranum+". �bergabewert vom Typ "+ist+" gefunden."); } else { if(ist.equals("String")||ist.equals("int")||ist.equals("char")||ist.equals("boolean")) { //ist der Typ String, int, char oder boolean passt die Methode im Normalfall nicht found=false; if(ist.equals("char")) { if(soll.equals("int")) { parserlog.info("ACHTUNG! Hier wird einem int ein char zugewiesen!"); parserlog.info("Methode: "+usedid.get_Name().toString()); found=true; } } } else // bei anderem Typ muss auf Vererbung �berpr�ft werden { if(ext) parserlog.debug("Semantik-Check hat noch nichts gefunden. �bergabewert vom Typ "+ist+" k�nnte vererbt sein."); counter=0; found=sc_check_method_kleiner(classlist,ist,soll,ext);//hier wird auf Vererbung gepr�ft if(found) { intnummern=String.valueOf(counter); //Counter gibt an wieviele Schritte bis zur richtigen uebernachdurch.put(intnummern,moeglich); //Klasse durchgef�hrt wurden -> Counter ist if(ext) //der Schl�ssel zur m�glichen Methode parserlog.debug("Semantik-Check hat Uebergabewert vom Typ "+ist+" vererbt gefunden nach "+counter+" Durchl�ufen."); } } } if(!found) { if(ext) parserlog.debug("Nicht passende Funktion gefunden, wird vom Vector gel�scht."); method.remove(moeglich); //Die m�gliche Methode wird gel�scht, wenn die Parameter nicht passen. } if(vectorlaenge!=method.size()) { vectorlaenge=method.size(); zaehl=-1; } } if(method.isEmpty()) { SCExcept ex=new SCExcept(); ex.set_error("Keine passende Funktion gefunden!"); ex.set_statement("Method - Call"); SCStatementException exce=new SCStatementException(); exce.addException(ex); throw exce; } } // ino.end // ino.method.sc_check_method_kleiner.25687.definition public boolean sc_check_method_kleiner(Vector classlist,String ist,String soll,boolean ext) // ino.end // ino.method.sc_check_method_kleiner.25687.body { Class hilf; String geerbtvon; String hilfmir; boolean erg=false; counter++; for(Enumeration el1=classlist.elements();el1.hasMoreElements();) { hilf=el1.nextElement(); hilfmir=hilf.getName(); if(hilfmir.equals(ist)) { if(ext) parserlog.debug("Habe Klasse gefunden "+hilfmir); geerbtvon=hilf.get_Superclass_Name(); if(ext) parserlog.debug("Aktuell geerbtvon: "+geerbtvon); if(geerbtvon!=null) { if(geerbtvon.equals(soll)) { if(ext) parserlog.debug("Kleiner gefunden. Klassenname "+geerbtvon); erg=true; break; } else { erg=sc_check_method_kleiner(classlist,geerbtvon,soll,ext); break; } } else erg=false; } else erg=false; } return erg; } // ino.end // ino.method.sc_init_extended_fcts.25690.definition public void sc_init_extended_fcts(Vector method, Vector classlist, String methodname, String classname, boolean ext) // ino.end // ino.method.sc_init_extended_fcts.25690.body { //hier werden die Funktionen mit dem gleichen Namen, die von einer anderen Klasse geerbt wurden in den Class hilf; //Vektor der m�glichen Methoden mitaufgenommen. String hilfclassname; ClassBody hilfbody; Vector varundmeth; Object typecheck; Method moeglich; String vergleich; for(Enumeration el=classlist.elements();el.hasMoreElements();) { hilf=el.nextElement(); hilfclassname=hilf.getName(); if(hilfclassname.equals(classname)) { hilfbody=hilf.get_ClassBody(); varundmeth=hilfbody.get_FieldDeclVector(); for(Enumeration el1=varundmeth.elements();el1.hasMoreElements();) { typecheck=el1.nextElement(); if(typecheck instanceof Method) { moeglich=(Method)typecheck; vergleich=moeglich.get_Method_Name(); if(vergleich.equals(methodname)) method.addElement(moeglich); } } if(hilf.does_Class_extend()) { classname=hilf.get_Superclass_Name(); sc_init_extended_fcts(method,classlist,methodname,classname,ext); } } } } // ino.end // ino.method.set_Receiver.25693.definition public void set_Receiver(Receiver rec) // ino.end // ino.method.set_Receiver.25693.body { receiver=rec; } // ino.end // ino.method.set_UsedId.25696.definition public void set_UsedId(UsedId u) // ino.end // ino.method.set_UsedId.25696.body { usedid=u; } // ino.end // ino.method.set_Expr_Vector.25699.definition public void set_Expr_Vector(Vector v) // ino.end // ino.method.set_Expr_Vector.25699.body { arglist.expr=v; } // ino.end // ino.method.add_Expr.25702.definition public void add_Expr(Expr e) // ino.end // ino.method.add_Expr.25702.body { arglist.expr.addElement(e); } // ino.end // ino.method.getMethodFittingMethodCallAndClassname.25705.defdescription type=javadoc /** * hoti 4.5.06 * Diese Methode lädt die Methodeninfos einer Methode aus der Hashtable * methodsfittingmethodcall in ein Method-Objekt * anhand der angegeben klasse * @see methodsFittingMethodCall * @param className * @return * @throws JVMCodeException */ // ino.end // ino.method.getMethodFittingMethodCallAndClassname.25705.definition public Method getMethodFittingMethodCallAndClassname(String className) throws JVMCodeException // ino.end // ino.method.getMethodFittingMethodCallAndClassname.25705.body { CMethodTypeAssumption assumption=methodsFittingMethodCall.get(className); if(assumption==null){ throw new JVMCodeException("Codegen: Fuer die Klasse "+className+" wurde die Methode "+usedid.get_Name_1Element()+" nicht gefunden"); } Vector paraAssumptions=assumption.getParaAssumptions(); Type returnType=assumption.getAssumedType(); Method meth=new Method(); Vector parameterVector=new Vector(); ParameterList pl=new ParameterList(); for(int i=0;i nichterkannte) kann kein Methodenaufruf ausgeführt werden // Es muss sich also um einen RefType handeln. Ansonsten gibt es einen Fehler if(!(receiver.get_Expr().getTypeVariable() instanceof RefType)){ throw new JVMCodeException("Es kann nur auf ein RefType ein Methodenaufruf ausgeführt werden ("+receiver+"["+receiver.get_Expr().getTypeVariable()+"])"); } // HOTI 4.5.06 // Es handelt sich also um einen RefType. Der Klassenname wird nun bezogen String receiverClassName=((RefType)receiver.get_Expr().getTypeVariable()).getTypeName(); // Die richtige Methode wird gesucht und gesetzt called_method=getMethodFittingMethodCallAndClassname(receiverClassName); Vector name_vector = get_Name_Vector(); String local_name = receiver.get_Expr().get_Name(); // Richtiges Objekt auf den Stack legen int index = code.get_indexOf_Var(local_name); if (index != -1 ) { // Lokale Variable try { String local_type = code.get_TypeOf_Var(local_name) .getName(); code.add_code(JVMCode.nload_n(local_type, index)); } catch (JVMCodeException e) { // out of nload_n String local_type = code.get_TypeOf_Var(local_name) .getName(); code.add_code(JVMCode.nload(local_type)); code.add_code_byte((byte) index); } } else { // FieldVariable code.add_code(JVMCode.aload_0); code.add_code(JVMCode.getfield); code.add_code_short(classfile.add_field_ref(local_name, class_name, JVMCode.get_codegen_Type(receiver.get_Type(), null))); } String called_method_name = called_method.get_Method_Name(); if (called_method_name == null) called_method_name = (String) name_vector.lastElement(); // feda 04.07.07 an dieser Stelle muss geschaut werden ob // die Methode eine Static Methode ist. // Wenn Static dann aload_0 weg und anstellen von // code.add_code(JVMCode.invokevirtual); muss // code.add_code(JVMCode.invokestatic); stehen. if (arglist != null) arglist.codegen(classfile, code, paralist); code.add_code(JVMCode.invokevirtual); code.add_code_short(classfile.add_method_ref(receiverClassName, called_method_name, called_method .get_codegen_Param_Type(paralist))); } // ino.end // ino.method.TRStatement.25711.defdescription type=javadoc /** * Implementierung des Algorithmus 5.27 von Martin Pl�micke
* Author: J�rg B�uerle * * @param sigma * @param V * @param supportData * @return */ // ino.end // ino.method.TRStatement.25711.definition public CTripleSet TRStatement(CSubstitutionSet sigma, CTypeAssumptionSet V, CSupportData supportData) // ino.end // ino.method.TRStatement.25711.body { CTripleSet resultSet = this.TRExp(sigma, V, supportData); Iterator it = resultSet.getIterator(); while(it.hasNext()){ ((CTriple)it.next()).setResultType(new Void(getOffset())); } return resultSet; } // ino.end // ino.method.makeReceiver.25714.definition private void makeReceiver() // ino.end // ino.method.makeReceiver.25714.body { usedid.get_Name().remove(usedid.get_Name().size()-1); //Methodenname loeschen Iterator namen = usedid.get_Name().iterator(); LocalOrFieldVar LOFV = new LocalOrFieldVar((String)namen.next(),getOffset()); LOFV.setType(TypePlaceholder.fresh(this)); receiver = new Receiver(LOFV); while(namen.hasNext()) { InstVar INSTVA = new InstVar(receiver.get_Expr(), (String)namen.next(),getOffset()); INSTVA.setType(TypePlaceholder.fresh(this)); receiver = new Receiver(INSTVA); } } // ino.end // ino.method.TRExp.25717.defdescription type=javadoc /** * Implementierung des Algorithmus 5.33 von Martin Pl�micke *
Author: J�rg B�uerle * @param sigma * @param V * @param supportData * @return */ // ino.end // ino.method.TRExp.25717.definition public CTripleSet TRExp(CSubstitutionSet sigma, CTypeAssumptionSet V, CSupportData supportData) // ino.end // ino.method.TRExp.25717.body { CTripleSet resultSet = new CTripleSet(); //String identifierName = (String)this.usedid.get_Name().elementAt(this.usedid.get_Name().size()-2); String identifierName = (String)this.usedid.get_Name().elementAt(0); String functionName = (String)this.usedid.get_Name().elementAt(this.usedid.get_Name().size()-1); if (receiver == null) { // PL 05-08-21 wenn im Parser nicht primary geparst wurde // also Aufruf von Objektkette oder Packagekette (nicht impl.) if (this.usedid.get_Name().size() > 1) { makeReceiver(); // macht aus der Liste von Strings in usedid.name einen receiver } else { receiver = new Receiver(new This (getOffset(),getVariableLength())); } } //called_method = functionName; MUSS NOCH GESETZT WERDEN, WENN KLAR IST WELCHEN TYP DIE PARAMETER HABEN Vector expressions = new Vector(); expressions.addElement(this.receiver.get_Expr()); if(this.arglist!=null){ expressions.addAll(this.arglist.expr); } // -------------------------- // TRTuple rufen: // -------------------------- CMultiplyTupleSet tupleSet = this.TRTuple(new CMultiplyTuple(sigma, new Vector(), V), expressions, supportData); Iterator tupleIt = tupleSet.getIterator(); int successfulls=0; Vector exceptions=new Vector(); while(tupleIt.hasNext()){ CMultiplyTuple tuple = tupleIt.next(); int paraCount = 0; if(this.arglist!=null){ paraCount = this.arglist.expr.size(); } try{ CTripleSet callAppSet = TRMCallApp(tuple, identifierName, functionName, paraCount, false, supportData); resultSet.unite(callAppSet); successfulls++; }catch(CTypeReconstructionException exception){ exceptions.addElement(exception); } } if(successfulls==0){ if(exceptions.size()>0){ throw exceptions.elementAt(0); } throw new CTypeReconstructionException("MethodCall: Es konnte keine Assumption gefunden werden, die auf die Anforderung passt.",exceptions,this); } CTripleSet resultSet2 = super.registerType(resultSet, supportData); return resultSet2; //ALLE VARIANTEN MethodCall TESTEN UsecaseOne_pl.jav TUT SO NICHT } // ino.end // ino.method.TRMCallApp.25720.defdescription type=javadoc /** * Implementierung des Algorithmus 5.34 von Martin Pl�micke * @param multiTuple * @param classOrIdentifierName * @param methodName * @param paraCount * @param isConstructorCall * @param supportData * @return */ // ino.end // ino.method.TRMCallApp.25720.definition public CTripleSet TRMCallApp(CMultiplyTuple multiTuple, String classOrIdentifierName, String methodName, int paraCount, boolean isConstructorCall, CSupportData supportData) // ino.end // ino.method.TRMCallApp.25720.body { // ########################## // 1. Alle bisherigen Typkombinationen durchgehen: // ########################## CTripleSet case1 = new CTripleSet(); for(int i=0; ihandleMethodAssum().
Author: J�rg B�uerle * @param multiTuple * @param possibleTypeComb * @param returnSet * @param className * @param methodName * @param paraCount * @param supportData * @param methodsFittingMethodCall Hashtable in der jede erfolgreiche Methode * abgelegt wird @return Einen Error-Code: OK, * UNIFY_ERROR oder METHOD_NOT_FOUND_ERROR */ // ino.end // ino.method.searchAndHandleMethod.25723.definition private int searchAndHandleMethod(CMultiplyTuple multiTuple, CTypeReconstructionResult possibleTypeComb, CTripleSet returnSet, String className, String methodName, int paraCount, CSupportData supportData, Hashtable methodsFittingMethodCall) // ino.end // ino.method.searchAndHandleMethod.25723.body { // -------------------------- // Typannahme f�r Methode heraussuchen: // -------------------------- CMethodKey key = new CMethodKey( className, methodName, paraCount ); Vector intersects = possibleTypeComb.getMethodIntersectionTypes(key); if(intersects.size()==0){ return METHOD_NOT_FOUND_ERROR; } int wellUnifiedMethodCount=0; // Alle Methoden durchgehen, die gefunden wurden for(int item=0;item genericClassParameters = possibleTypeComb.getGenerics(className); // Generics der Methode holen // p.ex. E test(){...} // ___________________ Vector genericMethodParameters=methodAssum.getGenericMethodParameters(); // Classtype initialisieren // Wird fuer die Unifizierung benoetigt RefType classType; // Wird spaeter fuer die Codegen benoetigt RefType classTypeWithRealParameters; // Klassenparameter berechnen // => aus p.ex. Vector wird Vector Vector unifyTypePara = new Vector(); if (genericClassParameters != null && genericClassParameters.size()>0) { CSubstitutionSet sub = new CSubstitutionSet(); for( int i = 0; i < genericClassParameters.size(); i++ ) { TypePlaceholder tlv = TypePlaceholder.fresh(this); unifyTypePara.addElement(tlv); sub.addElement(new CSubstitutionGenVar(genericClassParameters.elementAt(i), tlv)); } methodAssum.sub(sub); classType=new RefType(className,unifyTypePara,getOffset()); classTypeWithRealParameters=new RefType(className,possibleTypeComb.getGenerics(className),getOffset()); }else{ classType=new RefType(className,getOffset()); classTypeWithRealParameters=new RefType(className,getOffset()); } // Konstruktoren haben (inoffiziell) den Return-Typ des Objektes if(methodAssum.getIdentifier().equals("")){ methodAssum.setAssumedType(classType); } // Generische Methodenparameter hinzufuegen Vector additionalPairsToUnify=new Vector(); if (genericMethodParameters != null && genericMethodParameters.size()>0) { CSubstitutionSet sub = new CSubstitutionSet(); for( int i = 0; i < genericMethodParameters.size(); i++ ){ if(genericMethodParameters.elementAt(i) instanceof BoundedGenericTypeVar){ // Jede Bound als Paar zum Unifizieren vormerken TypePlaceholder newTLV=TypePlaceholder.fresh(this); BoundedGenericTypeVar bgtv=(BoundedGenericTypeVar)genericMethodParameters.elementAt(i); for(int j=0;j // Output: Alle Klassen <= Vector ... ohne Parameter RefType cloneRT=classToAdd.clone(); CSubstitutionSet sub=cloneRT.GenericTypeVar2TypePlaceholder(); sub.applyThisSubstitutionSet(cloneRT); Vector vec=sub.getVector(); for(int i=0;i> test=Unify.instanceSmaller(pair,fctto); for(int j=0;jhandleMethodAssum().
Author: J�rg B�uerle * @param multiTuple * @param possibleTypeComb * @param returnSet * @param className * @param methodName * @param paraCount * @param methodsFittingMethodCall Hashtable in der jede erfolgreiche Methode * abgelegt wird @param supportData * @return Einen Error-Code: OK, UNIFY_ERROR oder * METHOD_NOT_FOUND_ERROR */ // ino.end // ino.method.searchAndHandleMethod.25729.definition private int searchAndHandleMethod(CMultiplyTuple multiTuple, CTypeAssumptionSet V, CTripleSet returnSet, RefType classType, String methodName, int paraCount, CSupportData supportData, Hashtable methodsFittingMethodCall) // ino.end // ino.method.searchAndHandleMethod.25729.body { // -------------------------- // Typannahme f�r Methode heraussuchen: // -------------------------- String className; if(classType instanceof RefType){ className=((RefType)classType).getTypeName(); }else{ className=classType.getName(); } CMethodKey key = new CMethodKey( className, methodName, paraCount ); Vector methodAssums = V.getElements(key); // Wenn die Methode nicht fuendig war: if(methodAssums.size()==0){ return METHOD_NOT_FOUND_ERROR; } // Fuendig: Alle Methoden, die "xxx" heißen und y Parameter haben sind nun in dem Vector drin // Für alle soll jetzt geschaut werden int wellDoneFunctionCount=0; for(int item=0;item typeGenPara = supportData.getCurrentClassPara(); // Generics der Methode holen // p.ex. E test(){...} // ___________________ Vector genericMethodParameters=methodAssum.getGenericMethodParameters(); // Klassengenerics verarbeiten Vector typePara = null; if (typeGenPara != null) { typePara = new Vector(); for( int i = 0; i < typeGenPara.size(); i++ ) { typePara.addElement(typeGenPara.elementAt(i)); } } // Methodengenerics verarbeiten Vector additionalPairsToUnify=new Vector(); if (genericMethodParameters != null && genericMethodParameters.size()>0) { CSubstitutionSet sub = new CSubstitutionSet(); for( int i = 0; i < genericMethodParameters.size(); i++ ){ if(genericMethodParameters.elementAt(i) instanceof BoundedGenericTypeVar){ // Jede Bound als Paar zum Unifizieren vormerken TypePlaceholder newTLV=TypePlaceholder.fresh(this); BoundedGenericTypeVar bgtv=(BoundedGenericTypeVar)genericMethodParameters.elementAt(i); for(int j=0;jAuthor: J�rg B�uerle * @param multiTuple * @param returnSet * @param methodAssum * @param className * @param supportData * @param additionalPairsToUnify * @return Einen Error-Code: OK, UNIFY_ERROR oder * METHOD_NOT_FOUND_ERROR */ // ino.end // ino.method.handleMethodAssum.25732.definition private static int handleMethodAssum(CMultiplyTuple multiTuple, Vector typePara, CTripleSet returnSet, CMethodTypeAssumption methodAssum, Type classType, CSupportData supportData, Vector additionalPairsToUnify) // ino.end // ino.method.handleMethodAssum.25732.body { // -------------------------- // Typen unifizieren: // -------------------------- // Vorerst Paare zum Unifizieren bilden Vector pairsToUnify = createPairsToUnify(multiTuple, typePara, classType, methodAssum); // Vorgemerkte Paare if(pairsToUnify!=null && additionalPairsToUnify!=null) pairsToUnify.addAll(additionalPairsToUnify); // Die Paare endlich unifizieren Vector> unifierPossibilities = Unify.unify(pairsToUnify, supportData.getFiniteClosure()); // -------------------------- // Wenn Unifier vorhanden, dann anwenden: // -------------------------- if(unifierPossibilities.size()!=0){ // -------------------------- // Subset bauen: // -------------------------- CTripleSet subSet = new CTripleSet(); // -------------------------- // Alle Unifer durchgehen: // -------------------------- for(int j=0; jAuthor: J�rg B�uerle * @param multiTuple * @param receiverClass * @param methodAssum * @return */ // ino.end // ino.method.createPairsToUnify.25735.definition private static Vector createPairsToUnify(CMultiplyTuple multiTuple, Vector typePara, Type receiverClass, CMethodTypeAssumption methodAssum) // ino.end // ino.method.createPairsToUnify.25735.body { Vector pairList = new Vector(); Pair p = new Pair(multiTuple.getResultTypes().firstElement(), receiverClass); pairList.addElement(p); for(int i=1; iAuthor: Martin Pl�micke * @return */ // ino.end // ino.method.toString.25738.definition public String toString() // ino.end // ino.method.toString.25738.body { //return receiver/*.toString()*/ + " " + usedid.toString(); return type + " (" + this.get_Receiver() + "." + this.get_Name() +"(" + this.getArgumentList() + "))"; } // ino.end // ino.method.wandleRefTypeAttributes2GenericAttributes.25741.definition public void wandleRefTypeAttributes2GenericAttributes(Vector paralist, Vector genericMethodParameters) // ino.end // ino.method.wandleRefTypeAttributes2GenericAttributes.25741.body { } // ino.end public void addOffsetsToExpression(CTypeAssumption localAssumption,String NameVariable,boolean isMemberVariable) { if(this.get_Receiver()!=null) { this.get_Receiver().get_Expr().addOffsetsToExpression(localAssumption,NameVariable,isMemberVariable); } if(this.getArgumentList()!=null){ for(Expr n : this.getArgumentList().expr) { n.addOffsetsToExpression(localAssumption,NameVariable,isMemberVariable); }} } /** * @author Andreas Stadelmeier, a10023 * @return der Name der Methode, welcher dieser MethodCall aufruft. */ public String getName(){ return this.usedid.toString(); } /** * @author AI10023 - Andreas Stadelmeier * * Mögliche Probleme: * Wenn die Methode ohne Angabe eines Receivers im Quelltext steht: * methodCall(param); -> (bedeutet:) this.methodCall(param); * Der Parser macht hier aber komische Faxen (siehe JavaParser.jay Zeile 1858 ff) */ @Override public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) { //TODO hier muss unterschieden werden zwischen einem Konstruktor und einer Methode. //Hier der Ablauf für einen Methodenaufruf: ConstraintsSet ret = new ConstraintsSet(); //Der Return-Type des MEthodenaufrufs ist zunächst unbekannt: this.setTypeVariable(TypePlaceholder.fresh(this)); //Berechne die Constraints des Receivers if(receiver == null){ receiver = new Receiver(new This(0,0)); } ret.add(receiver.get_Expr().TYPEExpr(assumptions)); //Berechne die Constraints der Argumente aus der Argumentlist (also der Parameter, welche der Funktion übergeben wurden) if(this.arglist != null)for(Expr arg : this.arglist.expr){ ret.add(arg.TYPEExpr(assumptions)); } //Noch das Overloading-Constraint anhängen: ret.add(new Overloading(assumptions, this, this.getTypeVariable()).generateConsstraints()); return ret; } /** * Spezifikation: * TYPEStmt( Ass, stmt ) = * let (stmt : rty, ConS) = TYPEExpr( Ass, stmt ) * in (stmt : Void, ConS) */ @Override public ConstraintsSet TYPEStmt(TypeAssumptions assumptions){ ConstraintsSet ret = this.TYPEExpr(assumptions); //TypeExpr aufrufen this.setTypeVariable(new Void(0)); //Typ des Statments auf Void setzen, da als alleinstehendes Statement return ret; } @Override public JavaCodeResult printJavaCode(ResultSet resultSet) { JavaCodeResult ret = new JavaCodeResult(); if(this.receiver != null)ret.attach( this.receiver.printJavaCode(resultSet)).attach("."); ret .attach( this.get_Name()); ret .attach( "(" ).attach( this.getArgumentList().printJavaCode(resultSet)).attach( ")"); return ret.attach(";"); } } // ino.end