JavaPatternMatching/src/mycompiler/myclass/ClassBody.java

757 lines
27 KiB
Java
Raw Normal View History

2013-10-18 11:33:46 +00:00
// ino.module.ClassBody.8554.package
package mycompiler.myclass;
// ino.end
// ino.module.ClassBody.8554.import
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import mycompiler.mybytecode.ClassFile;
import mycompiler.myexception.JVMCodeException;
import mycompiler.myexception.SCClassBodyException;
import mycompiler.myexception.SCExcept;
import mycompiler.myexception.SCMethodException;
import mycompiler.mytype.RefType;
import mycompiler.mytype.Type;
import org.apache.log4j.Logger;
// ino.end
import typinferenz.JavaCodeResult;
import typinferenz.ResultSet;
// ino.class.ClassBody.23143.declaration
public class ClassBody
// ino.end
// ino.class.ClassBody.23143.body
{
// ino.attribute.fielddecl.23146.declaration
private Vector<FieldDecl> fielddecl = new Vector<FieldDecl>();
// ino.end
// ino.attribute.hash.23149.declaration
private Hashtable<String,String> hash = new Hashtable<String,String>(); // otth: Speichert folgende Paare: <Identifier> --> <Type>
// ino.end
// ino.attribute.paraclasshash.23152.declaration
private Hashtable paraclasshash = new Hashtable();
// ino.end
// ino.attribute.kill.23155.declaration
public Hashtable<Type,Type> kill = new Hashtable<Type,Type>();
// ino.end
// ino.attribute.parserlog.23158.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
// ino.method.sc_init_hashtable.23161.definition
public void sc_init_hashtable( Vector<Class> KlassenVektor, String strSuperKlassenName, String classname, boolean ext )
throws SCClassBodyException
// ino.end
// ino.method.sc_init_hashtable.23161.body
{
// Methoden und Vardeclarationen werden in die Hashtabelle eingefuegt
// KlassenVektor: Vektor mit allen Klassen im Sourcefile
// strSuperKlassenName: Name der Superklasse, Klasse ohne Vererbung <--> strSuperKlassenName = null
SCClassBodyException ex = null;
// otth: Vektor mit den Felddeklarationen durchgehen und Hashtabelle f<>r Felddeklarationen aufbauen
for( Enumeration<FieldDecl> el = fielddecl.elements(); el.hasMoreElements(); )
{
FieldDecl field = el.nextElement(); // Felddeklaration, also Instanzvariable oder Mehtode
Vector v = field.get_Name(); // verschiedene DeclId's, f<>r int a, b, c z.B 3
DeclId hilf;
Method init;
String name; // enth<74>lt den Namen des Identifiers, also ein Instanzvariablenname oder ein Methodennamen
// otth: bei Funktionen: Parameterliste erstellen!
if( field instanceof Method )
{
init=(Method) field;
init.sc_init_parameterlist(ext);
}
// otth: Vektor einer Felddeklaration mit ver. DeclIds durchgehen -
// otth: hier wird z.B. folgende Liste durchlaufen: a, b, c bei int a, b, c;
for ( Enumeration el1 = v.elements(); el1.hasMoreElements(); )
{
hilf = (DeclId)el1.nextElement();
name = hilf.get_Name();
// otth: pr<70>fen, ob Identifier bereits vorhanden ???
if( hash.containsKey( name ) )
{
parserlog.error("SEMANTIK-CHECK-Fehler: '" + name + "' ist bereits definiert!\n");
//FIXME Throw Exception or Error instead of simple exit the program
System.exit(1);
/* otth: Wenn dieser Code vorhanden ist, wird ... int a; int a; akkzeptiert!
String typedervar;
typedervar = (String)hash.get(name);
if ( !typedervar.equals(field.get_Type()) )
// otth: abstrakte Methode, z.B. von InstVarDecl gibt den Typ zur<75>ck
{
SCExcept neu=new SCExcept();
neu.set_error("Es kann nicht noch eine Variable mit dem Namen "+name+" angelegt werden.");
neu.set_statement("ClassBody");
if(ex==null)
{
System.out.println("neue classbodyexception anlegen");
ex=new SCClassBodyException();
}
ex.addException(neu);
if(ext)
System.out.println("Exception wurde angelegt!");
continue;
}
*/
}
// otth: Aufnahme in die Hash-Tabelle!
// otth: Typen pr<70>fen, field.get_Type() z.B. = int oder void, bei null --> Konstruktor
if( field.getTypeName() == null )
hash.put(name,"__CONSTRUCTOR__");
else
hash.put(name, field.getTypeName()); // Name & Typ, z.B. "a" --> "int"
} // Ende: Schleife <20>ber alle Feldvariablendeklarationen
}
// otth: Klassenname in Hash-Tabelle einfuegen
hash.put("###_classname", classname);
// otth: Ist Klasse eine Subklasse?
if( strSuperKlassenName != null ) // 'strSuperKlassenName' = <20>bergebener Parameter von 'Class'
{
Class tempKlasse;
String strTempKlassenName;
hash.put( "###_class_is_extended", "yes" );
// otth: Basisklasse wird im Vektor aller Klassen 'KlassenVektor` gesucht!
// <20>nderung von otth: Falls Klasse nicht gefunden wurde --> Superklasse ist undefiniert --> Fehler!
boolean bSuperKlasseGefunden = false;
for ( Enumeration<Class> el2 = KlassenVektor.elements(); el2.hasMoreElements(); )
{
tempKlasse = el2.nextElement();
strTempKlassenName = tempKlasse.getName();
if( strTempKlassenName.equals( strSuperKlassenName ) )
{
// otth: Die Hashtabelle wird um die Attribute / Methoden der Superklasse(n) ergaenzt
// otth: Funktion 'ClassBody.sc_init_hashtable_for_extended_classes' wird (indirekt) aufgerufen
bSuperKlasseGefunden = true;
tempKlasse.sc_check_for_extended_classes( KlassenVektor, hash, ext );
}
}
// otth: Superklasse mu<6D> existieren
if ( !bSuperKlasseGefunden )
{
parserlog.error("SEMANTIK-CHECK-Fehler [otth]: Symbol '" + strSuperKlassenName + "' kann nicht aufgel<65>st werden (Location: class " + classname + ").\n" );
System.exit( 1 );
}
}
// Fehler erkennen und werfen!!!
if( ex != null )
{
parserlog.error("SEMANTIK-CHECK-Fehler: Fehler beim Aufbau der Hash-Tabelle!");
throw ex;
}
// Ersetzen von vordefinierten Parametern bei der Vererbung
if( this.kill.size() > 0 )
{
for(Enumeration e1=this.kill.elements(),e2=this.kill.keys();e1.hasMoreElements();){
Type value = (Type)e1.nextElement(), key=(Type)e2.nextElement();
for(Enumeration e3=hash.elements(),e4=hash.keys();e3.hasMoreElements();){
String v = (String)e3.nextElement(),k=(String)e4.nextElement();
if(v.equals(key.getName())){
parserlog.debug(v+ " wird durch "+value.getName()+" ersetzt");
hash.put(k,value.getName());
}
}
}
}
parserlog.debug( "SC --> '" + classname + "' --> Hashtabelle (ClassBody.hash):\n" + hash);
}
// ino.end
// ino.method.sc_init_hashtable_for_extended_classes.23164.definition
public void sc_init_hashtable_for_extended_classes( Vector<Class> classlist, String strSuperKlassenName, Hashtable<String,String> childhash,Vector paralist, Hashtable parahash,Hashtable kill, boolean ext )
// ino.end
// ino.method.sc_init_hashtable_for_extended_classes.23164.body
{
// Hier werden in die <20>bergegebene Hashtable die Attribute und Methoden ergaenzt, die vererbt werden.
// otth: Struktur <20>hnlich wie in 'sc_init_hashtable'
for( Enumeration<FieldDecl> el = fielddecl.elements(); el.hasMoreElements(); )
{
FieldDecl field = el.nextElement();
Vector v = field.get_Name();
DeclId hilf;
String name;
// Hashtabelle erg<72>nzen
for ( Enumeration el1 = v.elements(); el1.hasMoreElements(); )
{
hilf=(DeclId)el1.nextElement();
name=hilf.get_Name();
if(field.getTypeName()==null)
childhash.put(name,"__Constructor__"); //Name & Typ
else
{
//string_rec("paralist: ", paralist);System.out.println();
childhash.put(name, field.getTypeName());
}
}
}
// Sollte die Basis-Klasse zus<75>tzlich erben muss folgendes getan werden:
if( strSuperKlassenName != null )
{
Class hilfe;
String hilfsstr;
for ( Enumeration<Class> el2=classlist.elements(); el2.hasMoreElements(); )
{
hilfe=el2.nextElement();
hilfsstr=hilfe.getName();
if( hilfsstr.equals( strSuperKlassenName ) )
hilfe.sc_check_for_extended_classes(classlist,childhash,ext);
}
}
}
// ino.end
// ino.method.init_parahashtable.23170.defdescription type=line
//
// ***NEU*****************************************************************************
//
// ino.end
// ino.method.init_parahashtable.23170.definition
public Hashtable<String,String> init_parahashtable(Vector paralist,boolean ext)
// ino.end
// ino.method.init_parahashtable.23170.body
{
//hier wird die Hashtabelle erzeugt, die s<>mtliche zuordnungen der parametrisierbaren Variablen enth<74>lt.
Hashtable<String,String> parahash = new Hashtable<String,String>();
FieldDecl decl;
for(Enumeration<FieldDecl> e = fielddecl.elements(); e.hasMoreElements();)
{
//Auslesen aller Fielddecl's
decl = e.nextElement();
for(Enumeration el = decl.get_Name().elements(); el.hasMoreElements();)
{ //Auslesen der Vectoren der Fielddecl's
String key, value;
key = ((DeclId)el.nextElement()).get_Name();
value = decl.getTypeName();
if ( value == null ) value = "###CONSTRUCTOR###"; // otth: eingef<65>gt, sonst NULLPOINTEREXCEPTION
parahash.put(key, value);
}
}
// entfernt ung<6E>ltige Eintr<74>ge in der ParaHashtabelle
for(Enumeration e = parahash.elements(), ee=parahash.keys(); e.hasMoreElements();)
{
String para = (String)e.nextElement();
String key = (String)ee.nextElement();
Enumeration e1 = paralist.elements();
do
{
if(e1.hasMoreElements())
{
String typ = ((Type)e1.nextElement()).getName();
if(para.equals(typ))
{
break;
}
}
if(!e1.hasMoreElements())
{
parahash.remove(key);
}
}
while(e1.hasMoreElements());
}
return parahash;
}
// ino.end
// ino.method.complete_parahashtable.23173.defdescription type=block
/* public void set_paratype(Vector classlist, UsedId superclass, Vector
pl,Hashtable ph,boolean ext){ DeclId decl;
FieldDecl field;
System.out.println("++ ParaCheck: Fielddecl's: "+fielddecl.toString());
for(Enumeration e=fielddecl.elements();e.hasMoreElements();){
field = (FieldDecl)e.nextElement();
for(Enumeration e1=field.get_Name().elements();e1.hasMoreElements();){
decl=(DeclId)e1.nextElement();
if(superclass != null){
System.out.println("superclass.get_ParaList: "
+superclass.get_ParaList().toString());
for(Enumeration e2 =
superclass.get_ParaList().elements();e2.hasMoreElements();){
System.out.println("paralist.elements:: "+((Type)e2.nextElement()).get_Type());
}
}
if(decl.get_Paratyp()!=null){
System.out.println("++ ParaCheck: Name:
"+decl.get_Name()+"\tParatyp: "+decl.get_Paratyp()); }
else System.out.println("++ ParaCheck: Name: "+decl.get_Name()+"\tkein
Paratyp gesetzt."); }
}
}
*/
// ino.end
// ino.method.complete_parahashtable.23173.definition
public Hashtable<String,String> complete_parahashtable(Vector<Class> classlist,UsedId superclassid,Hashtable childhash,boolean ext)
throws SCClassBodyException
// ino.end
// ino.method.complete_parahashtable.23173.body
{
// vervolltaendigt die ParaHashtabelle bei Vererbung
Hashtable<String,String> parahash = new Hashtable<String,String>();
String superhilf,superclass = (String)superclassid.get_Name_1Element();
Class supercl;
if(ext)
parserlog.debug("++ Para_check hat Vererbung gefunden!");
for(Enumeration<Class> e=classlist.elements();e.hasMoreElements();)
{
supercl = e.nextElement();
superhilf = supercl.getName();
if(superhilf.equals(superclass))
{
parahash = (Hashtable<String,String>) supercl.get_ParaHash().clone();
// otth: Pruefung: Ist ein Parameter, der keine TypePlaceholder ist
// (also RefType mit [=Typkonstruktor] oder ohne Parameter eine bereits definierte Klasse und
// stimmt die Anzahl der Parameter eines Typkonstruktors mit der zugeh<65>rigen Klassendefinition <20>berein?
// folgende Funktion bricht ab, falls Parameter fehlerhaft
istParameterOK( superclassid.get_ParaList(), classlist );
// end otth;
if(ext){
parserlog.debug(string_rec("++ PC\tParaHash der Basisklasse: ", parahash));
parserlog.debug(string_rec("++ PC\tParaList der Basisklasse: ", supercl.get_ParaList()));
parserlog.debug(string_rec("++ PC\tParaList der cb - klasse: ", superclassid.get_ParaList()));
parserlog.debug(string_rec("++ PC\tchildhash : ", childhash));
}
// falls bei Vererbung ein Parameter bereits festgelegt ist, so wird er hier aus dem ParaList-Vector entfernt
Vector<Type> rm = new Vector<Type>(); /* container f<>r zu entfendende Typen */
for( Enumeration<Class> e2=classlist.elements(); e2.hasMoreElements(); )
{
Class c = e2.nextElement();
for(Enumeration e1=superclassid.get_ParaList().elements();e1.hasMoreElements();)
{
Type t=(Type)e1.nextElement();
if(c.getName().equals(t.getName()))
{
int i = superclassid.get_ParaList().indexOf(t);
// refe ...
if ( t instanceof RefType )
{
if( ((RefType)t).get_ParaList() != null)
{
if( ((RefType)t).get_ParaList().size()>0)
{
/* auf existenz der Parameter pr<70>fen */
for(Enumeration e11 = ((RefType)t).get_ParaList().elements();e11.hasMoreElements();)
{
Type ty = (Type)e11.nextElement();
try
{
is_declared(ty,classlist);
}
catch(SCClassBodyException ex)
{
// otth: auskommentiert, den Parameter muessen nicht unbedingt bereits definierte Klassen sein
// throw ex;
}
}
}
}
}
rm.add(t);
Type removetype = (Type)supercl.get_ParaList().elementAt(i);
kill.put(removetype,t);
for(Enumeration e3=parahash.keys(),e4=parahash.elements();e3.hasMoreElements();)
{
String key = (String)e3.nextElement();
String ele = (String)e4.nextElement();
if(ele.equals(removetype.getName()))
{
parahash.remove(key);
}
}
}
}
}
if(rm.size()>0)
{
for(Enumeration e4 = rm.elements();e4.hasMoreElements();)
{
Type t=(Type)e4.nextElement();
superclassid.get_ParaList().remove(t);
parserlog.debug(string_rec("Typ \""+t.getName()+"\" aus ParaList entfernt! ", superclassid.get_ParaList()));
}
}
}
}
for(Enumeration e=childhash.keys();e.hasMoreElements();){
String key = (String)e.nextElement();
parahash.put(key,(String)childhash.get(key));
}
return parahash;
}
// ino.end
// ino.method.codegen.23176.definition
public void codegen(ClassFile classfile, Vector paralist)
throws JVMCodeException
// ino.end
// ino.method.codegen.23176.body
{
for(int i=0 ; i < fielddecl.size() ; i++)
{
if(this.fielddecl.elementAt(i) instanceof InstVarDecl)
{
((InstVarDecl)this.fielddecl.elementAt(i)).codegen(classfile, paralist);
}
else
{
this.fielddecl.elementAt(i).codegen(classfile, paralist);
}
}
}
// ino.end
// ino.method.get_hash.23179.definition
public Hashtable get_hash()
// ino.end
// ino.method.get_hash.23179.body
{
return hash;
}
// ino.end
// ino.method.get_FieldDeclVector.23182.definition
public Vector<FieldDecl> get_FieldDeclVector()
// ino.end
// ino.method.get_FieldDeclVector.23182.body
{
return fielddecl;
}
// ino.end
// ino.method.set_FieldDecl.23185.definition
public void set_FieldDecl(FieldDecl i)
// ino.end
// ino.method.set_FieldDecl.23185.body
{
fielddecl.addElement(i);
}
// ino.end
// ino.method.is_declared.23188.defdescription type=line
//
// ********************************************************************************************
//
// ino.end
// ino.method.is_declared.23188.definition
public boolean is_declared(Type t, Vector<Class> classlist)
throws SCClassBodyException
// ino.end
// ino.method.is_declared.23188.body
{
boolean flag=false;
for(Enumeration<Class> e = classlist.elements();e.hasMoreElements();)
{
flag = false;
Class c = e.nextElement();
// System.out.println("is_init: vergleiche "+t.get_Type_()+" mit "+c.getName());
if(c.getName().equals(t.getName())){
// System.out.println("Klasse "+t.get_Type()+"im Vector classlist gefunden.");
flag = true;
break;
}
}
if( t instanceof RefType && ((RefType)t).get_ParaList()!=null)
{
if( ((RefType)t).get_ParaList().size() > 0 )
{
for(Enumeration e1 = ((RefType)t).get_ParaList().elements(); e1.hasMoreElements(); )
{
try
{
is_declared((Type)e1.nextElement(),classlist);
}
catch(SCClassBodyException ex)
{
throw ex;
}
}
}
}
if(flag)
return true;
else
{
SCClassBodyException ex = new SCClassBodyException();
SCExcept e = new SCExcept();
e.set_error("unbekannte Klasse "+t.getName()+".");
e.set_function("complete_parahashtable() --> is_declared()");
e.set_statement(t.getName());
ex.addException(e);
throw ex;
}
}
// ino.end
// ino.method.string_rec.23191.definition
static String string_rec(Hashtable ht)
// ino.end
// ino.method.string_rec.23191.body
{
String record=("[");
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("= ");
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!!!!!!");
}
}
record=record.concat("]");
return(record);
}
// ino.end
// ino.method.string_rec.23194.defdescription type=block
/*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);
}*/
// ino.end
// ino.method.string_rec.23194.definition
static String string_rec(String st, Hashtable ht)
// ino.end
// ino.method.string_rec.23194.body
{
String record=(st);
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("= ");
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);
}
}
record=record.concat("]");
return(record);
}
// ino.end
// ino.method.string_rec.23197.definition
static String string_rec(String st,Vector v)
// ino.end
// ino.method.string_rec.23197.body
{
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("}");
return(record);
}
// ino.end
// ino.method.istParameterOK.23200.defdescription type=line
//
// ********************************************************************************************
//
// ino.end
// ino.method.istParameterOK.23200.definition
public void istParameterOK( Vector Parameter, Vector<Class> KlassenVektor )
// ino.end
// ino.method.istParameterOK.23200.body
{
// otth: prueft rekursiv, ob Parameter im Klassenvektor vorkommt, falls RefType, oder ob TypePlaceholder nicht vorkommt
for( int i = 0; i < Parameter.size(); i++)
{
Type TempParameter = (Type)(Parameter.elementAt(i));
// an dieser Stelle: Parametername
if ( TempParameter instanceof RefType )
{
// t im Klassenvektor suchen --> muss deklariert sein
boolean bGefunden = false;
for( int k = 0; k < KlassenVektor.size(); k++)
{
if( KlassenVektor.elementAt(k).getName().equals(((RefType)TempParameter).getTypeName()) )
{
// Namen gleich --> Parameterliste rekursiv pruefen
if( ((RefType)TempParameter).get_ParaList() != null )
{
if( ((RefType)TempParameter).get_ParaList().size() != KlassenVektor.elementAt(k).get_ParaList().size() )
{
parserlog.error( "SEMANTIK-CHECK-FEHLER: Parameteranzahl von\n" + TempParameter.getName() + " stimmt mit der Klassendefinition\n" + KlassenVektor.elementAt(k).getName() + " nicht <20>berein." );
System.exit( 1 );
}
else
{
istParameterOK( ((RefType)TempParameter).get_ParaList(), KlassenVektor );
bGefunden = true;
break;
}
}
else
{
// OK ...
bGefunden = true;
break;
}
}
}
// Parameter wurde nicht gefunden:
if( !bGefunden )
{
parserlog.error( "SEMANTIK-CHECK-FEHLER: Parameter " + TempParameter.getName() + " ist noch nicht als Klasse definiert." );
System.exit( 1 );
}
}
else
{
// Tylose Variablen d<>rfen nicht deklariert sein
for( int k = 0; k < KlassenVektor.size(); k++)
{
if( KlassenVektor.elementAt(k).getName().equals(TempParameter.getName()) )
{
parserlog.error( "SEMANTIK-CHECK-FEHLER: Parameter " + TempParameter.getName() + " ist bereits als Klasse definiert." );
System.exit( 1 );
}
}
// nicht gefunden
}
} // end otth; end if: t = RefType
}
// ino.end
// ino.method.toString.23203.defdescription type=javadoc
/**
* <br/>Author: Martin Pl<EFBFBD>micke
* @return
*/
// ino.end
// ino.method.toString.23203.definition
public String toString()
// ino.end
// ino.method.toString.23203.body
{
return fielddecl.toString();
}
// ino.end
private Vector<FieldInitialization> fieldInitialisations = new Vector<FieldInitialization>();
/**
* @author Andreas Stadelmeier, a10023
* F<EFBFBD>gt der Klasse eine Feldinitialisation hinzu.
* Eine Feldinitialisation steht f<EFBFBD>r eine Felddeklaration mit gleichzeitiger Wertzuweisung
* Beispiel: 'public Feld FeldVar = FeldWert;'
* @param feld
*/
public void addFieldInitialization(FieldInitialization feld) {
this.fieldInitialisations.add(feld);
}
public Vector<FieldInitialization> getFieldInitializations(){
return this.fieldInitialisations;
}
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult("{\n");
for(FieldDecl field : this.fielddecl)ret.attach( field.printJavaCode(resultSet) ).attach( "\n" );
return ret.attach("}\n");
}
}
// ino.end