2013-10-18 13:33:46 +02: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;
|
2014-02-09 16:07:31 +01:00
|
|
|
|
|
2014-02-22 04:58:49 +01:00
|
|
|
|
import mycompiler.SyntaxTreeNode;
|
2013-10-18 13:33:46 +02:00
|
|
|
|
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;
|
2014-02-09 16:07:31 +01:00
|
|
|
|
import mycompiler.mytypereconstruction.TypeinferenceResultSet;
|
2013-10-18 13:33:46 +02:00
|
|
|
|
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;
|
2014-02-09 16:07:31 +01:00
|
|
|
|
|
2013-10-18 13:33:46 +02:00
|
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
|
// ino.end
|
|
|
|
|
|
2014-02-09 16:07:31 +01:00
|
|
|
|
|
2014-02-22 04:58:49 +01:00
|
|
|
|
|
2013-10-18 13:33:46 +02:00
|
|
|
|
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
|
|
|
|
|
import typinferenz.ConstraintsSet;
|
|
|
|
|
import typinferenz.FreshTypeVariable;
|
|
|
|
|
import typinferenz.JavaCodeResult;
|
|
|
|
|
import typinferenz.Overloading;
|
|
|
|
|
import typinferenz.ResultSet;
|
2014-02-09 16:07:31 +01:00
|
|
|
|
import typinferenz.assumptions.TypeAssumptions;
|
2013-10-18 13:33:46 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
2014-02-22 04:58:49 +01:00
|
|
|
|
private ArgumentList arglist=new ArgumentList();
|
2013-10-18 13:33:46 +02:00
|
|
|
|
// 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
|
2014-02-22 04:58:49 +01:00
|
|
|
|
|
2013-10-18 13:33:46 +02:00
|
|
|
|
// 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.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();
|
2014-03-09 14:12:48 +01:00
|
|
|
|
Method meth=new Method(0);
|
2013-10-18 13:33:46 +02:00
|
|
|
|
Vector<FormalParameter> parameterVector=new Vector<FormalParameter>();
|
|
|
|
|
ParameterList pl=new ParameterList();
|
|
|
|
|
for(int i=0;i<paraAssumptions.size();i++){
|
|
|
|
|
CParaTypeAssumption paraassumtion=paraAssumptions.elementAt(i);
|
2014-03-27 16:43:07 +01:00
|
|
|
|
FormalParameter fp=new FormalParameter(new DeclId());
|
2013-10-18 13:33:46 +02:00
|
|
|
|
fp.setType(paraassumtion.getAssumedType());
|
|
|
|
|
parameterVector.addElement(fp);
|
|
|
|
|
}
|
|
|
|
|
pl.formalparameter=parameterVector;
|
2014-02-19 23:04:48 +01:00
|
|
|
|
meth.setType(returnType);
|
2013-10-18 13:33:46 +02:00
|
|
|
|
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
|
|
|
|
|
|
2014-02-11 16:30:38 +01:00
|
|
|
|
if(!(receiver.get_Expr().getType() instanceof RefType)){
|
|
|
|
|
throw new JVMCodeException("Es kann nur auf ein RefType ein Methodenaufruf ausgeführt werden ("+receiver+"["+receiver.get_Expr().getType()+"])");
|
2013-10-18 13:33:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// HOTI 4.5.06
|
|
|
|
|
// Es handelt sich also um einen RefType. Der Klassenname wird nun bezogen
|
2014-02-11 16:30:38 +01:00
|
|
|
|
String receiverClassName=((RefType)receiver.get_Expr().getType()).getTypeName();
|
2013-10-18 13:33:46 +02:00
|
|
|
|
|
|
|
|
|
// Die richtige Methode wird gesucht und gesetzt
|
2014-02-22 04:58:49 +01:00
|
|
|
|
Method called_method=getMethodFittingMethodCallAndClassname(receiverClassName);
|
2013-10-18 13:33:46 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2014-02-09 16:07:31 +01:00
|
|
|
|
|
2013-10-18 13:33:46 +02:00
|
|
|
|
|
|
|
|
|
// 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.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) {
|
|
|
|
|
//Hier der Ablauf f<>r einen Methodenaufruf:
|
|
|
|
|
ConstraintsSet ret = new ConstraintsSet();
|
|
|
|
|
//Der Return-Type des MEthodenaufrufs ist zun<75>chst unbekannt:
|
2014-02-11 16:30:38 +01:00
|
|
|
|
this.setType(TypePlaceholder.fresh(this));
|
2013-10-18 13:33:46 +02:00
|
|
|
|
//Berechne die Constraints des Receivers
|
|
|
|
|
if(receiver == null){
|
2014-04-24 01:53:35 +02:00
|
|
|
|
receiver = new Receiver(new This(this));
|
2013-10-18 13:33:46 +02:00
|
|
|
|
}
|
|
|
|
|
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:
|
2014-02-11 16:30:38 +01:00
|
|
|
|
ret.add(new Overloading(assumptions, this, this.getType()).generateConsstraints());
|
2013-10-18 13:33:46 +02:00
|
|
|
|
|
|
|
|
|
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
|
2014-02-11 16:30:38 +01:00
|
|
|
|
this.setType(new Void(0)); //Typ des Statments auf Void setzen, da als alleinstehendes Statement
|
2013-10-18 13:33:46 +02:00
|
|
|
|
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(";");
|
|
|
|
|
|
|
|
|
|
}
|
2014-02-22 04:58:49 +01:00
|
|
|
|
@Override
|
|
|
|
|
public Vector<SyntaxTreeNode> getChildren() {
|
|
|
|
|
Vector<SyntaxTreeNode> ret = new Vector<SyntaxTreeNode>();
|
|
|
|
|
for(Expr e : this.arglist.expr){
|
|
|
|
|
ret.add(e);
|
|
|
|
|
}
|
|
|
|
|
if(this.receiver!=null)ret.add(this.receiver.get_Expr());
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void parserPostProcessing(SyntaxTreeNode parent) {
|
|
|
|
|
super.parserPostProcessing(parent);
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-18 13:33:46 +02:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
// ino.end
|