forked from JavaTX/JavaCompilerCore
1548 lines
63 KiB
Java
1548 lines
63 KiB
Java
|
// 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
|