From bfb00ac1d1d1e1056e892904f528e12fe1de849b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Schr=C3=B6dter?= Date: Thu, 22 Oct 2015 20:40:33 +0200 Subject: [PATCH] =?UTF-8?q?ClassGenerator=20hat=20eine=20Map=20von=20zus?= =?UTF-8?q?=C3=A4tzlichen=20Klassen=20die=20generiert=20werden=20m=C3=BCss?= =?UTF-8?q?en=20MyCompiler=20und=20MyCompilerApi=20aufger=C3=A4umt=20ASTFa?= =?UTF-8?q?ctory=20Klasse=20angefangen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bytecode/ClassGenerator.java | 12 + src/de/dhbwstuttgart/core/MyCompiler.java | 600 +----------------- src/de/dhbwstuttgart/core/MyCompilerAPI.java | 8 +- src/de/dhbwstuttgart/syntaxtree/Class.java | 14 +- .../dhbwstuttgart/syntaxtree/SourceFile.java | 4 +- .../syntaxtree/factory/ASTFactory.java | 42 ++ .../syntaxtree/type/RefType.java | 7 +- .../typeinference/ByteCodeResult.java | 9 +- .../typeinference/TypeinferenceResultSet.java | 3 +- test/bytecode/SingleClassTester.java | 29 +- 10 files changed, 129 insertions(+), 599 deletions(-) create mode 100644 src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java diff --git a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java index 0f8012ac..514b1821 100644 --- a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java +++ b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java @@ -1,6 +1,8 @@ package de.dhbwstuttgart.bytecode; +import java.util.HashMap; import java.util.Iterator; +import java.util.Map; import org.apache.commons.bcel6.classfile.BootstrapMethod; import org.apache.commons.bcel6.classfile.BootstrapMethods; @@ -29,6 +31,8 @@ public class ClassGenerator extends ClassGen{ private Type superClass; private Menge usedTPHs = new Menge<>(); + + private Map extraClasses = new HashMap(); public ClassGenerator(String name, Type superClass, String string, short accPublic, String[] strings, TypeinferenceResultSet resultSet) { @@ -156,4 +160,12 @@ public class ClassGenerator extends ClassGen{ return ret; } + public void addExtraClass(ClassGenerator cg){ + extraClasses.put(cg.getClassName(), cg); + } + + public Map getExtraClasses() { + return extraClasses; + } + } diff --git a/src/de/dhbwstuttgart/core/MyCompiler.java b/src/de/dhbwstuttgart/core/MyCompiler.java index 7b72e79b..60ea5bb2 100755 --- a/src/de/dhbwstuttgart/core/MyCompiler.java +++ b/src/de/dhbwstuttgart/core/MyCompiler.java @@ -1,9 +1,6 @@ -// ino.module.MyCompiler.8569.package + package de.dhbwstuttgart.core; -// ino.end - -// ino.module.MyCompiler.8569.import import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; @@ -48,67 +45,28 @@ import de.dhbwstuttgart.typeinference.exceptions.ParserError; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; - -// ino.class.MyCompiler.21258.declaration -public class MyCompiler implements MyCompilerAPI -// ino.end -// ino.class.MyCompiler.21258.body -{ - // ino.attribute.NO_LINENUMBER.21262.decldescription type=line +public class MyCompiler implements MyCompilerAPI{ // PL: Der Zusammenhang zwischen paralist und vParaOrg muesste // noch geklaert werden 05-01-07 - // ino.end - // ino.attribute.NO_LINENUMBER.21262.declaration public static final int NO_LINENUMBER = -1; - // ino.end - - // ino.attribute.codegenlog.21265.decldescription type=line - // Logger - // ino.end - // ino.attribute.codegenlog.21265.declaration - //protected static Logger codegenlog = Logger.getLogger("codegen"); - // ino.end - // ino.attribute.inferencelog.21268.declaration + protected static Logger inferencelog = Logger.getLogger(MyCompiler.class.getName()); - // ino.end - // ino.attribute.parserlog.21271.declaration - //protected static Logger parserlog = Logger.getLogger("parser"); - // ino.end - - // ino.attribute.OutputDir.21274.declaration + protected String OutputDir = ""; - // ino.end + public Menge testPair = null; - // ino.attribute.m_AbstractSyntaxTree.21280.decldescription type=javadoc - /** - * Der abstrake Syntaxbaum - *
Autor: J�rg B�uerle - */ - // ino.end - // ino.attribute.m_AbstractSyntaxTree.21280.declaration - private Menge m_AbstractSyntaxTree = new Menge(); - // ino.end - - // ino.method.MyCompiler.21283.defdescription type=javadoc /** * Author: J�rg B�uerle
* Der private Konstruktor. Es soll von au�en kein Compiler angelegt werden * k�nnen, sondern nur eine API zur Verf�gung gestellt werden. * @param logger Konfiguration für Debug Ausgabe TODO */ - // ino.end - // ino.method.MyCompiler.21283.definition - private MyCompiler() - // ino.end - // ino.method.MyCompiler.21283.body - { + private MyCompiler(){ this.init(); } - // ino.end - - // ino.method.getAPI.21286.defdescription type=javadoc + /** * Author: Jörg Bäuerle
* Stellt eine neue Instanz der CompilerAPI zur Verf�gung. @@ -116,116 +74,11 @@ public class MyCompiler implements MyCompilerAPI * um eine Quellcode-Datei zu kompilieren. * @return Die Compiler-API */ - // ino.end - // ino.method.getAPI.21286.definition - public static MyCompilerAPI getAPI(LoggerConfiguration loggerConfig) - // ino.end - // ino.method.getAPI.21286.body - { + public static MyCompilerAPI getAPI(LoggerConfiguration loggerConfig){ Logger.setStandardConfiguration(loggerConfig); return new MyCompiler(); } - // ino.end - public Menge testPair = null; - - // ino.method.wandleGeneric2RefType.21289.defdescription type=javadoc - /** - * Author: Thomas Ott
- * Ersetzt in der Superklassenparameterliste einer Klasse, diejenigen - * GenericTypeVars, zu denen es eine Klasse gibt, die gleich hei�t. - * Beim Parsen werden n�mlich vom Jay nur GenericTypeVars erzeugt und keine - * RefTypes. Dies wird durch diese Methode nachgeholt.
- * Bsp.: class JoergsTolleKlasse extends MartinsSuperklasse - *
Wie man an diesem Beispiel sieht, kann nur eine Superklasse instantiierte - * Typvariablen zwischen den eckigen Klammern stehen haben, nicht jedoch die - * abgeleitete Klasse. - * - * @param className Klassenname der aktuell betrachteten Klasse - * @param Parameter Parameter der Superklasse - * @param KlassenVektor - - // ino.end - // ino.method.wandleGeneric2RefType.21289.definition - public static void wandleGeneric2RefType(Menge Parameter, Menge KlassenVektor ) - // ino.end - // ino.method.wandleGeneric2RefType.21289.body - { - //wandleGeneric2RefType SOLLTE NICHT NUR FUER LISTEN - //VON TYPEN FUNKTIONIEREN PL 05-01-19 - // otth: GenericTypeVar in Superklassenparameterlisten in RefTypes mit Parameterlsite = NULL umwandeln, - // falls: f�r GenericTypeVar existiert eine gleichnamige Klasse - if(Parameter == null) return; - - for( int i = 0; i < Parameter.size(); i++) - { - Type TempParameter = Parameter.elementAt(i); - inferencelog.debug("Nr. des Parameters: " + i); - - // an dieser Stelle: Parametername - if ( TempParameter instanceof GenericTypeVar) - { - inferencelog.debug("Generic, WANDLE: " + TempParameter.getName()); - // existiert f�r GenericTypeVar eine deklarierte Klasse - for( int k = 0; k < KlassenVektor.size(); k++) - { - if( KlassenVektor.elementAt(k).getSimpleName().equals(TempParameter.getSimpleName()) ) - { - // Klasse existiert, darf aber keine Parameterliste in der Definition haben - if( KlassenVektor.elementAt(k).get_ParaList().size() == 0 ) - { - RefType RNeu = new RefType( TempParameter.getName().toString(), null,TempParameter.getOffset()); - inferencelog.debug( "Vorher: " + Parameter ); - // i-te Stelle ersetzen - Parameter.set( i, RNeu ); - inferencelog.debug( "GenericTypeVar " + TempParameter.getName() + " umwandeln..." ); - inferencelog.debug( "Nachher: " + Parameter ); - } - else - { - //parserlog.error( "SEMANTIK-CHECK-FEHLER: Parameter " + TempParameter.getName() + " muss weitere Parameter besitzen (laut Klassendefinition)" ); - //FIXME Throw exception instead of simple exit - System.exit( 1 ); - } - } - else { - inferencelog.debug("Ist echter Generic, wird nicht ersetzt!"); - } - } // end for - } // end if - else - { - inferencelog.debug("Nicht Generic, WANDLE nicht: " + TempParameter.getName()); - // RefType --> u.U. rekursiv weiterwandeln - if(TempParameter instanceof RefType) - { - RefType R = (RefType)TempParameter; - if( R.get_ParaList() != null ) - wandleGeneric2RefType( R.get_ParaList(), KlassenVektor ); - } - else if(TempParameter instanceof ITypeContainer) - { - Type T = ((ITypeContainer)TempParameter).getContainedType(); - if(T instanceof RefType) - { - RefType R = (RefType)T; - if( R.get_ParaList() != null ) - wandleGeneric2RefType( R.get_ParaList(), KlassenVektor ); - } - } - else - { - inferencelog.error("Internal Error"); - System.exit( 1 ); - } - } - } //end for - } //end wandleGeneric2RefType - // ino.end - */ - - - // ino.method.parse.21292.defdescription type=javadoc /** * Parst den Quellcode und baut den abstrakten Syntaxbaum auf. Danach wird * automatisch der von Thomas Ott implementierte Algorithmus @@ -236,246 +89,19 @@ public class MyCompiler implements MyCompilerAPI * @throws IOException * @throws JavaParser.yyException */ - // ino.end - // ino.method.parse.21292.definition - private void parse_backup(Reader reader) - throws IOException, JavaParser.yyException - // ino.end - // ino.method.parse.21292.body - { - /* - parserlog.info("#########################################"); - parserlog.info("# Parsen - START #"); - parserlog.info("#########################################\n"); - - ////////////////////////////////////// - // Alte Daten l�schen: - ////////////////////////////////////// - m_AbstractSyntaxTree = null; - - ////////////////////////////////////// - // Scanner und Parser erzeugen: - ////////////////////////////////////// - Scanner scanner = new Scanner(reader); - JavaParser parser = new JavaParser(); - - ////////////////////////////////////// - // Parsen ==> Ergebnis: srcFile = Abstrakter Syntaxbaum - ////////////////////////////////////// - SourceFile srcFile = (SourceFile) parser.yyparse( scanner ); - this.testPair = parser.testPair; - - parserlog.info( "Parsen war erfolgreich!\n"); - - //PL 05-07-31 verschoben nach SourceFile.java in Methode typeReconstruction - // otth: TypePlaceholders in Superklassenparameterlisten in RefTypes mit Parameterlsite = NULL umwandeln, - // falls: f�r TypePlaceholder existiert eine gleichnamige Klasse - // Superklasse suchen - //for( int i = 0; i < srcFile.KlassenVektor.size(); i++ ) - //{ - //Class tempKlasse = (Class)srcFile.KlassenVektor.elementAt( i ); - - //PL 05-07-30 ausgetauscht um alle Typedeklarationen zu wandeln - // if( tempKlasse.superclassid != null && tempKlasse.get_ParaList() != null ) - // { - // // aktuelle Klasse hat Superklasse und Parameter - // Menge Parameter = tempKlasse.superclassid.get_ParaList(); - // this.wandleGeneric2RefType(Parameter, srcFile.KlassenVektor ); - // } - //wandleGeneric2RefType(tempKlasse.getContainedTypes(), srcFile.KlassenVektor ); - - //} - - // otth: echte Konstruktoren von Methodendeklarationen ohne Typen unterscheiden - if ( srcFile != null ) - { - Class tempKlasse = null; - ClassBody tempKlassBody = null; - Menge tempMengeFieldDecl; - mycompiler.myclass.Field tempFieldDecl = null; - String strKlasse; - - for( int i = 0; i < srcFile.KlassenVektor.size(); i++ ) - { - - // Unterscheidung zwischen Class und Interfaces - if (srcFile.KlassenVektor.elementAt(i) instanceof Class) { - tempKlasse = (Class)srcFile.KlassenVektor.elementAt( i ); - tempKlassBody = tempKlasse.get_ClassBody(); - } else { - tempKlasse = null; - tempKlassBody = null; - } - - if ( tempKlassBody != null ) - { - strKlasse = tempKlasse.getName(); - parserlog.debug("T->Felddeklarationen f�r die Klasse:" + strKlasse); - parserlog.debug( "------------------------------------"); - - // Schleife �ber alle fielddeclarations - tempMengeFieldDecl = tempKlassBody.getFields(); - for( int k = 0; k < tempMengeFieldDecl.size(); k++ ) - { - tempFieldDecl = tempMengeFieldDecl.elementAt(k); - if( tempFieldDecl instanceof Constructor ) - { - //parserlog.debug("T->Konstruktor: " + ((DeclId)tempFieldDecl.get_Name().elementAt(0)).get_Name() + " - ReturnType: " + tempFieldDecl.getTypeName()); - - // pr�fen, ob Construktorname == Klassenname - falls nein: Construktor in Methode umwandeln !!! - String strConstName = ((DeclId)tempFieldDecl.get_Name().elementAt(0)).get_Name(); // Konstruktorname - if ( !strConstName.equals( strKlasse ) ) - { - // Element k durch neues ersetzen! - - Method Methode = new Method(); - Method Konstruktor = (Constructor)tempFieldDecl; - - // Elementweise vom Konstruktor in die Methode kopieren - Methode.set_Block( Konstruktor.get_Block() ); - Methode.setParameterList( Konstruktor.getParameterList() ); - Methode.set_ExceptionList( Konstruktor.get_ExceptionList() ); - Methode.setReturnType( Konstruktor.getReturnType() ); - Methode.setDeclIdMenge( Konstruktor.getDeclIdMenge() ); - // types_in_parameterlist wird wohl erst sp�ter und intern gef�llt - - // R�ckgabetyp = Objekt der Klasse 'TypePlaceholder' - - // #JB# 31.03.2005 - // ########################################################### - Methode.setReturnType(TypePlaceholder.fresh(Methode)); - //Methode.setReturnType( new TypePlaceholder("###NEU###") ); - // ########################################################### - - // Element an der Position k durch neues ersetzen! - tempMengeFieldDecl.setElementAt( Methode, k ); - } - } - if( tempFieldDecl instanceof Method && !(tempFieldDecl instanceof Constructor) ) - { - //parserlog.debug("T->Methode: " + ((DeclId)tempFieldDecl.get_Name().elementAt(0)).get_Name() + " - ReturnType: " + tempFieldDecl.getTypeName()); - } - - } - - // Debugg-Infos - parserlog.debug(""); - parserlog.debug("T->NEUE Felddeklarationen f�r die Klasse:" + strKlasse); - parserlog.debug( "-----------------------------------------"); - for( int k = 0; k < tempMengeFieldDecl.size(); k++ ) - { - tempFieldDecl = tempMengeFieldDecl.elementAt(k); - //parserlog.debug("T->" + ((DeclId)tempFieldDecl.get_Name().elementAt(0)).get_Name() + " - Typ: " + tempFieldDecl + " - ReturnType: " + tempFieldDecl.getTypeName()); - } - - // otth: TypePlaceholders durchnummerieren mit A, B, ... - parserlog.debug(""); - parserlog.debug(""); - parserlog.debug("Suche TypePlaceholders in den FieldDecls:"); - parserlog.debug( "------------------------------------------"); - - ParameterList tempParameterList; - Menge tempVFktPara; - FormalParameter tempFP; - Method tempMethod; - Type tempReturn; - Type tempType; - for( int k = 0; k < tempMengeFieldDecl.size(); k++ ) - { - tempFieldDecl = tempMengeFieldDecl.elementAt(k); - tempMethod = null; - - if( tempFieldDecl instanceof Method ) - { - tempMethod = (Method)tempFieldDecl; - tempReturn = tempMethod.getReturnType(); - - // Funktionen ohne definierten R�ckgabetyp suchen!!! - if( tempReturn instanceof TypePlaceholder ) - { - // Methode mit nicht-definiertem R�ckgabetyp gefunden! - - // #JB# 31.03.2005 - // ########################################################### - // Wird bereits �ber fresh() gemacht!! - //tempReturn.setName( TypePlaceholder.makeNewName() ); - // ########################################################### - parserlog.debug(""); - parserlog.debug("Methode ohne Rueckgabetyp: " + tempMethod.get_Method_Name() + " --> " + tempReturn.getName()); - } - else - { - parserlog.debug(""); - parserlog.debug("Methode mit Rueckgabetyp / Konstruktor: " + tempMethod.get_Method_Name()); - } - - // Methoden-Funktionsparameter durchsuchen - tempParameterList = tempMethod.getParameterList(); - if ( tempParameterList != null ) - { - tempVFktPara = tempParameterList.sc_get_Formalparalist(); - for( int l = 0; l < tempVFktPara.size(); l++ ) - { - tempFP = tempVFktPara.elementAt(l); - tempType = tempFP.getType(); - if( tempType instanceof TypePlaceholder ) - { - if( tempType != null ) - { - // neuer Name berechnen - - // #JB# 31.03.2005 - // ########################################################### - // Wird bereits �ber fresh() gemacht!! - //tempType.setName( TypePlaceholder.makeNewName() ); - // ########################################################### - } - } - parserlog.debug(""); - parserlog.debug(" Parameter: " + tempFP.get_Name() + " --> " + tempType.getName()); - } - } - else - { - parserlog.debug(""); - parserlog.debug(" Methode hat keine Parameter!"); - } - } - } - } //end if - } //end for - } //end if - m_AbstractSyntaxTree = srcFile; - - parserlog.info("#########################################"); - parserlog.info("# Parsen - ENDE #"); - parserlog.info("#########################################\n"); - */ - } // end Methode parse() - // ino.end - + private void parse_backup(Reader reader) throws IOException, JavaParser.yyException{ + + } ///////////////////////////////////////////////////////////////////////////////////////////////// // Implementierte API-Methoden: ///////////////////////////////////////////////////////////////////////////////////////////////// - // ino.method.init.21295.defdescription type=javadoc /** * Author: J�rg B�uerle
* Initialisiert den Compiler */ - // ino.end - // ino.method.init.21295.definition - public void init() - // ino.end - // ino.method.init.21295.body - { + public void init(){ TypePlaceholder.deleteRegistry(); - - // Log4J fuer die Ausgabe vorbereiten - //DOMConfigurator.configure("log4j.xml"); } - // ino.end - - // ino.method.parse.21298.defdescription type=javadoc /** * Author: J�rg B�uerle
* Ruft die Parse-Methode. @@ -484,22 +110,13 @@ public class MyCompiler implements MyCompilerAPI * @throws IOException Wenn was schief l�uft. * @throws JavaParser.yyException Wenn ein Fehler beim Parsen auftritt. */ - // ino.end - // ino.method.parse.21298.definition - public SourceFile parse(File file) - throws FileNotFoundException, IOException, JavaParser.yyException - // ino.end - // ino.method.parse.21298.body - { + public SourceFile parse(File file) throws FileNotFoundException, IOException, JavaParser.yyException{ FileReader fr = new FileReader(file); SourceFile ret = this.parse2SyntaxTree(fr); - this.m_AbstractSyntaxTree.add(ret); fr.close(); return ret; } - // ino.end - - // ino.method.typeReconstruction.21304.defdescription type=javadoc + /** * Author: J�rg B�uerle
* Ruft den Typrekonstruktionsalgorithmus auf. @@ -508,16 +125,7 @@ public class MyCompiler implements MyCompilerAPI * ist. @throws CTypeReconstructionException Wenn ein Fehler bei der * Typrekonstruktion auftritt. */ - // ino.end - // ino.method.typeReconstruction.21304.definition - public Menge typeReconstruction() - throws NullPointerException, CTypeReconstructionException - // ino.end - // ino.method.typeReconstruction.21304.body - { - if(m_AbstractSyntaxTree==null){ - throw new NullPointerException("Es wurde noch kein Abstrakter Syntaxbaum erstellt!"); - } + public Menge typeReconstruction(Menge m_AbstractSyntaxTree) throws NullPointerException, CTypeReconstructionException{ inferencelog.info("##########################################", Section.TYPEINFERENCE); inferencelog.info("# TypeReconstruction-Algorithmus - START #", Section.TYPEINFERENCE); inferencelog.info("##########################################\n", Section.TYPEINFERENCE); @@ -535,7 +143,6 @@ public class MyCompiler implements MyCompilerAPI return result; } - // ino.end /** * Erstellt die FunN-Assumptions @@ -559,45 +166,13 @@ public class MyCompiler implements MyCompilerAPI return ret; } - - /** - * Author: J�rg B�uerle
- * Generiert den Bytecode und das Class-File f�r den Syntaxbaum. - * @throws NullPointerException Wenn noch kein abstrakter Syntaxbaum vorhanden - * ist. - - @Override - public Menge codeGeneration(ResultSet result) - throws NullPointerException, JVMCodeException - { - if(m_AbstractSyntaxTree==null){ - throw new NullPointerException("Es wurde noch kein Abstrakter Syntaxbaum erstellt!"); - } - codegenlog.info("Beginn der Codegenerierung ..."); - - Menge ret = new Menge(); - - for(SourceFile sf : m_AbstractSyntaxTree){ - ret.addAll(sf.codegen(result)); - } - - codegenlog.info("Codegenerierung beendet!"); - return ret; - }*/ - - // ino.method.main.21313.defdescription type=javadoc /** * Die Main-Funktion, �ber die der Compiler auch per Konsole gestartet * werden kann. * @param args Klassendatei */ - // ino.end - // ino.method.main.21313.definition - public static void main(String[] args) - // ino.end - // ino.method.main.21313.body - { + public static void main(String[] args){ MyCompilerAPI compiler = MyCompiler.getAPI(new LoggerConfiguration()); // Hier koennten ggf. Aenderungen der Ausgabeeinstellungen @@ -617,33 +192,9 @@ public class MyCompiler implements MyCompilerAPI System.err.println(e); System.exit(0); } - - ///////////////////////// - // Semantik-Check: - ///////////////////////// - // try { - // compiler.semanticCheck(); - // } catch (NullPointerException e) { - // System.out.println("Fehler beim Aufrufen des Semantik-Checks:"); - // System.out.println(e); - // System.exit(0); - // } catch (SCException e) { - // e.fehlerausgabe(); - // System.exit(0); - // } - - ///////////////////////// - // Code-Generierung: - ///////////////////////// - //compiler.codeGeneration(); - } - // ino.end + } - // ino.method.setOutputDir.21316.definition - public void setOutputDir(String dir) - // ino.end - // ino.method.setOutputDir.21316.body - { + public void setOutputDir(String dir){ char c = dir.charAt(dir.length()-1); if (c != '/' & c != '\\') dir = dir + "/"; OutputDir = dir; @@ -652,75 +203,11 @@ public class MyCompiler implements MyCompilerAPI File f = new File(dir); f.mkdirs(); } - // ino.end - // ino.method.getOutputDir.21319.definition - public String getOutputDir() - // ino.end - // ino.method.getOutputDir.21319.body - { + public String getOutputDir(){ return OutputDir; } - // ino.end -/* - // ino.method.getFullyQualifiedNameFromClassname.21322.definition - public static String getFullyQualifiedNameFromClassname(String typ, ImportDeclarations declarations) - // ino.end - // ino.method.getFullyQualifiedNameFromClassname.21322.body - { - String ret=null; - // Es ist kein FullyQualifiedName => In den Imports die Klasse suchen - for(int j=0;j de.dhbwstuttgart.typeinference.Menge x; - * @param containedTypes Alle Typen, die die Klasse beinhaltet - * @param name Alle Klassen, die es in den BasicAssumptions und im - * AbstractSyntaxTree gibt @param declarations Alle Import-Declarations - - // ino.end - // ino.method.makeRefTypesFullyQualified.21325.definition - public static void makeRefTypesFullyQualified(Menge containedTypes, ImportDeclarations declarations) - // ino.end - // ino.method.makeRefTypesFullyQualified.21325.body - { - // HOTI 8.5.06 Anhand der ContainedTypes alle Variablen aendern - for( int i = 0; i < containedTypes.size(); i++) - { - Type tempParameter = (Type)(containedTypes.elementAt(i)); - // Nat�rlich nur RefTypes updaten - if(tempParameter instanceof RefType){ - RefType typ=(RefType)tempParameter; - UsedId fullyQualifiedName=UsedId.createFromQualifiedName(typ.getTypeName(),typ.getOffset()); - // Kein FullyQualifiedName - if(fullyQualifiedName.name.size()==1){ - String newType=getFullyQualifiedNameFromClassname(typ.getSimpleName(),declarations); - if(newType!=null){ - typ.setName(newType); - } - - } - if(typ.get_ParaList()!=null){ - makeRefTypesFullyQualified(typ.get_ParaList(),declarations); - } - } - } - } - // ino.end - */ /** * @author Arne Lüdtke * Ersetzt alle GTVs durch TPHs mit gleichem Namen. Arbeitet Rekursiv. @@ -790,8 +277,10 @@ public class MyCompiler implements MyCompilerAPI /** * Diese Funktion nimmt einen Menge von Dateinamen. Alle diese Dateien werden zu einem SyntaxBaum geparst. + * @return */ - public void parse(Menge filenames) throws ParserError { + public Menge parse(Menge filenames) throws ParserError { + Menge m_AbstractSyntaxTree = new Menge(); for(String filename : filenames){ StringBuffer fileData = new StringBuffer(); @@ -816,58 +305,25 @@ public class MyCompiler implements MyCompilerAPI StringReader srcreader = new StringReader(fileData.toString()); //Den aus der Datei ausgelesenen Quellcode zu einem Syntaxbaum parsen: - this.m_AbstractSyntaxTree.add(parse2SyntaxTree(srcreader)); // Alle Dateien nacheinander hintereinander anhängen... - - } - /* - String gesamterSrc = ""; - //Hier werden alle übergebenen Dateinamen abgearbeitet: - for(String filename : filenames){ - try { - StringBuffer fileData = new StringBuffer(); - BufferedReader reader = new BufferedReader( - new FileReader(filename)); - char[] buf = new char[1024]; - int numRead=0; - while((numRead=reader.read(buf)) != -1){ - String readData = String.valueOf(buf, 0, numRead); - fileData.append(readData); - } - reader.close(); - gesamterSrc += fileData.toString() + "\n"; // Alle Dateien nacheinander hintereinander anhängen... - } catch (Exception e) { - e.printStackTrace(); - throw new TypinferenzException("Die übergebenen Dateien konnten nicht zum Parsen eingelesen werden."); - } + m_AbstractSyntaxTree.add(parse2SyntaxTree(srcreader)); // Alle Dateien nacheinander hintereinander anhängen... } - try { - // und anschließend zum Parsen übergeben. - this.parse(gesamterSrc.toString()); - } catch (Exception e) { - e.printStackTrace(); - //throw new TypinferenzException("Fehler beim Parsen"); - } - - */ + return m_AbstractSyntaxTree; } @Override public SourceFile parse(String sourceCode) { - SourceFile ret = this.parse2SyntaxTree(new StringReader(sourceCode)); - this.m_AbstractSyntaxTree.add(ret); - return ret; + return parse2SyntaxTree(new StringReader(sourceCode)); } @Override - public Menge> generateBytecode(TypeinferenceResultSet typeinferenceResult) { + public Menge generateBytecode(Menge m_AbstractSyntaxTree, TypeinferenceResultSet typeinferenceResult) { //SourceFile parsedFile = this.m_AbstractSyntaxTree.firstElement(); //Class parsedClass = parsedFile.KlassenVektor.firstElement(); - Menge> ret = new Menge<>(); - for(SourceFile sf : this.m_AbstractSyntaxTree){ + Menge ret = new Menge<>(); + for(SourceFile sf : m_AbstractSyntaxTree){ ret.addAll(sf.generateBytecode(typeinferenceResult)); } return ret; } } -// ino.end diff --git a/src/de/dhbwstuttgart/core/MyCompilerAPI.java b/src/de/dhbwstuttgart/core/MyCompilerAPI.java index 78860de4..f0eac42f 100755 --- a/src/de/dhbwstuttgart/core/MyCompilerAPI.java +++ b/src/de/dhbwstuttgart/core/MyCompilerAPI.java @@ -85,8 +85,7 @@ public interface MyCompilerAPI */ // ino.end // ino.method.typeReconstruction.21340.declaration - public Menge typeReconstruction() - throws NullPointerException, TypeinferenceException; + public Menge typeReconstruction(Menge m_AbstractSyntaxTree) throws NullPointerException, CTypeReconstructionException; // ino.end // ino.method.setOutputDir.21349.decldescription type=javadoc @@ -112,8 +111,9 @@ public interface MyCompilerAPI /** * Parst zusammenhängende JavaKlassen in verschiedenen Dateien. * @param filenames - Eine Liste von Quellcodedateien, welche gseparst werden sollen + * @return */ - public void parse(Menge filenames) throws ParserError; + public Menge parse(Menge filenames) throws ParserError; /** * Parst den SourceCode einer Datei. @@ -127,6 +127,6 @@ public interface MyCompilerAPI * Dafür müssen die Schritte Parsen und typeReconstruction ausgeführt werden. * @return */ - public Menge> generateBytecode(TypeinferenceResultSet rs); + public Menge generateBytecode(Menge m_AbstractSyntaxTree, TypeinferenceResultSet typeinferenceResult); } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/Class.java b/src/de/dhbwstuttgart/syntaxtree/Class.java index 2313f22c..bfa79b33 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Class.java +++ b/src/de/dhbwstuttgart/syntaxtree/Class.java @@ -75,7 +75,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I * @param resultSet - Fehlende Typen im Syntaxbaum werden nach diesem ResultSet aufgelöst * @return */ - public Menge genByteCode(TypeinferenceResultSet resultSet) { + public ByteCodeResult genByteCode(TypeinferenceResultSet resultSet) { InstructionFactory _factory; DHBWConstantPoolGen _cp; ClassGenerator _cg; @@ -113,12 +113,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I c.genByteCode(_cg, fieldInitializations); } - ByteCodeResult code = new ByteCodeResult(_cg); - results.add(code); - - results.addAll(getGenericClasses()); - - return results; + return new ByteCodeResult(_cg); } private Menge superif = new Menge(); @@ -1032,6 +1027,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I return false; } + /* private Collection getGenericClasses() { Collection results = new Menge<>(); @@ -1067,7 +1063,9 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I return results; } + */ + /* private Menge generateGenericClass(String name, Class superClass){ //TODO: bytecode -- Generics hinzufügen //Type superClassType = superClass.getType(); @@ -1080,6 +1078,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I //TODO: bytecode -- alle Konstruktoren generieren Block konstruktorBlock = new Block(); + konstruktorBlock.setType(new de.dhbwstuttgart.syntaxtree.type.Void(konstruktorBlock, 0)); konstruktorBlock.statements.add(new SuperCall(konstruktorBlock)); Constructor standardKonstruktor = new Constructor(Method.createEmptyMethod(konstruktorBlock, name, superClass), superClass); standardKonstruktor.parserPostProcessing(generatedClass); @@ -1088,5 +1087,6 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I return generatedClass.genByteCode(new TypeinferenceResultSet(generatedClass, new Menge<>(), new ResultSet())); } + */ } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index 22c45fd7..56222f1a 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -1834,8 +1834,8 @@ public class SourceFile * Bisher wird nur der Bytecode der Klassen generiert. Nicht der Interfaces. * @return */ - public Menge> generateBytecode(TypeinferenceResultSet rs) { - Menge> ret = new Menge<>(); + public Menge generateBytecode(TypeinferenceResultSet rs) { + Menge ret = new Menge<>(); for(Class cl : this.KlassenVektor){ ret.add(cl.genByteCode(rs)); } diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java new file mode 100644 index 00000000..29940082 --- /dev/null +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -0,0 +1,42 @@ +package de.dhbwstuttgart.syntaxtree.factory; + +import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.syntaxtree.Class; +import de.dhbwstuttgart.syntaxtree.Constructor; +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.misc.DeclId; +import de.dhbwstuttgart.syntaxtree.statement.Block; +import de.dhbwstuttgart.syntaxtree.statement.SuperCall; + +public class ASTFactory { + public static Method createMethod(String name, Block block, Class parent) { + Method method = new Method(0); + DeclId DImethod = new DeclId(); + //DImethod.set_Name(withSignature); //todo: bytecode signatur? + method.set_DeclId(DImethod); + method.set_Block(block); + method.parserPostProcessing(parent); + return method; + } + + public static Method createEmptyMethod(String withSignature, Class parent) { + return ASTFactory.createMethod("", new Block(), parent); + } + + public static Constructor createEmptyConstructor(Class parent){ + Block block = new Block(); + block.setType(new de.dhbwstuttgart.syntaxtree.type.Void(block, 0)); + block.statements.add(new SuperCall(block)); + + return ASTFactory.createConstructor(parent, block); + } + + public static Constructor createConstructor(Class superClass, Block block){ + return new Constructor(ASTFactory.createMethod("", block, superClass), superClass); + } + + public static ClassGenerator createClass(String className, Class superClass) { + // TODO Auto-generated method stub + return null; + } +} diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java index 56caea6c..e044c065 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java @@ -15,6 +15,7 @@ import de.dhbwstuttgart.myexception.SCException; import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; +import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.misc.UsedId; import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; @@ -834,6 +835,10 @@ public class RefType extends ObjectType implements IMatchable typeSignature = typeSignature.substring(0, typeSignature.length()-1); return typeSignature+paramString+";"; */ + + //TODO: bytecode woher bekommt ich die parent klasse + cg.addExtraClass(ASTFactory.createClass(getCombinedType(cg), null)); + return "L"+getCombinedType(cg)+";"; } @@ -845,7 +850,7 @@ public class RefType extends ObjectType implements IMatchable sb.append(this.get_Name().replace(".", "%")); sb.append("%%"); for(Type type: parameter){ - sb.append(((RefType) type).getCombinedType(cg)); + sb.append(((RefType) type).getCombinedType(cg).replace(".", "%")); sb.append("%"); } }else{ diff --git a/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java b/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java index c036b5da..8ed910ba 100644 --- a/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java +++ b/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java @@ -2,23 +2,26 @@ package de.dhbwstuttgart.typeinference; import java.io.File; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import org.apache.commons.bcel6.generic.ClassGen; import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.bytecode.ClassGenerator; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; public class ByteCodeResult{ - private ClassGen byteCode; + private ClassGenerator byteCode; //TODO: unresolvedTPHs entfernen. BROKEN! private Menge unresolvedTPHs = new Menge(); - public ByteCodeResult(ClassGen byteCode){ + public ByteCodeResult(ClassGenerator byteCode){ this.byteCode = byteCode; } - public ClassGen getByteCode(){ + public ClassGenerator getByteCode(){ return byteCode; } diff --git a/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java b/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java index 819d310b..5dbf463c 100755 --- a/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java +++ b/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java @@ -119,8 +119,7 @@ public class TypeinferenceResultSet * Dabei wird die codegen-Methode der inferierten Klasse mit diesem ResultSet aufgerufen. */ public ByteCodeResult codegen(){ - ByteCodeResult res = this.ownerOfResultSet.genByteCode(this).firstElement(); - return res; + return this.ownerOfResultSet.genByteCode(this); } } diff --git a/test/bytecode/SingleClassTester.java b/test/bytecode/SingleClassTester.java index a5d958f0..46693780 100644 --- a/test/bytecode/SingleClassTester.java +++ b/test/bytecode/SingleClassTester.java @@ -2,12 +2,14 @@ package bytecode; import java.io.File; import java.io.IOException; +import java.util.Map; import org.apache.commons.bcel6.classfile.JavaClass; import com.google.common.io.Files; import junit.framework.TestCase; +import de.dhbwstuttgart.bytecode.ClassGenerator; import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.core.MyCompilerAPI; import de.dhbwstuttgart.logger.Logger; @@ -15,6 +17,7 @@ import de.dhbwstuttgart.logger.LoggerConfiguration; import de.dhbwstuttgart.logger.Section; import de.dhbwstuttgart.logger.Timewatch; import de.dhbwstuttgart.parser.JavaParser.yyException; +import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.typeinference.ByteCodeResult; import de.dhbwstuttgart.typeinference.Menge; @@ -24,18 +27,28 @@ public class SingleClassTester { LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out); MyCompilerAPI compiler = MyCompiler.getAPI(logConfig); try { - compiler.parse(new File(inputFile)); - Menge> bytecode = compiler.generateBytecode(compiler.typeReconstruction().firstElement()); + SourceFile sf = compiler.parse(new File(inputFile)); + + Menge sourceFiles = new Menge<>(); + sourceFiles.add(sf); + + Menge bytecode = compiler.generateBytecode(sourceFiles, compiler.typeReconstruction(sourceFiles).firstElement()); //System.out.println(bytecode); - for(ByteCodeResult result: bytecode.firstElement()){ - JavaClass javaClass = result.getByteCode().getJavaClass(); - - Logger.getLogger("SingleClassTester").error(result.getByteCode().getJavaClass().toString(), Section.CODEGEN); - - javaClass.dump(new File(outputDirectory+javaClass.getClassName()+".class")); + ByteCodeResult result = bytecode.firstElement(); + + JavaClass javaClass = result.getByteCode().getJavaClass(); + javaClass.dump(new File(outputDirectory+javaClass.getClassName()+".class")); + + for(ClassGenerator cg: result.getByteCode().getExtraClasses().values()){ + JavaClass jc = cg.getJavaClass(); + jc.dump(new File(outputDirectory+jc.getClassName()+".class")); } + Logger.getLogger("SingleClassTester").error(result.getByteCode().getJavaClass().toString(), Section.CODEGEN); + + + } catch (IOException | yyException e) { Logger.getLogger("SingleClassTester").error(e.toString(), Section.CODEGEN); e.printStackTrace();