// ino.module.Class.8553.package package mycompiler.myclass; // ino.end // ino.module.Class.8553.import import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import mycompiler.AClassOrInterface; import mycompiler.mybytecode.ClassFile; import mycompiler.myexception.CTypeReconstructionException; import mycompiler.myexception.JVMCodeException; import mycompiler.myexception.SCClassBodyException; import mycompiler.myexception.SCClassException; import mycompiler.myexception.SCExcept; import mycompiler.mymodifier.Modifiers; import mycompiler.mystatement.*; import mycompiler.mytype.GenericTypeVar; import mycompiler.mytype.Pair; import mycompiler.mytype.RefType; import mycompiler.mytype.SuperWildcardType; import mycompiler.mytype.Type; import mycompiler.mytype.TypePlaceholder; import mycompiler.mytype.WildcardType; import mycompiler.mytypereconstruction.CReconstructionTuple; import mycompiler.mytypereconstruction.CSubstitution; import mycompiler.mytypereconstruction.CSupportData; import mycompiler.mytypereconstruction.CTriple; import mycompiler.mytypereconstruction.TypeinferenceResultSet; import mycompiler.mytypereconstruction.replacementlistener.CReplaceTypeEvent; import mycompiler.mytypereconstruction.set.CReconstructionTupleSet; import mycompiler.mytypereconstruction.set.CSubstitutionSet; import mycompiler.mytypereconstruction.set.CTripleSet; import mycompiler.mytypereconstruction.set.CTypeAssumptionSet; import mycompiler.mytypereconstruction.set.IHashSetKey; import mycompiler.mytypereconstruction.typeassumption.CInstVarTypeAssumption; import mycompiler.mytypereconstruction.typeassumption.CLocalVarTypeAssumption; import mycompiler.mytypereconstruction.typeassumption.CMethodTypeAssumption; import mycompiler.mytypereconstruction.typeassumption.CParaTypeAssumption; import mycompiler.mytypereconstruction.typeassumption.CTypeAssumption; import mycompiler.mytypereconstruction.typeassumptionkey.CMethodKey; import mycompiler.mytypereconstruction.unify.Unify; import mycompiler.SourceFile; import org.apache.log4j.Logger; // ino.end import sun.reflect.generics.reflectiveObjects.NotImplementedException; import typinferenz.ConstraintsSet; import typinferenz.JavaCodeResult; import typinferenz.OderConstraint; import typinferenz.ResultSet; import typinferenz.TypinferenzException; import typinferenz.UndConstraint; import typinferenz.FunN; import typinferenz.assumptions.TypeAssumptions; // ino.class.Class.23010.declaration public class Class extends AClassOrInterface // ino.end // ino.class.Class.23010.body { // ino.attribute.superclassid.23014.decldescription type=line // private Status status; // ino.end // ino.attribute.superclassid.23014.declaration public UsedId superclassid = (SourceFile.READ_OBJECT_SUPERCLASSES_FROM_JRE?UsedId.createFromQualifiedName("Object",-1):null); // ino.end // ino.attribute.body.23017.declaration private ClassBody body; // ino.end // ino.attribute.class_block.23020.decldescription type=line // private Class java; // ino.end // ino.attribute.class_block.23020.declaration private Block class_block; // ino.end // ino.attribute.paralist.23023.declaration private Vector paralist = new Vector(); // Parameterliste 'class xy{}' wird gespeichert // ino.end // ino.attribute.parahash.23026.declaration private Hashtable parahash = new Hashtable(); // parametrisierten Attrib. werden mit den Paramet.aus paralist verk. // ino.end // ino.attribute.isFirstLocalVarDecl.23029.declaration public static boolean isFirstLocalVarDecl; //Hilfsvariable fuer Offsets, hoth // ino.end private Vector genericClassParameters=new Vector(); // ino.attribute.containedTypes.23032.decldescription type=line // PL 05-07-30 eingefuegt. Vektor aller Typdeklarationen, die in der Klasse // vorkommen. Wird in der Studienarbeit von Andreas Stadelmeier nur für Verifizierung der Tests eingesetzt. // ino.end // ino.attribute.containedTypes.23032.declaration private Vector containedTypes = new Vector(); // ino.end // ino.attribute.usedIdsToCheck.23035.declaration private Vector usedIdsToCheck = new Vector(); // ino.end private TypeAssumptions typeAssumptions = null;//muss mit null Initialisiert werden. Darf nur über getTypeAssumptions abgerufen werden. private Vector methodList = null; // gleich wie typeAssumptions // ino.attribute.parserlog.23038.declaration protected Logger parselog = Logger.getLogger("parser"); // ino.end protected Logger typinferenzLog = Logger.getLogger("Typeinference"); // ino.method.Class.23041.definition public Class(String name) // ino.end // ino.method.Class.23041.body { super(name); if(name.equals("java.lang.Object")){ superclassid=null; } } // ino.end // ino.method.Class.23044.definition public Class(String name, Modifiers mod) // ino.end // ino.method.Class.23044.body { super(name, mod); if(name.equals("java.lang.Object")){ superclassid=null; } } // ino.end // ino.method.Class.23047.defdescription type=javadoc /** * Konstruktor, der die Angabe aller Parameter ermoeglicht. * Zur Uebersichtlichkeit in der Grammatik. */ // ino.end // ino.method.Class.23047.definition public Class(String name, Modifiers mod, ClassBody cb, Vector ct, Vector usedIdsToCheck, UsedId superclass, Vector superif, Vector paralist) // ino.end // ino.method.Class.23047.body { super(name, mod); if (cb != null) set_ClassBody(cb); if (ct != null) setContainedTypes(ct); if (superclass != null) set_UsedId(superclass); if (superif != null) setSuperInterfaces(superif); if (paralist != null) this.set_ParaList(paralist); if(usedIdsToCheck!=null) this.usedIdsToCheck=usedIdsToCheck; // HOTI 10.5.06 // Object darf natuerlich nicht Object als Superklasse haben // Sonst gibt es eine endlosaufloesung if(name.equals("java.lang.Object")){ superclassid=null; } parserlog.debug("Neue Klasse: " + name); } // ino.end // ino.method.getUsedIdsToCheck.23050.definition public Vector getUsedIdsToCheck() // ino.end // ino.method.getUsedIdsToCheck.23050.body { return usedIdsToCheck; } // ino.end // ino.method.setContainedTypes.23053.definition public void setContainedTypes(Vector containedTypes) // ino.end // ino.method.setContainedTypes.23053.body { this.containedTypes = containedTypes; } // ino.end // ino.method.getContainedTypes.23056.definition public Vector getContainedTypes() // ino.end // ino.method.getContainedTypes.23056.body { return containedTypes; } // ino.end // ino.method.para_check.23059.definition public void para_check(Vector classlist, boolean ext) throws SCClassException // ino.end // ino.method.para_check.23059.body { //pr�ft, ob jeder Key in der parahash-Tabelle auch im Vector paralist steht bzw. umgekehrt. parahash = body.init_parahashtable(paralist,ext); // Para_check erstellt Hashtabelle der Klasse this.get_classname + parahash.toString()+paralist.toString()); for(Enumeration el = paralist.elements(); el.hasMoreElements();) { Type typ = (Type)el.nextElement(); if(!parahash.contains(typ.getName())) { parserlog.error(""); parserlog.error("Fehler: unbekannter Parameter: "+ typ.getName()); SCExcept neu=new SCExcept(); neu.set_error("Fehler: unbekannter Parameter: "+ typ.getName()); neu.set_statement("Class"); SCClassException except = new SCClassException(); Vector v = new Vector(); v.add(neu); except.addException(v); except.addClassname(getName()); throw except; } } if(superclassid != null) { String superclassname; Vector superclass = superclassid.get_Name(); // superclass darf nur ein Element haben, da es in Java keine Mehrfachvererbung gibt! for(Enumeration el = superclass.elements();el.hasMoreElements();) { superclassname = (String) el.nextElement(); // Alle Klassen in der Klassenliste (enth�lt alle definierten Klassen) durchgehen for ( Enumeration e2 = classlist.elements(); e2.hasMoreElements(); ) { Class basis =e2.nextElement(); // Klasse im Vektor == Superklasse if( basis.getName().equals(superclassname) ) { if( basis.paralist != null && superclassid!=null && superclassid.get_ParaList()!=null) { // System/.out.println( "Basis: " + basis.get_ParaList() ); // if( basis.get_ParaList().size() > 0 ) System/.out.println( "0: " + ((TypePlaceholder)basis.get_ParaList().elementAt(0)).get_Type() ); // if( basis.get_ParaList().size() > 1 ) System/.out.println( "1: " + ((TypePlaceholder)basis.get_ParaList().elementAt(1)).get_Type() ); // otth: geaender auf vParaOrg if(basis.paralist.size() != this.superclassid.get_ParaList().size()) { SCExcept neu = new SCExcept(); neu.set_error("Parameterlisten von Basis und Child unterscheiden sich in der L�nge!"); neu.set_classname(getName()); neu.set_statement("Class"); SCClassException except = new SCClassException(); Vector v = new Vector(); v.add(neu); except.addException(v); except.addClassname(getName()); // Exceptions werfen aufgrund vom eingestellten // Debug-Level??? // if( MyCompiler.DebugLevel != MyCompiler.UNIFICATION_INFO) // throw except; parserlog.debug("Parameterlistenl�ngenpr�fung von Basis- u. Superkl. tempor�r ausgeschalten! - otth"); } } } } } try { parahash = body.complete_parahashtable(classlist, superclassid,parahash, ext); } catch(SCClassBodyException ex){ SCClassException except = new SCClassException(); except.addException(ex.get_exlist()); except.addClassname(getName()); throw except; } paralist = complete_paralist(ext); //Parameterliste wird um die Eintr�ge der Basisklasse erg�nzt // vParaOrg wird hier nicht veraendert } else { // typinferenzLog.debug("\tkeine Vererbung gefunden!"); } /* if(ext) { string_rec("++ ParaCheck Globale Parameterliste: ",paralist);typinferenzLog.debug(); string_rec("++ ParaCheck Globale ParaHashtabelle: ", parahash);typinferenzLog.debug(); } */ } // ino.end // ino.method.complete_paralist.23062.definition public Vector complete_paralist(boolean ext) // ino.end // ino.method.complete_paralist.23062.body { //Diese Funktion vervollt�ndigt die Parameterliste f�r vererbte Klassen Vector child = paralist; paralist = (Vector)superclassid.get_ParaList(); for(Enumeration e = child.elements();e.hasMoreElements();){ paralist.addElement(e.nextElement()); } return this.paralist; } // ino.end // ino.method.sc_check_for_extended_classes.23068.definition public void sc_check_for_extended_classes(Vector classlist, Hashtable childhash,boolean ext) // ino.end // ino.method.sc_check_for_extended_classes.23068.body { // Der Semantik-Check f�r Basis-Klassen - Aufgabe: In der mit �bergegeben Hashtable childhash sollen // die geerbten Funktionen und Methoden mit ihren zugeh�rigen Typen eingetragen werden String strSuperKlassenName = null; // otth: Hat diese Klasse wieder eine Supperklasse? if( superclassid != null) { Vector superclass = superclassid.get_Name(); for(Enumeration el = superclass.elements();el.hasMoreElements();) //superclass darf nur ein Element haben!!! { strSuperKlassenName = (String) el.nextElement(); } } // otth: Hashtabelle f�r Superklasse erestellen body.sc_init_hashtable_for_extended_classes(classlist, strSuperKlassenName, childhash, paralist, parahash, body.kill, ext); } // ino.end // ino.method.codegen.23071.definition public void codegen(SourceFile sf) throws JVMCodeException // ino.end // ino.method.codegen.23071.body { ClassFile classfile = new ClassFile(); String superClass; // Handling der Superklasse if(superclassid != null) { superClass = superclassid.get_codegen_UsedId(); } else { superClass = "java/lang/Object"; } // Handling der Package String pkgName = ""; if (sf.getPackageName() != null) { pkgName = sf.getPackageName().get_codegen_UsedId() + "/"; } classfile.add_class(getName(), pkgName, superClass, getAccessFlags()); // Handling fuer Superinterfaces classfile.addSuperInterfaces(getSuperInterfaces()); // Generics hinzufuegen - falls erforderlich classfile.addGenerics(this.paralist,superclassid, this.getSuperInterfaces()); // Body der Classfile generieren if(body != null) { body.codegen(classfile, this.paralist); } // Ueberpruefung, ob Konstruktor generiert // Falls nicht, default-Konstruktor erzeugen if(!classfile.get_constructor_founded()) { classfile.add_method("", "()V", null, null, null, (short)0, this.paralist, false); } classfile.codegen(); codegenlog.info("Compilierung erfolgreich abgeschlossen, "+ getName() + ".class erstellt."); } // ino.end // ino.method.set_UsedId.23074.definition public void set_UsedId (UsedId uid) // ino.end // ino.method.set_UsedId.23074.body { this.superclassid = uid; } // ino.end // ino.method.set_ClassBody.23077.definition public void set_ClassBody(ClassBody body) // ino.end // ino.method.set_ClassBody.23077.body { this.body = body; } // ino.end // ino.method.set_class_block.23080.definition public void set_class_block(Block block) // ino.end // ino.method.set_class_block.23080.body { this.class_block = block; } // ino.end // ino.method.is_member.23083.definition public String is_member(String var) // ino.end // ino.method.is_member.23083.body { Hashtable h; h=body.get_hash(); return (String)h.get(var); } // ino.end // ino.method.get_Superclass_Name.23086.definition public String get_Superclass_Name() // ino.end // ino.method.get_Superclass_Name.23086.body { if(superclassid!=null) return superclassid.getQualifiedName(); else return null; } // ino.end // ino.method.get_ClassBody.23089.definition public ClassBody get_ClassBody() // ino.end // ino.method.get_ClassBody.23089.body { return body; } // ino.end // ino.method.get_class_block.23092.definition public Block get_class_block() // ino.end // ino.method.get_class_block.23092.body { return class_block; } // ino.end // ino.method.does_Class_extend.23095.definition public boolean does_Class_extend() // ino.end // ino.method.does_Class_extend.23095.body { if(superclassid==null) return false; else return true; } // ino.end // ino.method.set_ParaList.23098.definition public void set_ParaList(Vector para) // ino.end // ino.method.set_ParaList.23098.body { this.paralist = para; } // ino.end // ino.method.get_ParaList.23101.definition public Vector get_ParaList() // ino.end // ino.method.get_ParaList.23101.body { return this.paralist; } // ino.end // ino.method.set_ParaHash.23104.definition public void set_ParaHash(Hashtable hash) // ino.end // ino.method.set_ParaHash.23104.body { this.parahash = hash; } // ino.end // ino.method.get_ParaHash.23107.definition public Hashtable get_ParaHash() // ino.end // ino.method.get_ParaHash.23107.body { return this.parahash; } // ino.end /*static void string_rec(Hashtable ht){ String record=""; boolean isError=false; record=record.concat("["); for(Enumeration e=ht.elements(),k=ht.keys();e.hasMoreElements();){ String s = (String)k.nextElement(); Object o = e.nextElement(); record=record.concat(" "+s); if(o instanceof Type){ record=record.concat(" = "+((Type)o).getName()); } else if(o instanceof Hashtable){ record=record.concat("= "); string_rec((Hashtable)o); if(e.hasMoreElements()) record=record.concat(", "); } else if(o instanceof String){ record=record.concat(" = "+o); if(e.hasMoreElements()) record=record.concat(", "); } else { record=("[FEHLER: string_rec: unbekannter Typ!!!!!!"); isError=true; } } record=record.concat("]"); if(isError){ parserlog.error(record); }else{ parserlog.debug(record); } }*/ /*static void string_rec(Vector v){ String record=("{"); for(Enumeration e=v.elements();e.hasMoreElements();){ Type t = (Type)e.nextElement(); record=record.concat(" "+t.getName()); if(e.hasMoreElements()) record=record.concat(","); } record=record.concat("}"); parserlog.debug(record); }*/ /*static void string_rec(String st, Hashtable ht){ String record=(st); boolean isError=false; record=record.concat("["); for(Enumeration e=ht.elements(),k=ht.keys();e.hasMoreElements();){ String s = (String)k.nextElement(); Object o = e.nextElement(); record=record.concat(" "+s); if(o instanceof Type){ record=record.concat(" = "+((Type)o).getName()); } else if(o instanceof Hashtable){ record=record.concat("= "); string_rec((Hashtable)o); if(e.hasMoreElements()) record=record.concat(", "); } else if(o instanceof String){ record=record.concat(" = "+o); if(e.hasMoreElements()) record=record.concat(", "); } else { record=("[FEHLER: string_rec: unbekannter Typ!!!!!! " +o); isError = true; } } record=record.concat("]"); if(isError){ parserlog.error(record); }else{ parserlog.debug(record); } }*/ /*static void string_rec(String st,Vector v) { String record=(st); record=record.concat("{"); for(Enumeration e=v.elements();e.hasMoreElements();) { Type t = (Type)e.nextElement(); record=record.concat(" "+t.getName()); if(e.hasMoreElements()) { record=record.concat(", "); } } record=record.concat("}"); parserlog.debug(record); }*/ ///////////////////////////////////////////////////////////////////////// // TypeReconstructionAlgorithmus ///////////////////////////////////////////////////////////////////////// // ino.method.TRProg.23110.defdescription type=javadoc /** * Ausgangspunkt f�r den Typrekonstruktionsalgorithmus. Hier werden zun�chst * die Mengen von Typannahmen V_fields_methods und V_i erstellt, die als Eingabe * f�r den Algorithmus dienen.
* (siehe Algorithmus 5.17 TRProg, Martin Pl�micke) *
Author: J�rg B�uerle * @param supportData * @param globalAssumptions * @return Liste aller bisher berechneten, m�glichen Typkombinationen * @throws CTypeReconstructionException */ // ino.end // ino.method.TRProg.23110.definition public Vector TRProg(CSupportData supportData, TypeAssumptions globalAssumptions) throws CTypeReconstructionException // ino.end // ino.method.TRProg.23110.body { /* */ ////////////////////////////// // Und los geht's: ////////////////////////////// inferencelog.info("Rufe TRStart()..."); ////////////////////////////// // Ab hier ... // @author A10023 - Andreas Stadelmeier: ////////////////////////////// //Erzeuge Assumptions: TypeAssumptions assumptions = this.getTypeAssumptions(); //-- assumptions.add(globalAssumptions); //Generiere Liste mit Expressions, welche zur Initialisierung von Feldern verwendet werden. Vector fieldInitializers = new Vector(); for(FieldInitialization field : body.getFieldInitializations()){ Assign fieldAssign = new Assign(0,0); Expr expr1 = new LocalOrFieldVar(field.getName(), 0); Expr expr2 = field.getWert(); fieldAssign.set_Expr(expr1, expr2); fieldInitializers.add(fieldAssign); } ConstraintsSet oderConstraints = this.TYPE(this.getMethodList(), fieldInitializers, assumptions); typinferenzLog.debug("Erstellte Constraints: "+oderConstraints); //Die Constraints in Pair's umwandeln: Vector> xConstraints = new Vector>();// = oderConstraints.getConstraints(); for(Vector uC:oderConstraints.getConstraints()){ //mit dem getConstraints-Aufruf wird das Karthesische Produkt erzeugt. Vector cons = new Vector(); for(UndConstraint undCons:uC){ cons.addAll(undCons.getConstraintPairs()); } xConstraints.add(cons); } typinferenzLog.debug("Karthesisches Produkt der Constraints: "+xConstraints); ////////////////////////////// // Unifizierung der Constraints: ////////////////////////////// Vector ret = new Vector(); //Generiere das Result-Set for(Vector constraints : xConstraints){ //Alle durch das Karthesische Produkt entstandenen Möglichkeiten durchgehen: Vector> result = new Vector>(); //Alle FunN-Typen werden per clone-methode in RefTypes verwandelt. (Die clone Methode in FunN darf nicht überschrieben werden. for(Pair p : constraints){ if(p.TA1 instanceof FunN){ p.TA1 = p.TA1.clone(); } if(p.TA2 instanceof FunN){ p.TA2 = p.TA2.clone(); } } //Erst die Unifizierung erstellen: Vector> unifyResult = Unify.unify(constraints, supportData.getFiniteClosure()); //Dann den Ergebnissen anfügen result.addAll(unifyResult); // Debugoutput:Vector> typinferenzLog.debug("Unifiziertes Ergebnis: "+result); /* // Prüfe ob eindeutige Lösung: if(result.size()>1 && !Unify.hasSolvedForm(result.elementAt(0))){ typinferenzLog.debug("Keine eindeutige Lösung!"); }else if(result.size()>1){ //Replace TPH: for(Pair res : result.elementAt(0)){ if(res.OperatorEqual()){ if(res.TA1 instanceof TypePlaceholder)((TypePlaceholder)res.TA1).fireReplaceTypeEvent(new CReplaceTypeEvent(res.TA1, res.TA2)); } } } */ //typinferenzLog.debug(); //typinferenzLog.debug(supportData.getFiniteClosure()); typinferenzLog.debug("Typinformationen: \n"+this.getTypeInformation(this.getMethodList(), fieldInitializers)); typinferenzLog.debug("\nJavaFiles:\n"); //typinferenzLog.debug(this.printJavaCode(new ResultSet(new Vector()))); //Der Unifikationsalgorithmus kann wiederum auch mehrere Lösungen errechnen, diese werden im folgenden durchlaufen: for(Vector resultSet : result){ //Add Result set as a new ReconstructionResult to ret: TypeinferenceResultSet reconstructionResult = new TypeinferenceResultSet(this); reconstructionResult.setConstraints(constraints); reconstructionResult.setUnifiedConstraints(resultSet); ret.add(reconstructionResult); //ResultSet res = new ResultSet(resultSet); typinferenzLog.debug("JavaFile für ResultSet "+reconstructionResult+"\n"); typinferenzLog.debug(this.printJavaCode(reconstructionResult)); } } return ret; /* CReconstructionTupleSet retTupleSet = this.TRStart(methodList, V, V_fields_methods, supportData); inferencelog.debug("Bin aus TRStart() zur�ck in TRProg()."); ////////////////////////////// // Neu Ergebnismenge A aller // Typannahmen erzeugen: ////////////////////////////// inferencelog.debug("Erstelle Ergebnismenge..."); Vector newA = new Vector(); // Alle bisherigen M�glichkeiten an Typkombinationen durchgehen: Vector oldA = supportData.getA(); for(int i=0; i retTupleIt = retTupleSet.getIterator(); while(retTupleIt.hasNext()){ CReconstructionTuple possibleTuple = retTupleIt.next(); this.clear(possibleTuple.getAssumSet(), rememberLocals); // Neue Typinformationen mit alten Typinformationen vereinigen: CTypeReconstructionResult newReconResult = oneReconResult.shallowCopy(); newReconResult.addDataFromTupel(possibleTuple); //PL 05-08-02 eingefuegt //Fuegt Klassen und GenericTypeVars zu A hinzu newReconResult.addClassName(this.getName()); Vector genericsList = new Vector(); for(int ii =0; ii getMethodList() { if(this.methodList != null) return this.methodList; //TODO: Unnötige Berechnungen im folgenden Code rauskürzen: ////////////////////////////// // Die Eingabedaten bauen: ////////////////////////////// inferencelog.debug("Baue Eingabedaten..."); TypeAssumptions V_fields_methods = new TypeAssumptions(this.getName()); Vector methodList = new Vector(); Vector V = new Vector(); Vector rememberLocals = new Vector(); ////////////////////////////// // Alle Felder durchgehen: // Zuerst alle Attribute, dann Methoden // ge�ndert: hoth 06.04.2006 ////////////////////////////// for(FieldDecl field : body.get_FieldDeclVector()) { ////////////////////////////// // Attribut: ////////////////////////////// if(field instanceof InstVarDecl){ InstVarDecl instVar = (InstVarDecl)field; ////////////////////////////// // Alle Variablendeklarationen (int a, b, c) durchgehen: ////////////////////////////// for(int i=0; i()); // Typannahme bauen... V_fields_methods.add(assum); // ...und hinzuf�gen. } } } for(FieldDecl field : body.get_FieldDeclVector()) { ////////////////////////////// // Methode: ////////////////////////////// if(field instanceof Method){ Method method = (Method)field; //if(method.get_Method_Name().equals(this.getName()) && ((method.getReturnType().equals(new mycompiler.mytype.Void(0))) || method.getReturnType() instanceof TypePlaceholder)){ if(method.get_Method_Name().equals(this.getName()) ){ method.set_Method_Name(""); } //hoth: 06.04.2006 //durchlaufe Block und suche nach Objektvariablen fuer Offset-Markierung Iterator fieldVarIterator = V_fields_methods.iterator(); while (fieldVarIterator.hasNext()) { //Wenn ObjektVariable CTypeAssumption dieAssum = fieldVarIterator.next(); if(dieAssum instanceof CInstVarTypeAssumption) { Class.isFirstLocalVarDecl=false; if(method.get_Block() != null) method.get_Block().addOffsetsToAssumption(dieAssum,dieAssum.getIdentifier(),true); } } methodList.addElement(method); // F�r V_fields_methods: CMethodTypeAssumption methodAssum = new CMethodTypeAssumption(this.getType(), method.get_Method_Name(), method.getReturnType(), method.getParameterCount(),method.getLineNumber(),method.getOffset(),new Vector(),method.getGenericMethodParameters()); // Typannahme bauen... // Methode in V_Fields_methods ablegen // Dabei wird die OverloadedMethodID ermittelt !! // => Method setzenuct V_fields_methods.add(methodAssum); method.setOverloadedID(methodAssum.getHashSetKey().getOverloadedMethodID()); // F�r die V_i: CTypeAssumptionSet localAssum = new CTypeAssumptionSet(); // Bauen... ParameterList parameterList = method.getParameterList(); if(parameterList!=null){ for(int i=0; i()); //fuege Offsets fuer Parameter hinzu, hoth: 06.04.2006 Class.isFirstLocalVarDecl=false; if(method.get_Block() != null) method.get_Block().addOffsetsToAssumption(paraAssum,paraAssum.getIdentifier(),true); methodAssum.addParaAssumption(paraAssum); // F�r die V_i: CLocalVarTypeAssumption varAssum = new CLocalVarTypeAssumption(this.getName(), method.get_Method_Name(), method.getParameterCount(), method.getOverloadedID(),"1", para.get_Name(),para.getType(), para.getLineNumber(),para.getOffset(),new Vector()); localAssum.addElement(varAssum); rememberLocals.addElement(varAssum); } } // ...und hinzuf�gen: V.addElement(localAssum); } } this.methodList = methodList; return methodList; } /** * Die Funktion ist erst nach dem Aufruf von getMethodList() nutzbar. * Ermittelt alle Felder und Methoden der Klasse und Erstellt eine Assumption für diese. * @return Die erstellten TypeAssumptions */ private TypeAssumptions getTypeAssumptions() { if(this.typeAssumptions != null)return this.typeAssumptions; //Das sorgt dafür, dass die Assumptions nur einmalig generiert werden. TypeAssumptions assumptions = new TypeAssumptions(this.getName()); this.getMethodList(); //Diese Funktion muss zuerst ausgeführt werden. //Assumption für this, also die aktuelle Klasse: (ist nicht mehr nötig, da jedes AssumptionSet einer Klasse (dem namen einer Klasse) zugewiesen ist. //CLocalVarTypeAssumption thisAssumption = new CLocalVarTypeAssumption(this.name, name, 0, 0, name, "this", new RefType(name,0), 0, 0, null); //assumptions.setThisV(thisAssumption); for(FieldDecl field : body.get_FieldDeclVector()){ assumptions.add(field.createTypeAssumptions(this)); } //Eine Assumption für den Standardkonstruktor: // (Ein Standardkonstruktor wird immer angefügt, da es momentan keine statischen Klassen gibt) if(assumptions.getMethodAssumptions(this.getName(), "").size()==0){ //Falls kein Konstruktor für diese Klasse definiert wurde: assumptions.addMethodAssumption(new RefType(this.getName(),0), "", new RefType(this.getName(),0), new Vector()); } typinferenzLog.debug("Erstellte Assumptions: "+assumptions); this.typeAssumptions = assumptions; //Diese müssen anschließend nicht wieder generiert werden. return assumptions; } public ConstraintsSet TYPE(Vector methodList, Vector fielddeclarationList, TypeAssumptions assumptions){ ConstraintsSet ret = new ConstraintsSet(); // Die Felddeklarationen werden zu den Assumptions hinzugefügt und gelten danach für jede Methode. //TypeAssumptions assumptionsPlusFieldAssumptions = new TypeAssumptions(assumptions); for(Expr expr : fielddeclarationList){ //ret.add(expr.TYPEStmt(assumptionsPlusFieldAssumptions)); ret.add(expr.TYPEStmt(assumptions)); } for(Method methode : methodList){ //ret.add(methode.TYPE(assumptionsPlusFieldAssumptions)); ret.add(methode.TYPE(assumptions)); } return ret; } // ino.method.clear.23113.defdescription type=javadoc /** * Entfernt Annahmen f�r lokale Variablen, die f�r Methodenparameter erzeugt * worden sind. (siehe Algorithmus 5.17 TRProg, Martin Pl�micke) *
Author: J�rg B�uerle * @param V * @param locals */ // ino.end // ino.method.clear.23113.definition void clear(CTypeAssumptionSet V, Vector locals) // ino.end // ino.method.clear.23113.body { Iterator localsIt = locals.iterator(); while(localsIt.hasNext()){ CTypeAssumption local = localsIt.next(); CTypeAssumption assum = V.getElement(local.getHashSetKey()); if(assum!=null){ V.removeElement(local.getHashSetKey()); } } } // ino.end // ino.method.RetType.23119.defdescription type=javadoc /** * Liefert den berechneten R�ckgabetyp f�r die �bergebene Methode zur�ck.
* (siehe Algorithmus RetType, Martin Pl�micke) *
Author: J�rg B�uerle * @param me * @param V * @return */ // ino.end // ino.method.RetType.23119.definition private Type RetType(Method me, CTypeAssumptionSet V) // ino.end // ino.method.RetType.23119.body { CTypeAssumption assum = V.getElement(new CMethodKey(this.getName(), me.get_Method_Name(), me.getParameterCount(),me.getOverloadedID())); if(assum instanceof CMethodTypeAssumption){ return ((CMethodTypeAssumption)assum).getAssumedType(); } else return null; } // ino.end // ino.method.toString.23125.defdescription type=javadoc /** *
Author: Martin Pl�micke * @return */ // ino.end // ino.method.toString.23125.definition public String toString() // ino.end // ino.method.toString.23125.body { //return superclassid.toString() + body.toString(); //geaendert PL 07-07-28 return name + body.toString(); } // ino.end // ino.method.wandleRefTypeAttributes2GenericAttributes.23128.defdescription type=javadoc /** * Alle Methoden der Klassen überprüfen, ob sie als * RefType deklarierte Attribute haben, die aber GenericTypeVars sind * und ggf. ersetzen * * Bsp.: * bei public E elementAt(i){...} wird E vorerst als RefType erkannt * */ // ino.end // ino.method.wandleRefTypeAttributes2GenericAttributes.23128.definition public void wandleRefTypeAttributes2GenericAttributes() // ino.end // ino.method.wandleRefTypeAttributes2GenericAttributes.23128.body { // Klassen ohne Body werden hier nicht durchsucht // (p.ex. BaseTypes) if(body==null) return; Vector fieldsAndMethods=body.get_FieldDeclVector(); // Alle Methoden und Instanzvariablen durchgehen for(int i=0;i enumer = V_last.getHashtable().keys(); // while(enumer.hasMoreElements()){ // CTypeAssumption currentAssum = V_last.getElement(enumer.nextElement()); // if(currentAssum instanceof CLocalVarTypeAssumption){ // V_i.removeElement(currentAssum); // } // } // // } // ino.method.addOffsetsToAssumption.23131.defdescription type=javadoc /** * Methode f�gt zu einer CTypeAssumption alle * Offsets hinzu, wo die Variable benutzt wird. *
Author: Thomas Hornberger 07.04.2006 *
Author: Arne Lüdtke 20.01.2007, Auf Polymorphie erweitert. * Wird nicht mehr verwendet. In Block ausgelagert. * @return */ // ino.end // ino.method.addOffsetsToAssumption.23131.definition public static void addOffsetsToAssumption(CTypeAssumption localAssumption, Block localBlock,String NameVariable,boolean isMemberVariable) // ino.end // ino.method.addOffsetsToAssumption.23131.body { /*if(localBlock!=null){ for(Object vectorObjekt : localBlock.statements) //durchlaufe alle Statements dieses Blocks { if(vectorObjekt instanceof Block) //Bei Block { Block b = (Block)vectorObjekt; addOffsetsToAssumption(localAssumption,b,NameVariable,isMemberVariable);//rekursiver Aufruf } else { String Name_Superklasse = vectorObjekt.getClass().getSuperclass().getSimpleName(); if(Name_Superklasse.equals("Statement")) //Bei Statement { Statement s = (Statement)vectorObjekt; try{ if(addOffsetsToStatement(localAssumption,s,NameVariable,isMemberVariable)==false) {break;}} catch(NullPointerException NPE){} } else if(Name_Superklasse.equals("Expr") || Name_Superklasse.equals("BinaryExpr") || Name_Superklasse.equals("UnaryExpr")) //Bei Expression { Expr e = (Expr)vectorObjekt; try{ addOffsetsToExpression(localAssumption,e,NameVariable,isMemberVariable);} catch(NullPointerException NPE){} } } }}*/ } // ino.end // ino.method.addOffsetsToStatement.23134.defdescription type=javadoc /** * Hilfs-Methode f�r die Offset-Zuweisung * durchsucht ein Statement rekursiv *
Author: Thomas Hornberger 08.04.2006 *
Author: Arne Lüdtke 20.10.2007, Auf Polymorphie umgebaut. * @return */ // ino.end // ino.method.addOffsetsToStatement.23134.definition public static boolean addOffsetsToStatement(CTypeAssumption localAssumption,Statement statement, String NameVariable, boolean isMemberVariable) // ino.end // ino.method.addOffsetsToStatement.23134.body { return statement.addOffsetsToStatement(localAssumption,NameVariable,isMemberVariable); /*if(statement instanceof Block) //Wenn Block { Block b = (Block)statement; addOffsetsToAssumption(localAssumption,b,NameVariable,isMemberVariable); } else if(statement instanceof IfStmt)//Wenn if { IfStmt i = (IfStmt)statement; addOffsetsToExpression(localAssumption,i.expr,NameVariable,isMemberVariable); addOffsetsToStatement(localAssumption,i.else_block,NameVariable,isMemberVariable); addOffsetsToStatement(localAssumption,i.then_block,NameVariable,isMemberVariable); } else if(statement instanceof Return)//Wenn Return { Return r = (Return)statement; addOffsetsToExpression(localAssumption,r.retexpr,NameVariable,isMemberVariable); } else if(statement instanceof WhileStmt)//Wenn While { WhileStmt w = (WhileStmt)statement; addOffsetsToExpression(localAssumption,w.expr,NameVariable,isMemberVariable); addOffsetsToStatement(localAssumption,w.loop_block,NameVariable,isMemberVariable); } else if(statement instanceof LocalVarDecl)//Wenn Lokale-Variable-Deklaration { isMemberVariable=true;//hoth 02.05.06 if(isMemberVariable)//Wenn Objektvariable { LocalVarDecl l = (LocalVarDecl)statement; if(l.get_Name().equals(NameVariable)) { if(isFirstLocalVarDecl==false) {return false;}//Wenn jetzt lokale Variable kommt, dann springe raus else {isFirstLocalVarDecl=false;} } } } return true;*/ } // ino.end // ino.method.addOffsetsToExpression.23137.defdescription type=javadoc /** * Hilfs-Methode f�r die Offset-Zuweisung * durchsucht eine Expression rekursiv *
Author: Thomas Hornberger 07.04.2006 *
Authos: Arne Lüdtke 20.01.2007, Auf Polymorphie umgebaut. * @return */ // ino.end // ino.method.addOffsetsToExpression.23137.definition public static void addOffsetsToExpression(CTypeAssumption localAssumption,Expr expression, String NameVariable,boolean isMemberVariable) // ino.end // ino.method.addOffsetsToExpression.23137.body { expression.addOffsetsToExpression(localAssumption,NameVariable,isMemberVariable); } // ino.end // ino.method.getSimpleName.23140.defdescription type=javadoc /** * HOTI * Liefert bei Klassen die fullyQualified angegeben wurden * nur den schlussendlichen Bezeichner * p.ex. java.util.Vector => Vector * @return */ // ino.end // ino.method.getSimpleName.23140.definition public String getSimpleName() // ino.end // ino.method.getSimpleName.23140.body { return UsedId.createFromQualifiedName(getName(),-1).getSimpleName(); } // ino.end public String getTypeInformation(Vector methodList, Vector fieldList){ String ret = this.name+": "; for(Expr field : fieldList){ ret+=field.getTypeInformation()+"\n"; } for(Method m : methodList){ ret+=m.getTypeInformation()+"\n"; } return ret; } /** * Generiert den JavaCode dieser Klasse im Falle für das übergebene resultSet. * Dem ResultSet entsprechend werden in diesem Java-Code die TypePlaceholder durch die in ResultSet stehenden Typen ersetzt. * @return Java-Sourcefile */ public String printJavaCode(TypeinferenceResultSet reconstructionResult){ JavaCodeResult ret = new JavaCodeResult("class "); //Generiere JavaCode der extends-Typen: /* String containedTypesJavaCode = ""; for(Type containedType : containedTypes){ containedTypesJavaCode += containedType.printJavaCode(resultSet)+ ", "; } if(containedTypesJavaCode.length()>1)containedTypesJavaCode = containedTypesJavaCode.substring(0, containedTypesJavaCode.length() -2); */ JavaCodeResult classBodyCode = new JavaCodeResult(); if(this.modifiers!=null)classBodyCode.attach(this.modifiers.printJavaCode(reconstructionResult.getUnifiedConstraints())).attach(" "); if(superclassid == null || superclassid.get_Name().size()<1){ int superclassidOffset = superclassid == null ? 0 : superclassid.getOffset(); superclassid = new UsedId("Object", superclassidOffset); } classBodyCode.attach(this.name + " extends ").attach(superclassid.printJavaCode(reconstructionResult.getUnifiedConstraints())).attach("\n"); JavaCodeResult bodyString = this.body.printJavaCode(reconstructionResult.getUnifiedConstraints()).attach("\n"); classBodyCode.attach(bodyString); //Zuerst die generischen Parameter für diese Klasse berechnen: this.createGenericTypeVars(classBodyCode.getUnresolvedTPH()); if(this.genericClassParameters != null && this.genericClassParameters.size()>0){ ret.attach("<"); Iterator it = this.genericClassParameters.iterator(); while(it.hasNext()){ GenericTypeVar tph = it.next(); ret.attach(tph.printJavaCode(reconstructionResult.getUnifiedConstraints())); if(it.hasNext())ret.attach(", "); } ret.attach(">"); } String stringReturn = ret.attach(classBodyCode).toString(); return stringReturn; } /** * Errechnet die Generischen Parameter der Klasse für diese Klasse. * Die berechneten Variablen werden anschließend in die this.genericTypeVars eingesetzt. Dabei werden alte genericTypeVars überschrieben. * @param tphs : Alle übriggebliebenen TypePLaceholder */ public void createGenericTypeVars(Vector tphs){ this.genericClassParameters = new Vector(); for(TypePlaceholder tph : tphs){ GenericTypeVar toAdd = new GenericTypeVar(tph); if(!this.genericClassParameters.contains(toAdd))this.genericClassParameters.add(toAdd); } } /** * Errechnet die Generischen Parameter der Klasse für diese Klasse. * Die berechneten Variablen werden anschließend in die this.genericTypeVars eingesetzt. Dabei werden alte genericTypeVars überschrieben. * @param reconstructionResult */ public void createGenericTypeVars(TypeinferenceResultSet reconstructionResult){ this.genericClassParameters = new Vector(); for(Pair pair : reconstructionResult.getUnifiedConstraints()){ if(pair.TA2 instanceof TypePlaceholder && pair.TA1 instanceof TypePlaceholder){// if(pair.OperatorSmallerExtends() || pair.OperatorSmaller()){ Type ta1=reconstructionResult.getUnifiedConstraints().getTypeEqualTo(pair.TA1); Type ta2=reconstructionResult.getUnifiedConstraints().getTypeEqualTo(pair.TA2); this.genericClassParameters.add(new GenericTypeVar(new Pair(ta1,ta2))); } /* // Auf SuperWildcardTypes überprüfen: ArrayList wildcardTypes = pair.TA2.getSuperWildcardTypes(); wildcardTypes.addAll(pair.TA1.getSuperWildcardTypes()); for(SuperWildcardType wildcardType : wildcardTypes){ this.genericClassParameters.add(new GenericTypeVar(new Pair(TypePlaceholder.fresh(), wildcardType.getContainedType()))); } */ } for(Pair pair : reconstructionResult.getConstraints()){ if( ! reconstructionResult.getUnifiedConstraints().contains(pair.TA1)){ this.genericClassParameters.add(new GenericTypeVar(pair.TA1)); } if( ! reconstructionResult.getUnifiedConstraints().contains(pair.TA2)){ this.genericClassParameters.add(new GenericTypeVar(pair.TA2)); } } } /** * Erstellt einen RefType, welcher auf diese Klasse verweist * @return */ public RefType getType() { return new RefType(this.getName(), this.get_ParaList(), 0); } /** * Ermittelt die Sichtbaren Felder und Methoden der Klasse. * (Momentan sind im Projekt alle Felder und Methoden "package private", da der Parser keine Access-Modifier einlesen kann. * @return */ public TypeAssumptions getPublicFieldAssumptions() { TypeAssumptions ret = this.getTypeAssumptions(); return ret; } } // ino.end