forked from JavaTX/JavaCompilerCore
730 lines
28 KiB
Java
Executable File
730 lines
28 KiB
Java
Executable File
// 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.SyntaxTreeNode;
|
||
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.TypeinferenceResultSet;
|
||
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.assumptions.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=new ArgumentList();
|
||
// 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.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<65>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<>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.setType(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().getType() instanceof RefType)){
|
||
throw new JVMCodeException("Es kann nur auf ein RefType ein Methodenaufruf ausgeführt werden ("+receiver+"["+receiver.get_Expr().getType()+"])");
|
||
}
|
||
|
||
// HOTI 4.5.06
|
||
// Es handelt sich also um einen RefType. Der Klassenname wird nun bezogen
|
||
String receiverClassName=((RefType)receiver.get_Expr().getType()).getTypeName();
|
||
|
||
// Die richtige Methode wird gesucht und gesetzt
|
||
Method 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.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<>gt diese Klasse mit deren Typannahme in den Vektor ein.
|
||
* Da aber auch die Subklassen alle die Methodenproperties haben
|
||
* k<>nnen m<>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<>rg B<>uerle
|
||
* @param multiTuple
|
||
* @param possibleTypeComb
|
||
* @param returnSet
|
||
* @param className
|
||
* @param methodName
|
||
* @param paraCount
|
||
* @param methodsFittingMethodCall Hashtable in der jede erfolgreiche Methode
|
||
* abgelegt wird @param supportData
|
||
* @return Einen Error-Code: <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<>rg B<>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<>rg B<>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<50>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<>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.setType(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.getType()).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.setType(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(";");
|
||
|
||
}
|
||
@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);
|
||
}
|
||
|
||
|
||
}
|
||
// ino.end
|