JavaPatternMatching/src/mycompiler/mystatement/MethodCall.java

1548 lines
63 KiB
Java
Raw Normal View History

2013-10-18 11:33:46 +00:00
// 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<String> exprtypes=new Vector<String>(); //hier werden die Typen der <20>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<String,Method> uebernachdurch;
// ino.end
// ino.attribute.finde_method.25654.declaration
private Vector<Hashtable<String,Method>> finde_method=new Vector<Hashtable<String,Method>>();
// 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<EFBFBD>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<String, CMethodTypeAssumption> methodsFittingMethodCall=new Hashtable<String,CMethodTypeAssumption>();
// 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<Class> classname, Hashtable ch, Hashtable<String, String> bh, boolean ext, Hashtable parach, Hashtable<String, 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 <20>bergabewerte zu erhalten
parserlog.debug(" ---- 1. Vector expr wird nun durchgegangen, um die Typen der <20>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<SCExcept> v;
SCExcept hilf;
v=ex.get_exlist();
for(Enumeration<SCExcept> 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. <20>berpr<70>fung des Methodennamens
parserlog.debug(" ---- 2. <20>berpr<70>fung des Methodennamens ---- ");
Vector name = usedid.get_Name();
Vector<String> typen = new Vector<String>();
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 <20>berpr<70>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<Class> 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<65>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<Class> 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<65>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<Class> 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 <20>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<Class> 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> method=new Vector<Method>();
Method moeglich;
String vergleich;
String classname;
int no_of_exprtypes;
Vector paralist;
no_of_exprtypes=exprtypes.size(); //Hier wird die Anzahl der <20>bergabeparameter festgestellt
if(ext)
parserlog.debug("Semantik-Check ist in sc_check_get_Method: Die Methode hat "+no_of_exprtypes+" <20>bergabewerte.");
for(Enumeration<Class> 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()+" <20>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 <20>bergabewerte pruefen
for(int i=0;exprtypes.size()>i;i++) //l<>uft so ab: F<>r jeden <20>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<String,Method> zumueberpruefen;
String intnummern;
Method passt;
int indexnr=0;
boolean best=false;
int vererbschritte=0;
int zaehlen=0;
Vector<Method> aussuchen=new Vector<Method>();
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<68>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<vererbschritte)
{
// Method hilfmirhier;
// hilfmirhier=(Method)method.elementAt(zaehlen);
aussuchen.remove(zaehlen);
//method.addElement(hilfmirhier);
zaehlen++;
}
}
}
}
}
if(arglist!=null)
called_method=aussuchen.elementAt(zaehlen);
else
called_method=method.elementAt(0);
Vector testerichtig;
testerichtig=called_method.get_Type_Paralist();
if(ext)
{
parserlog.debug("Semantik-Check hat die aufgerufene Methode mit folgenden <20>bergabewerten gefunden: "+testerichtig.toString()); //Zur Ueberpruefung werden bei eingeschaltetem ext die Typen der gefundenen Methode ausgegeben.
}
}
// ino.end
// ino.method.sc_check_uebergabe.25684.definition
public void sc_check_uebergabe(Vector<Class> classlist,Vector<Method> 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<String,Method>();
if(ext)
parserlog.debug("Semantik-Check pr<70>ft "+paranum+". <20>bergabewert.");
int vectorlaenge=method.size();
for(int zaehl=0;zaehl<vectorlaenge;zaehl++)
{
moeglich=method.elementAt(zaehl);
parameterlist=moeglich.get_Type_Paralist();
soll=(String)parameterlist.elementAt(paranum);
ist=(String)exprtypes.elementAt(paranum);
/******
parserlog.debug(string_rec(parach));parserlog.debug(string_rec(parabh));
System.out.println(parameterlist.toString());
System.out.println("soll: "+soll);*/
for(Enumeration<Class> 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 <20>bergabetypen passen
{
found=true;
intnummern="0";
uebernachdurch.put(intnummern,moeglich); //passen sie sofort -> Eintragung der Methode in Hashtable
if(ext) //unter Schl<68>ssel "0"
parserlog.debug("Semantik-Check hat "+paranum+". <20>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 <20>berpr<70>ft werden
{
if(ext)
parserlog.debug("Semantik-Check hat noch nichts gefunden. <20>bergabewert vom Typ "+ist+" k<>nnte vererbt sein.");
counter=0;
found=sc_check_method_kleiner(classlist,ist,soll,ext);//hier wird auf Vererbung gepr<70>ft
if(found)
{
intnummern=String.valueOf(counter); //Counter gibt an wieviele Schritte bis zur richtigen
uebernachdurch.put(intnummern,moeglich); //Klasse durchgef<65>hrt wurden -> Counter ist
if(ext) //der Schl<68>ssel zur m<>glichen Methode
parserlog.debug("Semantik-Check hat Uebergabewert vom Typ "+ist+" vererbt gefunden nach "+counter+" Durchl<68>ufen.");
}
}
}
if(!found)
{
if(ext)
parserlog.debug("Nicht passende Funktion gefunden, wird vom Vector gel<65>scht.");
method.remove(moeglich); //Die m<>gliche Methode wird gel<65>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<Class> 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<Class> 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> method, Vector<Class> 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<Class> 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<Expr> 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<EFBFBD>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<CParaTypeAssumption> paraAssumptions=assumption.getParaAssumptions();
Type returnType=assumption.getAssumedType();
Method meth=new Method();
Vector<FormalParameter> parameterVector=new Vector<FormalParameter>();
ParameterList pl=new ParameterList();
for(int i=0;i<paraAssumptions.size();i++){
CParaTypeAssumption paraassumtion=paraAssumptions.elementAt(i);
FormalParameter fp=new FormalParameter();
fp.setType(paraassumtion.getAssumedType());
parameterVector.addElement(fp);
}
pl.formalparameter=parameterVector;
meth.setReturnType(returnType);
meth.setParameterList(pl);
meth.set_DeclId(new DeclId(assumption.getIdentifier()));
return(meth);
}
// ino.end
// ino.method.codegen.25708.definition
public void codegen(ClassFile classfile, CodeAttribute code, Vector paralist)
throws JVMCodeException
// ino.end
// ino.method.codegen.25708.body
{
// HOTI 4.5.06
// Auf eine TypePlaceholders-Variable (=> 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<EFBFBD>micke <br>
* Author: J<EFBFBD>rg B<EFBFBD>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<EFBFBD>micke
* <br/>Author: J<EFBFBD>rg B<EFBFBD>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<Expr> expressions = new Vector<Expr>();
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<Type>(), V), expressions, supportData);
Iterator<CMultiplyTuple> tupleIt = tupleSet.getIterator();
int successfulls=0;
Vector<CTypeReconstructionException> exceptions=new Vector<CTypeReconstructionException>();
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<EFBFBD>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; i<supportData.getA().size(); i++){
CTypeReconstructionResult possibleComb = supportData.getA().elementAt(i);
// --------------------------
// Bei Konstruktor Klasse bereits bekannt:
// --------------------------
if(isConstructorCall){
searchAndHandleMethod(multiTuple, possibleComb, case1, classOrIdentifierName, methodName, paraCount, supportData,methodsFittingMethodCall);
//searchAndHandleMethod(multiTuple, possibleComb, case1, classOrIdentifierName, classOrIdentifierName, paraCount, supportData,methodsFittingMethodCall);
}
// --------------------------
// Bei normaler Methode alle Klassen durchsuchen:
// --------------------------
else{
for(int j=0; j<possibleComb.getClassNameList().size(); j++){
String clName = possibleComb.getClassNameList().elementAt(j); // ReceiverName
searchAndHandleMethod(multiTuple, possibleComb, case1, clName, methodName, paraCount, supportData,methodsFittingMethodCall);
}
}
}
// ##########################
// 2. Aktuelle Klasse durchsuchen:
// ##########################
CTripleSet case2 = new CTripleSet();
searchAndHandleMethod(multiTuple, multiTuple.getAssumptionSet(), case2, supportData.getCurrentClassType(), methodName, paraCount, supportData,methodsFittingMethodCall);
// ##########################
// 3. Ergebnismengen vereinigen:
// ##########################
case1.unite(case2);
CTripleSet returnSet = case1;
if(returnSet.getCardinality()==0){
throw new CTypeReconstructionException("MethodCall.TRMCallApp(): Die Methode "+methodName+" konnte mit keiner bekannten Methode unifiziert werden.",this);
}
return returnSet;
}
// ino.end
// ino.method.searchAndHandleMethod.25723.defdescription type=javadoc
/**
* Sucht eine Methode aus einem IntersectionType heraus und ruft
* <code>handleMethodAssum()</code>. <br/>Author: J<EFBFBD>rg B<EFBFBD>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: <code>OK</code>,
* <code>UNIFY_ERROR</code> oder <code>METHOD_NOT_FOUND_ERROR</code>
*/
// 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<String,CMethodTypeAssumption> methodsFittingMethodCall)
// ino.end
// ino.method.searchAndHandleMethod.25723.body
{
// --------------------------
// Typannahme f<>r Methode heraussuchen:
// --------------------------
CMethodKey key = new CMethodKey(
className,
methodName,
paraCount
);
Vector<CIntersectionType> 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<intersects.size();item++){
CIntersectionType intersect=intersects.get(item);
// Annahme holen
CMethodTypeAssumption methodAssum = intersect.getMethodTypeAssumptions().firstElement().clone();
// Annahme clonen, um sie nachher f<>r die Codegenerierung zu setzen
// (Codegenerierung ben<65>tigt die Orginalsignatur)
CMethodTypeAssumption methodAssumCopy = intersect.getMethodTypeAssumptions().firstElement().clone();
// Generics der Klasse holen
Vector<GenericTypeVar> genericClassParameters = possibleTypeComb.getGenerics(className);
// Generics der Methode holen
// p.ex. <E extends Integer> E test(){...}
// ___________________
Vector<GenericTypeVar> 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<E> wird Vector<NEUE_TypePlaceholder-VARIABLE>
Vector<Type> unifyTypePara = new Vector<Type>();
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("<init>")){
methodAssum.setAssumedType(classType);
}
// Generische Methodenparameter hinzufuegen
Vector<Pair> additionalPairsToUnify=new Vector<Pair>();
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<bgtv.getBounds().size();j++){
Type bound=bgtv.getBounds().elementAt(j);
Pair newPairToAdd=new Pair(newTLV,bound);
additionalPairsToUnify.addElement(newPairToAdd);
sub.addElement(new CSubstitutionGenVar(bgtv, newTLV));
}
}else{ // Normale GenericTypeVar
TypePlaceholder newTLV=TypePlaceholder.fresh(this);
sub.addElement(new CSubstitutionGenVar(genericMethodParameters.elementAt(i), newTLV));
}
}
methodAssum.sub(sub);
}
// Versuch, die Methode zu unifizieren
int result=handleMethodAssum(multiTuple, unifyTypePara, returnSet, methodAssum, classType, supportData, additionalPairsToUnify);
if(result==OK){
// Gefundene Methode in
addMethodAndSuperclassMethodsToFittings(classTypeWithRealParameters, methodAssumCopy,supportData.getFiniteClosure());
wellUnifiedMethodCount++;
}
}
if(wellUnifiedMethodCount==1){
return OK;
}else{
return UNIFY_ERROR;
}
}
// ino.end
// ino.method.addMethodAndSuperclassMethodsToFittings.25726.defdescription type=javadoc
/**
* HOTI 4.5.06-15.5.06
* F<EFBFBD>gt diese Klasse mit deren Typannahme in den Vektor ein.
* Da aber auch die Subklassen alle die Methodenproperties haben
* k<EFBFBD>nnen m<EFBFBD>ssen die mit rein...
* @param classToAdd
* @param methodAssumCopy
* @param fc
*/
// ino.end
// ino.method.addMethodAndSuperclassMethodsToFittings.25726.definition
private void addMethodAndSuperclassMethodsToFittings(RefType classToAdd, CMethodTypeAssumption methodAssumCopy, FC_TTO fctto)
// ino.end
// ino.method.addMethodAndSuperclassMethodsToFittings.25726.body
{
methodsFittingMethodCall.put(classToAdd.getTypeName(),methodAssumCopy);
// Input: Klasse Vector<E>
// Output: Alle Klassen <= Vector<E> ... ohne Parameter
RefType cloneRT=classToAdd.clone();
CSubstitutionSet sub=cloneRT.GenericTypeVar2TypePlaceholder();
sub.applyThisSubstitutionSet(cloneRT);
Vector<CSubstitution> vec=sub.getVector();
for(int i=0;i<vec.size();i++){
Pair pair=new Pair(vec.elementAt(i).getType(),cloneRT);
Vector<Vector<Pair>> test=Unify.instanceSmaller(pair,fctto);
for(int j=0;j<test.size();j++){
for(int k=0;k<test.elementAt(j).size();k++){
Pair foundSubclassPair=test.elementAt(j).elementAt(k);
Type foundSubclass=foundSubclassPair.getTA2Copy();
if(foundSubclass instanceof RefType){
RefType elem=(RefType)foundSubclass;
CMethodTypeAssumption clone=methodAssumCopy.clone();
clone.setClassName(elem.getTypeName());
methodsFittingMethodCall.put(elem.getTypeName(),clone);
}
}
}
}
}
// ino.end
// ino.method.searchAndHandleMethod.25729.defdescription type=javadoc
/**
* Sucht eine Methode aus einer Menge von Typannahmen heraus und ruft
* <code>handleMethodAssum()</code>. <br/>Author: J<EFBFBD>rg B<EFBFBD>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: <code>OK</code>, <code>UNIFY_ERROR</code> oder
* <code>METHOD_NOT_FOUND_ERROR</code>
*/
// 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<String,CMethodTypeAssumption> 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<CTypeAssumption> 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<65>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<methodAssums.size();item++){
CTypeAssumption methodAssumObj=methodAssums.get(item);
if(methodAssumObj instanceof CMethodTypeAssumption){
CMethodTypeAssumption methodAssum=(CMethodTypeAssumption)methodAssumObj;
CMethodTypeAssumption methodAssumCopy=(CMethodTypeAssumption)methodAssumObj.clone();
Vector<GenericTypeVar> typeGenPara = supportData.getCurrentClassPara();
// Generics der Methode holen
// p.ex. <E extends Integer> E test(){...}
// ___________________
Vector<GenericTypeVar> genericMethodParameters=methodAssum.getGenericMethodParameters();
// Klassengenerics verarbeiten
Vector<Type> typePara = null;
if (typeGenPara != null) {
typePara = new Vector<Type>();
for( int i = 0; i < typeGenPara.size(); i++ )
{
typePara.addElement(typeGenPara.elementAt(i));
}
}
// Methodengenerics verarbeiten
Vector<Pair> additionalPairsToUnify=new Vector<Pair>();
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<bgtv.getBounds().size();j++){
Type bound=bgtv.getBounds().elementAt(j);
Pair newPairToAdd=new Pair(newTLV,bound);
additionalPairsToUnify.addElement(newPairToAdd);
sub.addElement(new CSubstitutionGenVar(bgtv, newTLV));
}
}else{ // Normale GenericTypeVar
TypePlaceholder newTLV=TypePlaceholder.fresh(this);
sub.addElement(new CSubstitutionGenVar(genericMethodParameters.elementAt(i), newTLV));
}
}
methodAssum.sub(sub);
}
int returnValue=handleMethodAssum(multiTuple, typePara, returnSet, methodAssum, classType, supportData, additionalPairsToUnify);
if(returnValue==OK){
if(methodAssum instanceof CMethodTypeAssumption){
addMethodAndSuperclassMethodsToFittings(classType, methodAssumCopy,supportData.getFiniteClosure());
}
wellDoneFunctionCount++;
}
}
}
return (wellDoneFunctionCount==1)?OK:UNIFY_ERROR;
}
// ino.end
// ino.method.handleMethodAssum.25732.defdescription type=javadoc
/**
* Unifiziert die in Alg. 5.34 angegeben Typen von Methodenargumenten und
* Receivern. <br/>Author: J<EFBFBD>rg B<EFBFBD>uerle
* @param multiTuple
* @param returnSet
* @param methodAssum
* @param className
* @param supportData
* @param additionalPairsToUnify
* @return Einen Error-Code: <code>OK</code>, <code>UNIFY_ERROR</code> oder
* <code>METHOD_NOT_FOUND_ERROR</code>
*/
// ino.end
// ino.method.handleMethodAssum.25732.definition
private static int handleMethodAssum(CMultiplyTuple multiTuple, Vector<Type> typePara, CTripleSet returnSet, CMethodTypeAssumption methodAssum, Type classType, CSupportData supportData, Vector<Pair> additionalPairsToUnify)
// ino.end
// ino.method.handleMethodAssum.25732.body
{
// --------------------------
// Typen unifizieren:
// --------------------------
// Vorerst Paare zum Unifizieren bilden
Vector<Pair> pairsToUnify = createPairsToUnify(multiTuple, typePara, classType, methodAssum);
// Vorgemerkte Paare
if(pairsToUnify!=null && additionalPairsToUnify!=null)
pairsToUnify.addAll(additionalPairsToUnify);
// Die Paare endlich unifizieren
Vector<Vector<Pair>> 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; j<unifierPossibilities.size(); j++){
CSubstitutionSet unifier = new CSubstitutionSet(unifierPossibilities.elementAt(j));
// --------------------------
// Ergebnis-Triple bauen:
// --------------------------
CTriple subTriple = new CTriple();
subTriple.setAssumptionSet(multiTuple.getAssumptionSet());
subTriple.setSubstitutions(multiTuple.getSubstitutions());
subTriple.setResultType(methodAssum.getAssumedType());
// --------------------------
// Unifier anwenden:
// --------------------------
subTriple = subTriple.cloneAndApplyUnify(unifier);
if(!subSet.contains(subTriple)){
subSet.addElement(subTriple);
}
}
returnSet.unite(subSet);
return OK;
}
return UNIFY_ERROR;
}
// ino.end
// ino.method.createPairsToUnify.25735.defdescription type=javadoc
/**
* Baut die in Algorithmus 5.34 angegeben Liste von zu unifizierenden Typen auf.
* <br/>Author: J<EFBFBD>rg B<EFBFBD>uerle
* @param multiTuple
* @param receiverClass
* @param methodAssum
* @return
*/
// ino.end
// ino.method.createPairsToUnify.25735.definition
private static Vector<Pair> createPairsToUnify(CMultiplyTuple multiTuple, Vector<Type> typePara, Type receiverClass, CMethodTypeAssumption methodAssum)
// ino.end
// ino.method.createPairsToUnify.25735.body
{
Vector<Pair> pairList = new Vector<Pair>();
Pair p = new Pair(multiTuple.getResultTypes().firstElement(), receiverClass);
pairList.addElement(p);
for(int i=1; i<multiTuple.getResultTypes().size(); i++){
Type nu = multiTuple.getResultTypes().elementAt(i);
Type theta = methodAssum.getParaAssumption(i-1).getAssumedType();
// HOTI 04-22-06 Hier war einst ein BackDoorFresh, welches das obige
// theta ersetzt hat und dem Theta die neuen TypePlaceholder zugewiesen
// hat. Dies war in unseren (Martin, Joerg, Ich) Augen falsch, deshalb
// haben wir es raus gemacht. Es wird naemlich schon in
// searchandhandlemethod ein TypePlaceholder erzeugt, hier waere es
// sonst "doppelt gemoppelt" gewesen, was nat<61>rlich weitere Probleme
// verursachte ....
p = new Pair(nu, theta);
pairList.addElement(p);
}
return pairList;
}
// ino.end
// ino.method.toString.25738.defdescription type=javadoc
/**
* <br/>Author: Martin Pl<EFBFBD>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<Type> paralist, Vector<GenericTypeVar> 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<EFBFBD>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<75>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 <20>bergeben wurden)
if(this.arglist != null)for(Expr arg : this.arglist.expr){
ret.add(arg.TYPEExpr(assumptions));
}
//Noch das Overloading-Constraint anh<6E>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