// ino.module.MethodCall.8639.package package de.dhbwstuttgart.syntaxtree.statement; // 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.myexception.CTypeReconstructionException; import mycompiler.myexception.JVMCodeException; import mycompiler.myexception.SCExcept; import mycompiler.myexception.SCStatementException; 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.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 de.dhbwstuttgart.core.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.ClassBody; import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.misc.DeclId; import de.dhbwstuttgart.syntaxtree.misc.UsedId; import de.dhbwstuttgart.syntaxtree.type.BoundedGenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.Pair; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.typeinference.ConstraintsSet; import de.dhbwstuttgart.typeinference.FreshTypeVariable; import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.Overloading; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import sun.reflect.generics.reflectiveObjects.NotImplementedException; // 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 exprtypes=new Vector(); //hier werden die Typen der �bergabewerten von sc_check eingetragen. // ino.attribute.class_name.25645.declaration private String class_name; //hier steht in welcher Klasse die Methode deklariert ist. // ino.end // ino.attribute.uebernachdurch.25651.declaration private Hashtable uebernachdurch; // ino.end // ino.attribute.finde_method.25654.declaration private Vector> finde_method=new Vector>(); // ino.end // ino.attribute.counter.25657.declaration private int counter; // ino.end // ino.attribute.methodsFittingMethodCall.25660.decldescription type=javadoc /** * Da der SemanticCheck nicht mehr ausgeführt wird, werden hier die bei der * Typrekonstruktion gefundenen Methoden abgespeichert. Problem ist hier jedoch, * dass der receiver in diesem Moment noch nicht fest steht. Deshalb wird je * Receiver ein Methodcall abgelegt. Dieser kann dann mit bspw. * methodsFittingMethodCAll.get("Vector") abgerufen werden. */ // ino.end // ino.attribute.methodsFittingMethodCall.25660.declaration private Hashtable methodsFittingMethodCall=new Hashtable(); // ino.end // ino.attribute.parserlog.25663.declaration protected static Logger parserlog = Logger.getLogger("parser"); // ino.end // ino.method.set_ArgumentList.25666.definition public void set_ArgumentList(ArgumentList al) // ino.end // ino.method.set_ArgumentList.25666.body { this.arglist = al; } // ino.end // ino.method.getArgumentList.25669.definition public ArgumentList getArgumentList() // ino.end // ino.method.getArgumentList.25669.body { if(this.arglist==null)return this.arglist = new ArgumentList(); return this.arglist; } // ino.end // ino.method.get_Receiver.25672.definition public Receiver get_Receiver() // ino.end // ino.method.get_Receiver.25672.body { return receiver; } // ino.end // ino.method.get_Name.25675.definition public String get_Name() // ino.end // ino.method.get_Name.25675.body { return this.usedid.name.firstElement(); } // ino.end public void set_Name(String name){ this.usedid = new UsedId(name, 0); } // ino.method.set_Receiver.25693.definition public void set_Receiver(Receiver rec) // ino.end // ino.method.set_Receiver.25693.body { receiver=rec; } // ino.end // ino.method.set_UsedId.25696.definition public void set_UsedId(UsedId u) // ino.end // ino.method.set_UsedId.25696.body { usedid=u; } // ino.end // ino.method.set_Expr_Vector.25699.definition public void set_Expr_Vector(Vector v) // ino.end // ino.method.set_Expr_Vector.25699.body { arglist.expr=v; } // ino.end // ino.method.add_Expr.25702.definition public void add_Expr(Expr e) // ino.end // ino.method.add_Expr.25702.body { arglist.expr.addElement(e); } // ino.end // ino.method.getMethodFittingMethodCallAndClassname.25705.defdescription type=javadoc /** * hoti 4.5.06 * Diese Methode lädt die Methodeninfos einer Methode aus der Hashtable * methodsfittingmethodcall in ein Method-Objekt * anhand der angegeben klasse * @see methodsFittingMethodCall * @param className * @return * @throws JVMCodeException */ // ino.end // ino.method.getMethodFittingMethodCallAndClassname.25705.definition public Method getMethodFittingMethodCallAndClassname(String className) throws JVMCodeException // ino.end // ino.method.getMethodFittingMethodCallAndClassname.25705.body { CMethodTypeAssumption assumption=methodsFittingMethodCall.get(className); if(assumption==null){ throw new JVMCodeException("Codegen: Fuer die Klasse "+className+" wurde die Methode "+usedid.get_Name_1Element()+" nicht gefunden"); } Vector paraAssumptions=assumption.getParaAssumptions(); Type returnType=assumption.getAssumedType(); Method meth=new Method(0); Vector parameterVector=new Vector(); ParameterList pl=new ParameterList(); for(int i=0;i nichterkannte) kann kein Methodenaufruf ausgeführt werden // Es muss sich also um einen RefType handeln. Ansonsten gibt es einen Fehler if(!(receiver.get_Expr().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 // Output: Alle Klassen <= Vector ... ohne Parameter RefType cloneRT=classToAdd.clone(); CSubstitutionSet sub=cloneRT.GenericTypeVar2TypePlaceholder(); sub.applyThisSubstitutionSet(cloneRT); Vector vec=sub.getVector(); for(int i=0;i> test=Unify.instanceSmaller(pair,fctto); for(int j=0;jhandleMethodAssum().
Author: J�rg B�uerle * @param multiTuple * @param possibleTypeComb * @param returnSet * @param className * @param methodName * @param paraCount * @param methodsFittingMethodCall Hashtable in der jede erfolgreiche Methode * abgelegt wird @param supportData * @return Einen Error-Code: OK, UNIFY_ERROR oder * METHOD_NOT_FOUND_ERROR */ // ino.end // ino.method.searchAndHandleMethod.25729.definition private int searchAndHandleMethod(CMultiplyTuple multiTuple, CTypeAssumptionSet V, CTripleSet returnSet, RefType classType, String methodName, int paraCount, CSupportData supportData, Hashtable methodsFittingMethodCall) // ino.end // ino.method.searchAndHandleMethod.25729.body { // -------------------------- // Typannahme f�r Methode heraussuchen: // -------------------------- String className; if(classType instanceof RefType){ className=((RefType)classType).getTypeName(); }else{ className=classType.getName(); } CMethodKey key = new CMethodKey( className, methodName, paraCount ); Vector methodAssums = V.getElements(key); // Wenn die Methode nicht fuendig war: if(methodAssums.size()==0){ return METHOD_NOT_FOUND_ERROR; } // Fuendig: Alle Methoden, die "xxx" heißen und y Parameter haben sind nun in dem Vector drin // Für alle soll jetzt geschaut werden int wellDoneFunctionCount=0; for(int item=0;item typeGenPara = supportData.getCurrentClassPara(); // Generics der Methode holen // p.ex. E test(){...} // ___________________ Vector genericMethodParameters=methodAssum.getGenericMethodParameters(); // Klassengenerics verarbeiten Vector typePara = null; if (typeGenPara != null) { typePara = new Vector(); for( int i = 0; i < typeGenPara.size(); i++ ) { typePara.addElement(typeGenPara.elementAt(i)); } } // Methodengenerics verarbeiten Vector additionalPairsToUnify=new Vector(); if (genericMethodParameters != null && genericMethodParameters.size()>0) { CSubstitutionSet sub = new CSubstitutionSet(); for( int i = 0; i < genericMethodParameters.size(); i++ ){ if(genericMethodParameters.elementAt(i) instanceof BoundedGenericTypeVar){ // Jede Bound als Paar zum Unifizieren vormerken TypePlaceholder newTLV=TypePlaceholder.fresh(this); BoundedGenericTypeVar bgtv=(BoundedGenericTypeVar)genericMethodParameters.elementAt(i); for(int j=0;jAuthor: J�rg B�uerle * @param multiTuple * @param returnSet * @param methodAssum * @param className * @param supportData * @param additionalPairsToUnify * @return Einen Error-Code: OK, UNIFY_ERROR oder * METHOD_NOT_FOUND_ERROR */ // ino.end // ino.method.handleMethodAssum.25732.definition private static int handleMethodAssum(CMultiplyTuple multiTuple, Vector typePara, CTripleSet returnSet, CMethodTypeAssumption methodAssum, Type classType, CSupportData supportData, Vector additionalPairsToUnify) // ino.end // ino.method.handleMethodAssum.25732.body { // -------------------------- // Typen unifizieren: // -------------------------- // Vorerst Paare zum Unifizieren bilden Vector pairsToUnify = createPairsToUnify(multiTuple, typePara, classType, methodAssum); // Vorgemerkte Paare if(pairsToUnify!=null && additionalPairsToUnify!=null) pairsToUnify.addAll(additionalPairsToUnify); // Die Paare endlich unifizieren Vector> unifierPossibilities = Unify.unify(pairsToUnify, supportData.getFiniteClosure()); // -------------------------- // Wenn Unifier vorhanden, dann anwenden: // -------------------------- if(unifierPossibilities.size()!=0){ // -------------------------- // Subset bauen: // -------------------------- CTripleSet subSet = new CTripleSet(); // -------------------------- // Alle Unifer durchgehen: // -------------------------- for(int j=0; jAuthor: J�rg B�uerle * @param multiTuple * @param receiverClass * @param methodAssum * @return */ // ino.end // ino.method.createPairsToUnify.25735.definition private static Vector createPairsToUnify(CMultiplyTuple multiTuple, Vector typePara, Type receiverClass, CMethodTypeAssumption methodAssum) // ino.end // ino.method.createPairsToUnify.25735.body { Vector pairList = new Vector(); Pair p = new Pair(multiTuple.getResultTypes().firstElement(), receiverClass); pairList.addElement(p); for(int i=1; iAuthor: Martin Pl�micke * @return */ // ino.end // ino.method.toString.25738.definition public String toString() // ino.end // ino.method.toString.25738.body { //return receiver/*.toString()*/ + " " + usedid.toString(); return type + " (" + this.get_Receiver() + "." + this.get_Name() +"(" + this.getArgumentList() + "))"; } // ino.end // ino.method.wandleRefTypeAttributes2GenericAttributes.25741.definition public void wandleRefTypeAttributes2GenericAttributes(Vector paralist, Vector genericMethodParameters) // ino.end // ino.method.wandleRefTypeAttributes2GenericAttributes.25741.body { } // ino.end public void addOffsetsToExpression(CTypeAssumption localAssumption,String NameVariable,boolean isMemberVariable) { if(this.get_Receiver()!=null) { this.get_Receiver().get_Expr().addOffsetsToExpression(localAssumption,NameVariable,isMemberVariable); } if(this.getArgumentList()!=null){ for(Expr n : this.getArgumentList().expr) { n.addOffsetsToExpression(localAssumption,NameVariable,isMemberVariable); }} } /** * @author Andreas Stadelmeier, a10023 * @return der Name der Methode, welcher dieser MethodCall aufruft. */ public String getName(){ return this.usedid.toString(); } /** * @author AI10023 - Andreas Stadelmeier * * Mögliche Probleme: * Wenn die Methode ohne Angabe eines Receivers im Quelltext steht: * methodCall(param); -> (bedeutet:) this.methodCall(param); * Der Parser macht hier aber komische Faxen (siehe JavaParser.jay Zeile 1858 ff) */ @Override public ConstraintsSet TYPEExpr(TypeAssumptions assumptions) { //Hier der Ablauf für einen Methodenaufruf: ConstraintsSet ret = new ConstraintsSet(); //Der Return-Type des MEthodenaufrufs ist zunächst unbekannt: this.setType(TypePlaceholder.fresh(this)); //Berechne die Constraints des Receivers if(receiver == null){ receiver = new Receiver(new This(this)); } ret.add(receiver.get_Expr().TYPEExpr(assumptions)); //Berechne die Constraints der Argumente aus der Argumentlist (also der Parameter, welche der Funktion übergeben wurden) if(this.arglist != null)for(Expr arg : this.arglist.expr){ ret.add(arg.TYPEExpr(assumptions)); } //Noch das Overloading-Constraint anhängen: ret.add(new Overloading(assumptions, this, this.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 getChildren() { Vector ret = new Vector(); 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