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 ;
2014-02-09 15:07:31 +00:00
2013-10-18 11:33:46 +00:00
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 ;
2014-02-09 15:07:31 +00:00
import mycompiler.mytypereconstruction.TypeinferenceResultSet ;
2013-10-18 11:33:46 +00:00
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 ;
2014-02-09 15:07:31 +00:00
2013-10-18 11:33:46 +00:00
import org.apache.log4j.Logger ;
// ino.end
2014-02-09 15:07:31 +00:00
2013-10-18 11:33:46 +00:00
import sun.reflect.generics.reflectiveObjects.NotImplementedException ;
import typinferenz.ConstraintsSet ;
import typinferenz.JavaCodeResult ;
import typinferenz.OderConstraint ;
import typinferenz.ResultSet ;
import typinferenz.TypinferenzException ;
import typinferenz.UndConstraint ;
2014-02-05 12:38:34 +00:00
import typinferenz.FunN ;
2014-02-09 15:07:31 +00:00
import typinferenz.assumptions.TypeAssumptions ;
2013-10-18 11:33:46 +00:00
// 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
2014-02-09 15:07:31 +00:00
public Vector < TypeinferenceResultSet > TRProg ( CSupportData supportData , TypeAssumptions globalAssumptions )
2013-10-18 11:33:46 +00:00
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:
//////////////////////////////
2014-02-09 15:07:31 +00:00
Vector < TypeinferenceResultSet > ret = new Vector < TypeinferenceResultSet > ( ) ; //Generiere das Result-Set
2013-10-18 11:33:46 +00:00
for ( Vector < Pair > constraints : xConstraints ) {
//Alle durch das Karthesische Produkt entstandenen M<> glichkeiten durchgehen:
Vector < Vector < Pair > > result = new Vector < Vector < Pair > > ( ) ;
2014-02-05 12:38:34 +00:00
//Alle FunN-Typen werden per clone-methode in RefTypes verwandelt. (Die clone Methode in FunN darf nicht <20> berschrieben werden.
for ( Pair p : constraints ) {
if ( p . TA1 instanceof FunN ) {
p . TA1 = p . TA1 . clone ( ) ;
}
if ( p . TA2 instanceof FunN ) {
p . TA2 = p . TA2 . clone ( ) ;
}
}
2013-10-18 11:33:46 +00:00
//Erst die Unifizierung erstellen:
2014-02-05 12:38:34 +00:00
Vector < Vector < Pair > > unifyResult = Unify . unify ( constraints , supportData . getFiniteClosure ( ) ) ;
//Dann den Ergebnissen anf<6E> gen
result . addAll ( unifyResult ) ;
2013-10-18 11:33:46 +00:00
// 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:
2014-02-09 15:07:31 +00:00
TypeinferenceResultSet reconstructionResult = new TypeinferenceResultSet ( this ) ;
2013-10-18 11:33:46 +00:00
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
* /
2014-02-09 15:07:31 +00:00
public String printJavaCode ( TypeinferenceResultSet reconstructionResult ) {
2013-10-18 11:33:46 +00:00
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
* /
2014-02-09 15:07:31 +00:00
public void createGenericTypeVars ( TypeinferenceResultSet reconstructionResult ) {
2013-10-18 11:33:46 +00:00
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