JavaPatternMatching/src/mycompiler/myclass/Class.java

1658 lines
64 KiB
Java
Raw Normal View History

2013-10-18 11:33:46 +00:00
// 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.CTypeReconstructionResult;
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.TypeAssumptions;
import typinferenz.TypinferenzException;
import typinferenz.UndConstraint;
// 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<Type> paralist = new Vector<Type>(); // Parameterliste 'class xy<para1, para2,...>{}' wird gespeichert
// ino.end
// ino.attribute.parahash.23026.declaration
private Hashtable<String,String> parahash = new Hashtable<String,String>(); // 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<GenericTypeVar> genericClassParameters=new Vector<GenericTypeVar>();
// 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<Type> containedTypes = new Vector<Type>();
// ino.end
// ino.attribute.usedIdsToCheck.23035.declaration
private Vector<UsedId> usedIdsToCheck = new Vector<UsedId>();
// ino.end
private TypeAssumptions typeAssumptions = null;//muss mit null Initialisiert werden. Darf nur <20>ber getTypeAssumptions abgerufen werden.
private Vector<Method> 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<Type> ct, Vector<UsedId> usedIdsToCheck,
UsedId superclass, Vector<UsedId> superif, Vector<Type> 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<UsedId> getUsedIdsToCheck()
// ino.end
// ino.method.getUsedIdsToCheck.23050.body
{
return usedIdsToCheck;
}
// ino.end
// ino.method.setContainedTypes.23053.definition
public void setContainedTypes(Vector<Type> containedTypes)
// ino.end
// ino.method.setContainedTypes.23053.body
{
this.containedTypes = containedTypes;
}
// ino.end
// ino.method.getContainedTypes.23056.definition
public Vector<Type> getContainedTypes()
// ino.end
// ino.method.getContainedTypes.23056.body
{
return containedTypes;
}
// ino.end
// ino.method.para_check.23059.definition
public void para_check(Vector<Class> classlist, boolean ext)
throws SCClassException
// ino.end
// ino.method.para_check.23059.body
{
//pr<70>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<SCExcept> v = new Vector<SCExcept>();
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<74>lt alle definierten Klassen) durchgehen
for ( Enumeration<Class> 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<SCExcept> v = new Vector<SCExcept>();
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<EFBFBD>ngenpr<EFBFBD>fung von Basis- u. Superkl. tempor<6F>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<74>ge der Basisklasse erg<72>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<Type> complete_paralist(boolean ext)
// ino.end
// ino.method.complete_paralist.23062.body
{
//Diese Funktion vervollt<6C>ndigt die Parameterliste f<>r vererbte Klassen
Vector<Type> child = paralist;
paralist = (Vector<Type>)superclassid.get_ParaList();
for(Enumeration<Type> e = child.elements();e.hasMoreElements();){
paralist.addElement(e.nextElement());
}
return this.paralist;
}
// ino.end
// ino.method.sc_check.23065.definition
public void sc_check(Vector<Class> classlist, boolean ext)
throws SCClassException
// ino.end
// ino.method.sc_check.23065.body
{
// Der normale Semantik-Check - Aufgabe: Initialisierung der Class-Hashtable und Aufruf des Semantik-Checks
// otth: Diese Funktion wird f<>r alle Objekte vom Typ 'Class`,
// otth: die im Vector Sourcefile.classes gespeichert sind, im Sourcefile aufgerufen.
// PARAMETRISIERTE TYPEN
try
{
para_check(classlist,ext);
}
catch(SCClassException ex)
{
throw ex;
}
// Initialisierung der Hash-Tabelle!
// erbt die Klasse von einer anderen???
String strSuperKlassenName = null;
if( superclassid != null )
{
Vector superclass = superclassid.get_Name(); // 'superclass'-nur ein Element, da in Java keine Mehrfachver.
for( Enumeration el = superclass.elements(); el.hasMoreElements(); )
{
strSuperKlassenName = (String) el.nextElement();
}
}
// Hash-Tabelle aufrufen!
try
{
body.sc_init_hashtable( classlist, strSuperKlassenName, getName(), ext );
}
catch (SCClassBodyException ex)
{
SCClassException except = new SCClassException();
except.addException(ex.get_exlist());
except.addClassname(getName());
throw except;
}
// Semantik-Check aufrufen
try
{
body.sc_check( classlist,ext );
}
catch (SCClassBodyException ex)
{
SCClassException except = new SCClassException();
except.addException( ex.get_exlist() );
except.addClassname( getName() );
throw except;
}
}
// ino.end
// ino.method.sc_check_for_extended_classes.23068.definition
public void sc_check_for_extended_classes(Vector<Class> classlist, Hashtable<String,String> 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 <20>bergegeben Hashtable childhash sollen
// die geerbten Funktionen und Methoden mit ihren zugeh<65>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("<init>", "()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<Type> 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<String,String> hash)
// ino.end
// ino.method.set_ParaHash.23104.body
{
this.parahash = hash;
}
// ino.end
// ino.method.get_ParaHash.23107.definition
public Hashtable<String,String> 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<EFBFBD>r den Typrekonstruktionsalgorithmus. Hier werden zun<EFBFBD>chst
* die Mengen von Typannahmen V_fields_methods und V_i erstellt, die als Eingabe
* f<EFBFBD>r den Algorithmus dienen.<br/>
* (siehe Algorithmus 5.17 TRProg, Martin Pl<EFBFBD>micke)
* <br/>Author: J<EFBFBD>rg B<EFBFBD>uerle
* @param supportData
* @param globalAssumptions
* @return Liste aller bisher berechneten, m<EFBFBD>glichen Typkombinationen
* @throws CTypeReconstructionException
*/
// ino.end
// ino.method.TRProg.23110.definition
public Vector<CTypeReconstructionResult> 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<Expr> fieldInitializers = new Vector<Expr>();
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<Vector<Pair>> xConstraints = new Vector<Vector<Pair>>();// = oderConstraints.getConstraints();
for(Vector<UndConstraint> uC:oderConstraints.getConstraints()){ //mit dem getConstraints-Aufruf wird das Karthesische Produkt erzeugt.
Vector<Pair> cons = new Vector<Pair>();
for(UndConstraint undCons:uC){
cons.addAll(undCons.getConstraintPairs());
}
xConstraints.add(cons);
}
typinferenzLog.debug("Karthesisches Produkt der Constraints: "+xConstraints);
//////////////////////////////
// Unifizierung der Constraints:
//////////////////////////////
Vector<CTypeReconstructionResult> ret = new Vector<CTypeReconstructionResult>(); //Generiere das Result-Set
for(Vector<Pair> constraints : xConstraints){
//Alle durch das Karthesische Produkt entstandenen M<>glichkeiten durchgehen:
Vector<Vector<Pair>> result = new Vector<Vector<Pair>>();
//Erst die Unifizierung erstellen:
result.addAll(Unify.unify(constraints, supportData.getFiniteClosure()));
// Debugoutput:Vector<Vector<Pair>>
typinferenzLog.debug("Unifiziertes Ergebnis: "+result);
/*
// Pr<50>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<Pair>())));
//Der Unifikationsalgorithmus kann wiederum auch mehrere L<>sungen errechnen, diese werden im folgenden durchlaufen:
for(Vector<Pair> resultSet : result){
//Add Result set as a new ReconstructionResult to ret:
CTypeReconstructionResult reconstructionResult = new CTypeReconstructionResult(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<75>ck in TRProg().");
//////////////////////////////
// Neu Ergebnismenge A aller
// Typannahmen erzeugen:
//////////////////////////////
inferencelog.debug("Erstelle Ergebnismenge...");
Vector<CTypeReconstructionResult> newA = new Vector<CTypeReconstructionResult>();
// Alle bisherigen M<>glichkeiten an Typkombinationen durchgehen:
Vector<CTypeReconstructionResult> oldA = supportData.getA();
for(int i=0; i<oldA.size(); i++){
CTypeReconstructionResult oneReconResult = oldA.elementAt(i);
// Und mit den neuen m<>glichen Typkombinationen vereinigen:
Iterator<CReconstructionTuple> 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<GenericTypeVar> genericsList = new Vector<GenericTypeVar>();
for(int ii =0; ii<this.get_ParaList().size(); ii++){
Type para = (Type)this.get_ParaList().elementAt(ii);
if(para instanceof GenericTypeVar){
genericsList.addElement((GenericTypeVar)para);
}
}
newReconResult.addGenericTypeVars(this.getName(), genericsList);
//Hinzuf<75>gen:
newA.addElement(newReconResult);
}
}
return newA;
*/
}
// ino.end
/**
* @return Eine Liste mit allen Methoden dieser Klasse
*/
private Vector<Method> getMethodList() {
if(this.methodList != null) return this.methodList;
//TODO: Unn<6E>tige Berechnungen im folgenden Code rausk<73>rzen:
//////////////////////////////
// Die Eingabedaten bauen:
//////////////////////////////
inferencelog.debug("Baue Eingabedaten...");
TypeAssumptions V_fields_methods = new TypeAssumptions(this.getName());
Vector<Method> methodList = new Vector<Method>();
Vector<CTypeAssumptionSet> V = new Vector<CTypeAssumptionSet>();
Vector<CTypeAssumption> rememberLocals = new Vector<CTypeAssumption>();
//////////////////////////////
// Alle Felder durchgehen:
// Zuerst alle Attribute, dann Methoden
// ge<67>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<instVar.getDeclIdVector().size(); i++){
DeclId id = (DeclId)instVar.getDeclIdVector().elementAt(i);
CInstVarTypeAssumption assum = new CInstVarTypeAssumption(this.getName(), id.get_Name(), instVar.getType(), instVar.getLineNumber(),instVar.getOffset(),new Vector<Integer>()); // Typannahme bauen...
V_fields_methods.add(assum); // ...und hinzuf<75>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("<init>");
}
//hoth: 06.04.2006
//durchlaufe Block und suche nach Objektvariablen fuer Offset-Markierung
Iterator<CTypeAssumption> 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<Integer>(),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<parameterList.sc_get_Formalparalist().size(); i++){
FormalParameter para = parameterList.sc_get_Formalparalist().elementAt(i);
// F<>r V_fields_methods:
CParaTypeAssumption paraAssum = new CParaTypeAssumption(this.getName(), method.get_Method_Name(), method.getParameterCount(), method.getOverloadedID(),para.get_Name(), para.getType(), para.getLineNumber(),para.getOffset(),new Vector<Integer>());
//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<Integer>());
localAssum.addElement(varAssum);
rememberLocals.addElement(varAssum);
}
}
// ...und hinzuf<75>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<EFBFBD>r diese.
* @return Die erstellten TypeAssumptions
*/
private TypeAssumptions getTypeAssumptions() {
if(this.typeAssumptions != null)return this.typeAssumptions; //Das sorgt daf<61>r, dass die Assumptions nur einmalig generiert werden.
TypeAssumptions assumptions = new TypeAssumptions(this.getName());
this.getMethodList(); //Diese Funktion muss zuerst ausgef<65>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<65>gt, da es momentan keine statischen Klassen gibt)
if(assumptions.getMethodAssumptions(this.getName(), "<init>").size()==0){ //Falls kein Konstruktor f<>r diese Klasse definiert wurde:
assumptions.addMethodAssumption(new RefType(this.getName(),0), "<init>", new RefType(this.getName(),0), new Vector<CParaTypeAssumption>());
}
typinferenzLog.debug("Erstellte Assumptions: "+assumptions);
this.typeAssumptions = assumptions; //Diese m<>ssen anschlie<69>end nicht wieder generiert werden.
return assumptions;
}
public ConstraintsSet TYPE(Vector<Method> methodList, Vector<Expr> fielddeclarationList, TypeAssumptions assumptions){
ConstraintsSet ret = new ConstraintsSet();
// Die Felddeklarationen werden zu den Assumptions hinzugef<65>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<EFBFBD>r lokale Variablen, die f<EFBFBD>r Methodenparameter erzeugt
* worden sind. (siehe Algorithmus 5.17 TRProg, Martin Pl<EFBFBD>micke)
* <br/>Author: J<EFBFBD>rg B<EFBFBD>uerle
* @param V
* @param locals
*/
// ino.end
// ino.method.clear.23113.definition
void clear(CTypeAssumptionSet V, Vector<CTypeAssumption> locals)
// ino.end
// ino.method.clear.23113.body
{
Iterator<CTypeAssumption> 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.TRStart.23116.defdescription type=javadoc
/**
* Zentrale Methode des Typrekonstruktionsalgorithmus zur Steuerung des Ablaufs
* zwischen den einzelnen Methoden und Konstruktion der Ergebnismengen.<br/>
* (siehe Algorithmus 5.18 TRStart, Martin Pl<EFBFBD>micke)
* <br/>Author: J<EFBFBD>rg B<EFBFBD>uerle
* @param methodList
* @param V
* @param V_fields_methods
* @param supportData
* @return Menge aller neu berechneter, m<EFBFBD>glichen Typkombinationen in Form von
* 2-Tupeln aus einer Menge von Unifiern und einer Menge von Typannahmen ==>
* (sigma, V)
* @throws CTypeReconstructionException
*/
// ino.end
// ino.method.TRStart.23116.definition
private CReconstructionTupleSet TRStart(Vector<Method> methodList, Vector<CTypeAssumptionSet> V, CTypeAssumptionSet V_fields_methods, CSupportData supportData)
throws CTypeReconstructionException
// ino.end
// ino.method.TRStart.23116.body
{
// --------------------------
// Startdaten vorbereiten:
// --------------------------
inferencelog.debug("Bereite Startdaten vor...");
V.insertElementAt(new CTypeAssumptionSet(), 0); // V_0
CReconstructionTupleSet ret = new CReconstructionTupleSet(); // ret_0
ret.addElement(new CReconstructionTuple(new CSubstitutionSet(), V_fields_methods));
// --------------------------
// Alle n Methoden durchgehen:
// --------------------------
for(int i=1; i<methodList.size()+1; i++){
Method currentMethod = methodList.elementAt(i-1);
// --------------------------
// TRNextMeth rufen:
// --------------------------
inferencelog.debug("Rufe TRNextMeth f<>r Methode \""+currentMethod.get_Method_Name()+"()\"");
CTripleSet triples = this.TRNextMeth(V.elementAt(i-1), V.elementAt(i), ret, currentMethod, supportData);
inferencelog.debug("Bin zur<75>ck in TRStart().");
ret = new CReconstructionTupleSet();
// --------------------------
// Alle m Triple durchgehen:
// --------------------------
inferencelog.debug("Durchlaufe Menge der Ergebnis-Triple...");
Iterator<CTriple> it = triples.getIterator();
// HOTI 14.5.06
// HadAChance gibt an, ob <20>berhaupt eine Typannahme vom Inferieren zur<75>ckkam
// Wenn false, dann ausgeben, dass keine zur<75>ck kam
// Wenn true, nachschauen, ob diese Typannahme(n) mit dem Returntyp unifizierbar sind!
// Die unifizierbaren z<>hlt successfulls
// Wenn successfulls nachher==0 ausgeben, dass kein Returntyp passt. Ansonsten ist alles o.k.
boolean hadAChance=it.hasNext();
int successfulls=0;
Vector<CTypeReconstructionException> exceptions=new Vector<CTypeReconstructionException>();
while(it.hasNext()){
CTriple triple = it.next();
// --------------------------
// Typannahme f<>r R<>ckgabewert der Methode extrahieren:
// --------------------------
CTypeAssumptionSet V_j = triple.getAssumptionSet();
Type theta = this.RetType(currentMethod, V_j);
// --------------------------
// Extrahierte Typannahme mit zur<75>ckgelieferter Typannahme
// des Blocks unifizieren:
// --------------------------
inferencelog.debug("Rufe Unify() f<>r ReturnType...");
Iterator<Vector<Pair>> unifierPossibilities = Unify.unify(triple.getResultType(), theta, supportData.getFiniteClosure()).iterator();
inferencelog.debug("Wende Unifier an...");
CReconstructionTuple resultTuple = null;
// --------------------------
// Wenn Unifier vorhanden, dann anwenden:
// --------------------------
if(unifierPossibilities.hasNext()){
// --------------------------
// Alle m<>glichen Unifier auf V_j anwenden:
// --------------------------
successfulls++;
while(unifierPossibilities.hasNext()){
CSubstitutionSet unifier = new CSubstitutionSet(unifierPossibilities.next());
// --------------------------
// Typannahmen bauen:
// --------------------------
CTypeAssumptionSet V_j_substituted = V_j.deepCopy();
V_j_substituted.sub(unifier);
// --------------------------
// Substitutionen bauen:
// --------------------------
CSubstitutionSet substSet = triple.getSubstitutions().deepCopy();
substSet.applyUnifier(unifier);
substSet.unite(unifier);
// --------------------------
resultTuple = new CReconstructionTuple(substSet, V_j_substituted);
// --------------------------
// Tuple zu R<>ckgabemenge hinzuf<75>gen
// (entspricht der Vereinigung in Algorithmus 5.18, Martin Pl<50>micke):
// --------------------------
inferencelog.warn("##########################################");
inferencelog.warn("F<EFBFBD>ge neues passendes Ergebnis-Tuple hinzu:");
inferencelog.warn("##########################################");
inferencelog.warn(resultTuple.toString());
inferencelog.warn("##########################################\n");
ret.addElement(resultTuple);
}
}
// --------------------------
// Ansonsten ohne Unifier hinzuf<75>gen:
// --------------------------
else{
exceptions.addElement(new CTypeReconstructionException("Der berechnete Return-Typ("+triple.getResultType()+") laesst sich nicht mit dem Return-Typ der Methode ("+this.RetType(currentMethod, V_j)+") unifizieren.",currentMethod));
//resultTuple = new CReconstructionTuple(triple.getSubstitutions(), V_j);
//inferencelog.warn("");
//inferencelog.warn("#########################################");
//inferencelog.warn("Fuege neues unpassendes Ergebnis-Tuple hinzu:");
//inferencelog.warn("##########################################");
//inferencelog.warn(resultTuple.toString());
//inferencelog.warn("##########################################\n");
//ret.addElement(resultTuple);
}
}
if(hadAChance && successfulls==0 && exceptions.size()>0) {
if(exceptions.size()==1){
throw exceptions.elementAt(0);
}
throw new CTypeReconstructionException("Die berechneten Return-Typen lassen sich nicht mit dem Return-Typ der Methode unifizieren.",exceptions,currentMethod);
}
// --------------------------
// TupleSet "ret" geht als Eingabewert bzw. Vorkenntnis
// in den n<>chsten Schleifendurchlauf, d.h. in TRNextMeth
// f<>r die n<>chste Methode, ein...
// --------------------------
}
// --------------------------
// Nach dem letzten Schleifendurchlauf
// TupleSet "ret" als Ergebnis zur<75>ckgeben:
// --------------------------
for(int i=0;i<ret.getCardinality();i++){
CReconstructionTuple tuple=ret.getVector().elementAt(i);
CTypeAssumptionSet V_j_substituted=tuple.getAssumSet();
// HOTI 25.5.06
// Suche nach nicht erkannten TypePlaceholdern in den Parametern
// und R<>ckgabewerten der Methoden
Hashtable<TypePlaceholder, CMethodTypeAssumption> typePlaceholderHasMethod=new Hashtable<TypePlaceholder, CMethodTypeAssumption>();
Vector<TypePlaceholder> tphs=new Vector<TypePlaceholder>();
Hashtable<IHashSetKey, CTypeAssumption> data = V_j_substituted.getHashtable();
Collection<CTypeAssumption> values=data.values();
Iterator<CTypeAssumption> myit=values.iterator();
while(myit.hasNext()){
CTypeAssumption myassum=myit.next();
if(myassum instanceof CMethodTypeAssumption){
CMethodTypeAssumption mAssum=(CMethodTypeAssumption)myassum;
Type aT=mAssum.getAssumedType();
if(aT instanceof TypePlaceholder && !tphs.contains(aT)){
tphs.addElement((TypePlaceholder)aT);
typePlaceholderHasMethod.put((TypePlaceholder)aT,mAssum);
}
Vector<CParaTypeAssumption> paras=mAssum.getParaAssumptions();
if(paras!=null){
for(int j=0;j<paras.size();j++){
Type pT=paras.elementAt(j).getAssumedType();
if(pT instanceof TypePlaceholder && !tphs.contains(pT)){
tphs.addElement((TypePlaceholder)pT);
typePlaceholderHasMethod.put((TypePlaceholder)pT,mAssum);
}
}
}
}
}
// Mache diese zu MethodenGenerics
CSubstitutionSet sub = new CSubstitutionSet();
for(int j=0;j<tphs.size();j++){
TypePlaceholder var=tphs.elementAt(j);
GenericTypeVar gtv=new GenericTypeVar(TypePlaceholder.fresh().getName(),-1);
CMethodTypeAssumption meth=typePlaceholderHasMethod.get(var);
if(meth!=null){
sub.addElement(new CSubstitution(var,gtv));
meth.getGenericMethodParameters().addElement(gtv);
}
}
V_j_substituted.sub(sub);
}
return ret;
}
// ino.end
// ino.method.RetType.23119.defdescription type=javadoc
/**
* Liefert den berechneten R<EFBFBD>ckgabetyp f<EFBFBD>r die <EFBFBD>bergebene Methode zur<EFBFBD>ck.<br/>
* (siehe Algorithmus RetType, Martin Pl<EFBFBD>micke)
* <br/>Author: J<EFBFBD>rg B<EFBFBD>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.TRNextMeth.23122.defdescription type=javadoc
/**
* Erweitert die bisherigen Teilergebnisse um weitere Informationen aus dem
* <EFBFBD>bergebenen Block der aktuellen Methode.<br/>
* (siehe Algorithmus TRNextMeth, Martin Pl<EFBFBD>micke)
* <br/>Author: J<EFBFBD>rg B<EFBFBD>uerle
* @param V_last
* @param V_next
* @param tupleSet
* @param nextMethod
* @param supportData
* @return
* @throws CTypeReconstructionException
*/
// ino.end
// ino.method.TRNextMeth.23122.definition
private CTripleSet TRNextMeth(CTypeAssumptionSet V_last, CTypeAssumptionSet V_next, CReconstructionTupleSet tupleSet, Method nextMethod, CSupportData supportData)
throws CTypeReconstructionException
// ino.end
// ino.method.TRNextMeth.23122.body
{
Block Bl = nextMethod.get_Block();
CTripleSet returnSet = new CTripleSet();
// --------------------------
// Alle Tupel durchgehen:
// --------------------------
Vector<CTypeReconstructionException> exceptions=new Vector<CTypeReconstructionException>();
int successfulls=0;
Iterator<CReconstructionTuple> tuples = tupleSet.getIterator();
while(tuples.hasNext()){
CReconstructionTuple currentTuple = tuples.next();
CTypeAssumptionSet V_i = currentTuple.getAssumSet().shallowCopy();
CSubstitutionSet sigma_i = currentTuple.getSubSet().shallowCopy();
V_next = V_next.deepCopy();
V_next.sub(sigma_i);
//this.removeOldLocalVars(V_i, V_last); // Wird ganz am Ende <20>ber clear() in TRProg() gemacht --> hier nicht mehr n<>tig
V_i.unite(V_next);
supportData.setCurrentMethod(nextMethod.get_Method_Name());
supportData.setCurrentMethodParaCount(nextMethod.getParameterCount());
supportData.setCurrentMethodOverloadedID(nextMethod.getOverloadedID());
supportData.resetBlockId();
try{
CTripleSet tripleSet = Bl.TRStatement(sigma_i, V_i, supportData);
returnSet.unite(tripleSet);
successfulls++;
}catch(CTypeReconstructionException tre){
exceptions.addElement(tre);
}
}
if(successfulls==0&& exceptions.size()>0){
if(exceptions.size()==1){
throw exceptions.elementAt(0);
}
throw new CTypeReconstructionException("Class: Es konnte keine Assumption gefunden werden, die auf die Anforderung passt.",exceptions,null);
}
return returnSet;
}
// ino.end
// ino.method.toString.23125.defdescription type=javadoc
/**
* <br/>Author: Martin Pl<EFBFBD>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 <EFBFBD>berpr<EFBFBD>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<fieldsAndMethods.size();i++){
// Ist es eine Methode?
if(fieldsAndMethods.get(i) instanceof Method){
Method method=(Method)fieldsAndMethods.get(i);
method.wandleRefTypeAttributes2GenericAttributes(paralist);
}// Ist es eine InstanzVariable?
else if(fieldsAndMethods.get(i) instanceof InstVarDecl){
InstVarDecl instVar=(InstVarDecl)fieldsAndMethods.get(i);
Type type=instVar.getType();
// Nur wenn es sich um ein RefType-Field handelt
if(type instanceof RefType){
GenericTypeVar pendant=ClassHelper.findGenericType((RefType)type,paralist,null);
if(pendant!=null){ //Wenn generisch, dann modifizieren
instVar.setType(pendant);
}
}
}
}
}
// ino.end
// private void removeOldLocalVars(CTypeAssumptionSet V_i, CTypeAssumptionSet V_last){
// Enumeration<IHashSetKey> 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<EFBFBD>gt zu einer CTypeAssumption alle
* Offsets hinzu, wo die Variable benutzt wird.
* <br/>Author: Thomas Hornberger 07.04.2006
* <br/>Author: Arne L<EFBFBD>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<EFBFBD>r die Offset-Zuweisung
* durchsucht ein Statement rekursiv
* <br/>Author: Thomas Hornberger 08.04.2006
* <br/>Author: Arne L<EFBFBD>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<EFBFBD>r die Offset-Zuweisung
* durchsucht eine Expression rekursiv
* <br/>Author: Thomas Hornberger 07.04.2006
* <br/>Authos: Arne L<EFBFBD>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<Method> methodList, Vector<Expr> 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<EFBFBD>r das <EFBFBD>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(CTypeReconstructionResult 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<GenericTypeVar> 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<EFBFBD>r diese Klasse.
* Die berechneten Variablen werden anschlie<EFBFBD>end in die this.genericTypeVars eingesetzt. Dabei werden alte genericTypeVars <EFBFBD>berschrieben.
* @param tphs : Alle <EFBFBD>briggebliebenen TypePLaceholder
*/
public void createGenericTypeVars(Vector<TypePlaceholder> tphs){
this.genericClassParameters = new Vector<GenericTypeVar>();
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<EFBFBD>r diese Klasse.
* Die berechneten Variablen werden anschlie<EFBFBD>end in die this.genericTypeVars eingesetzt. Dabei werden alte genericTypeVars <EFBFBD>berschrieben.
* @param reconstructionResult
*/
public void createGenericTypeVars(CTypeReconstructionResult reconstructionResult){
this.genericClassParameters = new Vector<GenericTypeVar>();
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 <20>berpr<70>fen:
ArrayList<SuperWildcardType> 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