// 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 = new Vector(); // ino.end // ino.attribute.hash.23149.declaration private Hashtable hash = new Hashtable(); // otth: Speichert folgende Paare: --> // ino.end // ino.attribute.paraclasshash.23152.declaration private Hashtable paraclasshash = new Hashtable(); // ino.end // ino.attribute.kill.23155.declaration public Hashtable kill = new Hashtable(); // 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 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 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�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�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�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�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 �ber alle Feldvariablendeklarationen } // otth: Klassenname in Hash-Tabelle einfuegen hash.put("###_classname", classname); // otth: Ist Klasse eine Subklasse? if( strSuperKlassenName != null ) // 'strSuperKlassenName' = �bergebener Parameter von 'Class' { Class tempKlasse; String strTempKlassenName; hash.put( "###_class_is_extended", "yes" ); // otth: Basisklasse wird im Vektor aller Klassen 'KlassenVektor` gesucht! // �nderung von otth: Falls Klasse nicht gefunden wurde --> Superklasse ist undefiniert --> Fehler! boolean bSuperKlasseGefunden = false; for ( Enumeration 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� existieren if ( !bSuperKlasseGefunden ) { parserlog.error("SEMANTIK-CHECK-Fehler [otth]: Symbol '" + strSuperKlassenName + "' kann nicht aufgel�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 classlist, String strSuperKlassenName, Hashtable 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 �bergegebene Hashtable die Attribute und Methoden ergaenzt, die vererbt werden. // otth: Struktur �hnlich wie in 'sc_init_hashtable' for( Enumeration el = fielddecl.elements(); el.hasMoreElements(); ) { FieldDecl field = el.nextElement(); Vector v = field.get_Name(); DeclId hilf; String name; // Hashtabelle erg�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�tzlich erben muss folgendes getan werden: if( strSuperKlassenName != null ) { Class hilfe; String hilfsstr; for ( Enumeration 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 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�lt. Hashtable parahash = new Hashtable(); FieldDecl decl; for(Enumeration 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�gt, sonst NULLPOINTEREXCEPTION parahash.put(key, value); } } // entfernt ung�ltige Eintr�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 complete_parahashtable(Vector classlist,UsedId superclassid,Hashtable childhash,boolean ext) throws SCClassBodyException // ino.end // ino.method.complete_parahashtable.23173.body { // vervolltaendigt die ParaHashtabelle bei Vererbung Hashtable parahash = new Hashtable(); String superhilf,superclass = (String)superclassid.get_Name_1Element(); Class supercl; if(ext) parserlog.debug("++ Para_check hat Vererbung gefunden!"); for(Enumeration e=classlist.elements();e.hasMoreElements();) { supercl = e.nextElement(); superhilf = supercl.getName(); if(superhilf.equals(superclass)) { parahash = (Hashtable) 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�rigen Klassendefinition �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 rm = new Vector(); /* container f�r zu entfendende Typen */ for( Enumeration 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�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 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 classlist) throws SCClassBodyException // ino.end // ino.method.is_declared.23188.body { boolean flag=false; for(Enumeration 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 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 �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 /** *
Author: Martin Pl�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 fieldInitialisations = new Vector(); /** * @author Andreas Stadelmeier, a10023 * Fügt der Klasse eine Feldinitialisation hinzu. * Eine Feldinitialisation steht für eine Felddeklaration mit gleichzeitiger Wertzuweisung * Beispiel: 'public Feld FeldVar = FeldWert;' * @param feld */ public void addFieldInitialization(FieldInitialization feld) { this.fieldInitialisations.add(feld); } public Vector 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