// 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.IItemWithOffset; import mycompiler.SyntaxTreeNode; 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.FC_TTO; 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.Typeable; import typinferenz.UndConstraint; import typinferenz.FunN; import typinferenz.assumptions.ClassAssumption; import typinferenz.assumptions.TypeAssumptions; import typinferenz.exceptions.DebugException; import typinferenz.exceptions.TypeinferenceException; import typinferenz.typedeployment.TypeInsertPoint; import typinferenz.*; // ino.class.Class.23010.declaration public class Class extends SyntaxTreeNode implements AClassOrInterface, IItemWithOffset, Generic, GenericTypeInsertable // ino.end // ino.class.Class.23010.body { /** * Log4j - Loggerinstanzen */ protected static Logger inferencelog = Logger.getLogger("inference"); protected static Logger codegenlog = Logger.getLogger("codegen"); protected static Logger parserlog = Logger.getLogger("parser"); protected UsedId pkgName; protected Modifiers modifiers; protected String name; private Vector superif = new Vector(); public UsedId getPackageName() { return pkgName; } public void setPackageName(UsedId pkgName) { this.pkgName = pkgName; } public String getName() { return name; } public void setName(String strName) { name = strName; } public void setModifiers(Modifiers mod) { this.modifiers = mod; } public Modifiers getModifiers() { return this.modifiers; } /** * Liefert die AccessFlags fuer den Bytecode zurueck. */ public short getAccessFlags() { short ret = 0; if (modifiers != null) { ret = modifiers.calculate_access_flags(); } return ret; } public Vector getSuperInterfaces() { return superif; } public void setSuperInterfaces(Vector superif) { this.superif = superif; } // 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.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. // ino.attribute.parserlog.23038.declaration protected Logger parselog = Logger.getLogger("parser"); // ino.end protected Logger typinferenzLog = Logger.getLogger("Typeinference"); private SyntaxTreeNode parent; private Vector fielddecl = new Vector(); private GenericDeclarationList genericClassParameters; private int offset; // ino.method.Class.23041.definition public Class(String name, int offset) // ino.end // ino.method.Class.23041.body { this.name = name; if(name.equals("java.lang.Object")){ superclassid=null; } this.offset = offset; } // ino.end // ino.method.Class.23044.definition public Class(String name, Modifiers mod, int offset) // ino.end // ino.method.Class.23044.body { this.name = name; this.modifiers = mod; if(name.equals("java.lang.Object")){ superclassid=null; } this.offset = offset; } // 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, int offset) // ino.end // ino.method.Class.23047.body { this.name = name; this.modifiers = 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); this.offset = offset; } // ino.end public Vector getFields() { return fielddecl; } /** * @author Andreas Stadelmeier, a10023 * Fügt der Klasse eine Feld hinzu. * Prüft dabei, ob es sich um einen Constructor handelt und wandelt diesen direkt um. * @param feld */ public void addField(Field i) { fielddecl.addElement(i); } // 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.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 /** * Generiert die ClassFile für diese Klasse. * @param typeinferenceResult - Das ResultSet einer Typinferierung oder null, falls alle Typen eindeutig feststehen. * @return * @throws JVMCodeException */ // ino.method.codegen.23071.definition public ClassFile codegen(ResultSet typeinferenceResult) 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() + "/"; //} //geändert von Andreas Stadelmeier: pkgName wird nicht mehr aus dem SourceFile ausgelesen: String packageName = ""; if(pkgName != null) packageName = pkgName.get_Name_1Element(); classfile.add_class(getName(), packageName, 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) { this.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."); return classfile; } public void codegen(ClassFile classfile, Vector paralist) throws JVMCodeException { for(int i=0 ; i < this.getFields().size() ; i++) { /* * if(this.fielddecl.elementAt(i) instanceof InstVarDecl) { ((InstVarDecl)this.fielddecl.elementAt(i)).codegen(classfile, paralist); } else */ { this.fielddecl.elementAt(i).codegen(classfile, paralist); } } } public void set_UsedId (UsedId uid) // ino.end // ino.method.set_UsedId.23074.body { this.superclassid = uid; } // ino.end /** * Setzt den ClassBody dieser Klasse. Wird zum Parsen benötigt. * Der ClassBody enthält sämtliche Felder dieser Klasse. * Mit dem Aufruf dieser Methode werden alle Felder des ClassBody in diese Class übertragen. * (Nur einmal während des Parsens aufrufen!) */ public void set_ClassBody(ClassBody body) { Vector tempFields=body.getFields(); for(Field f : this.getFields()){ if(f instanceof Method){ //Wenn es sich um eine Methode handelt ist eine zusätzliche Prüfung erfoderlich: (Ist es ein Konstruktor?) Method m = (Method)f; /* * Ermitteln ob es sich bei der Methode um einen Konstruktor handelt: * (Parser kann nicht zwischen Methode und Konstruktor unterscheiden. * Denn für einen Konstruktor gelten besondere Regeln: * -Typ des Blocks eines Konstruktor ist void (kein Return-Statement) * -Rückgabetyp der Methode/Konstruktors ist der Typ der Klasse * -Ein Konstruktor kann nicht aufgerufen werden (nur mit new) */ if(m.get_Method_Name().equals(""))throw new TypeinferenceException(" ist kein gültiger Methodenname", m); if((m.get_Method_Name().equals(this.getName()))) { Constructor constructor = new Constructor(m); tempFields.add(constructor); //Den Konstruktor anstatt der Methode anfügen }else{ //Handelt es sich um keinen Konstruktor, dann die Methode unverändert den Feldern hinzufügen: tempFields.add(m); } }else{ tempFields.add(f); //Ansonsten das Feld anfügen... } } this.fielddecl = tempFields; } // 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.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_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 ConstraintsSet typeReconstruction(FC_TTO 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.getPrivateFieldAssumptions(); //Globale Assumptions anfügen: assumptions.add(globalAssumptions); ConstraintsSet oderConstraints = new ConstraintsSet(); for(Type gparam : this.paralist){ if(gparam instanceof GenericTypeVar)assumptions.add(((GenericTypeVar)gparam).createAssumptions()); //Constraints für die Generischen Variablen erstellen und diese dem AssumptionsSet hinzufügen } for(Type gparam : this.paralist){ if(gparam instanceof GenericTypeVar)oderConstraints.add(((GenericTypeVar)gparam).TYPE(assumptions)); //Constraints für die Generischen Variablen erstellen und diese dem AssumptionsSet hinzufügen } typinferenzLog.debug("Erstellte Assumptions: "+assumptions); /* //Generiere Liste mit Expressions, welche zur Initialisierung von Feldern verwendet werden. Vector fieldInitializers = new Vector(); for(FieldDeclaration 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); for(Field f:this.getFields()){ oderConstraints.add(f.TYPE(assumptions)); } typinferenzLog.debug("Erstellte Constraints: "+oderConstraints); return oderConstraints; /* 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(Field field : this.getFields()) { ////////////////////////////// // Attribut: ////////////////////////////// } for(Field field : this.getFields()) { ////////////////////////////// // 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.getIdentifier(),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; } */ /** * Ermittelt alle privaten Felder und Methoden der Klasse und Erstellt eine Assumption für diese. * Bemerkung: Momentan werden noch alle Felder dieser Klasse zurückgegeben. * @return Die erstellten TypeAssumptions */ private TypeAssumptions getPrivateFieldAssumptions() { 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(Field field : this.getFields()){ if(!field.isPublic())assumptions.add(field.createTypeAssumptions(this)); } //Eine Assumption für den Standardkonstruktor: // (Ein Standardkonstruktor wird immer angefügt, da es momentan keine statischen Klassen gibt) //auskommentiert, da der Standardkonstruktor beim Parser-Postprocessing angefügt wird. //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()); //} 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; } // 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 { for(Field f : this.getFields()){ //f.wandleRefTypeAttributes2GenericAttributes(paralist); } /* Vector fieldsAndMethods=this.getFields(); // 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(" "); classBodyCode.attach(this.name + " extends ").attach(superclassid.printJavaCode(reconstructionResult.getUnifiedConstraints())).attach("\n"); JavaCodeResult bodyString = new JavaCodeResult("{\n"); for(Field field : this.fielddecl)bodyString.attach( field.printJavaCode(reconstructionResult.getUnifiedConstraints()) ).attach( "\n" ); bodyString.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 private void createGenericTypeVars(Vector tphs){ this.genericClassParameters = new GenericDeclarationList(new Vector()); for(TypePlaceholder tph : tphs){ GenericTypeVar toAdd = new GenericTypeVar(tph,this.getOffset()); 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),this.getOffset())); } } for(Pair pair : reconstructionResult.getConstraints()){ if( ! reconstructionResult.getUnifiedConstraints().contains(pair.TA1)){ this.genericClassParameters.add(new GenericTypeVar(pair.TA1,this.getOffset())); } if( ! reconstructionResult.getUnifiedConstraints().contains(pair.TA2)){ this.genericClassParameters.add(new GenericTypeVar(pair.TA2, this.getOffset())); } } } */ public int getOffset(){ return this.offset; } /** * Erstellt einen RefType, welcher auf diese Klasse verweist * Ersetzt alle Generischen Variablen in der Parameterliste mit TPH * @return */ public RefType getType() { /* Vector parameter = new Vector(); for(Type param : this.get_ParaList()){ parameter.add(((GenericTypeVar)param).getTypePlaceHolder());//(TypePlaceholder.fresh()); //Hier ist kein ReplacementListener notwendig. Der Typ soll nie eingesetzt werden. Der TPH wird nur gebraucht, damit das Unifizieren funktioniert. } */ 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 = new TypeAssumptions();//this.getPrivateFieldAssumptions(); ret.addClassAssumption(new ClassAssumption(this)); for(Field f : this.getFields()){ if(f.isPublic())ret.add(f.createTypeAssumptions(this)); } return ret; } @Override public void parserPostProcessing(SyntaxTreeNode parent) { super.parserPostProcessing(parent); //Wenn keine Superklasse, dann erbt die Klasse zwangsweise von Object: if(superclassid == null || superclassid.get_Name().size()<1){ int superclassidOffset = superclassid == null ? 0 : superclassid.getOffset(); superclassid = new UsedId("Object", superclassidOffset); } //Alle Methoden auf Konstruktoren durchsuchen und diese umwandeln: Vector tempFields = new Vector(); for(Field f : this.getFields()){ if(f instanceof Method && !(f instanceof Constructor)){ Method method = (Method)f; if(method.get_Method_Name().equals(this.getName()) ){ tempFields.add(new Constructor(method)); }else{ tempFields.add(f); } }else{ tempFields.add(f); } } this.fielddecl = tempFields; //Prüfen ob ein Konstruktor vorhanden ist: boolean constructorVorhanden = false; for(Field f : this.getFields()){ if(f instanceof Constructor){ constructorVorhanden = true; break; } } if(!constructorVorhanden){//Falls kein Konstruktor vorhanden ist, muss noch der Standardkonstruktor angefügt werden: Constructor standardKonstruktor = new Constructor(Method.createEmptyMethod(this.getName(), this)); this.addField(standardKonstruktor); } //TODO: Umwandlung zu RefTypes funktioniert noch nicht richtig. (siehe LambdaTest2) //Als RefType geparste Generische Variablen umwandeln: this.wandleRefTypeAttributes2GenericAttributes(); } @Override public SyntaxTreeNode getParent() { return this; } @Override public Vector getChildren() { Vector ret = new Vector(); for(Field f : this.getFields()){ ret.add(f); } return ret; } @Override public boolean equals(Object obj){ if(!(obj instanceof Class))return false; Class cl = (Class) obj; if(!(cl.getName().equals(this.getName())))return false; return true; } @Override public Iterable getGenericParameter() { if(this.genericClassParameters == null)return new Vector(); return this.genericClassParameters; } @Override public String getDescription(){ return "class "+this.getName(); } @Override public int getVariableLength() { // TODO Auto-generated method stub return 0; } @Override public void setGenericParameter(GenericDeclarationList params) { this.genericClassParameters = params; } @Override public String getGenericVarDeclarationString(String genericVarDeclaration) { if(this.genericClassParameters != null){ return ", "+genericVarDeclaration; }else{ return "<"+genericVarDeclaration+">"; } } @Override public int getGenericVarDeclarationOffset(){ // Falls Generische Parameterliste vorhanden, hier Wert der Liste zurückgegebn if(this.genericClassParameters != null){ return this.genericClassParameters.getOffsetOfLastElement(); }else{ return this.offset; } } } // ino.end