diff --git a/src/de/dhbwstuttgart/core/MyCompiler.java b/src/de/dhbwstuttgart/core/MyCompiler.java index 1b776429..5c066cee 100755 --- a/src/de/dhbwstuttgart/core/MyCompiler.java +++ b/src/de/dhbwstuttgart/core/MyCompiler.java @@ -864,7 +864,9 @@ public class MyCompiler implements MyCompilerAPI * - wird der Rückgabetyp von generateBytecode in MyCompiler geändert, so muss auch der Rückgabetyp im Interface MyCompilerAPI geändert werden */ try { - return this.m_AbstractSyntaxTree.firstElement().KlassenVektor.firstElement().genByteCode(); + SourceFile parsedFile = this.m_AbstractSyntaxTree.firstElement(); + Class parsedClass = parsedFile.KlassenVektor.firstElement(); + return parsedClass.genByteCode(); } catch (IOException e) { e.printStackTrace(); return null; diff --git a/src/de/dhbwstuttgart/syntaxtree/Class.java b/src/de/dhbwstuttgart/syntaxtree/Class.java index 5acd3c00..fecde547 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Class.java +++ b/src/de/dhbwstuttgart/syntaxtree/Class.java @@ -16,9 +16,9 @@ import org.apache.bcel.generic.InstructionList; import org.apache.bcel.generic.MethodGen; import de.dhbwstuttgart.typeinference.Menge; - import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.logger.Section; +import de.dhbwstuttgart.logger.SectionLogger; import de.dhbwstuttgart.core.AClassOrInterface; import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.parser.JavaClassName; @@ -37,13 +37,16 @@ import de.dhbwstuttgart.typeinference.*; import de.dhbwstuttgart.typeinference.assumptions.ClassAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; import de.dhbwstuttgart.typeinference.exceptions.DebugException; +import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint; import de.dhbwstuttgart.typeinference.unify.FC_TTO; import de.dhbwstuttgart.typeinference.unify.Unify; + import org.apache.bcel.generic.*; import org.apache.bcel.classfile.*; import org.apache.bcel.*; + import java.io.*; @@ -70,26 +73,21 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I //Method created with BCEL to generate ByteCode public ByteCodeResult genByteCode() throws IOException { - ByteCodeResult code = new ByteCodeResult(); - _cg = new ClassGen(pkgName.get_Name() + "/" + name, superClass.get_Name(), name + ".java", Constants.ACC_PUBLIC , new String[] { }); //new String necessary? + + SectionLogger logger = Logger.getSectionLogger(this.getClass().getName(), Section.CODEGEN); + logger.debug("Test"); + + if(pkgName != null)throw new NotImplementedException(); + _cg = new ClassGen(name, superClass.get_Name(), name + ".java", Constants.ACC_PUBLIC , new String[] { }); //new String necessary? _cp = _cg.getConstantPool(); _factory = new InstructionFactory(_cg, _cp); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - InstructionList il = new InstructionList(); - MethodGen method = new MethodGen(Constants.ACC_PUBLIC, org.apache.bcel.generic.Type.VOID, org.apache.bcel.generic.Type.NO_ARGS, new String[] { }, "", pkgName.get_Name() + "." + name, il, _cp); - - InstructionHandle ih_0 = il.append(_factory.createLoad(org.apache.bcel.generic.Type.OBJECT, 0)); //creates Constructor - il.append(_factory.createInvoke("java.lang.Object", "", org.apache.bcel.generic.Type.VOID, org.apache.bcel.generic.Type.NO_ARGS, Constants.INVOKESPECIAL)); - InstructionHandle ih_4 = il.append(_factory.createReturn(org.apache.bcel.generic.Type.VOID)); //creates Constructor - method.setMaxStack(); - method.setMaxLocals(); - _cg.addMethod(method.getMethod()); - il.dispose(); - _cg.getJavaClass().dump(out); - code.attach(out.toString()); - + for(Field field : this.fielddecl){ + field.genByteCode(_cg); + } + + ByteCodeResult code = new ByteCodeResult(_cg); return code; /*ByteCodeResult bc = new ByteCodeResult(); diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index e7b29569..958a0f30 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -1,7 +1,15 @@ package de.dhbwstuttgart.syntaxtree; -import de.dhbwstuttgart.typeinference.Menge; +import org.apache.bcel.Constants; +import org.apache.bcel.classfile.ConstantPool; +import org.apache.bcel.generic.ClassGen; +import org.apache.bcel.generic.ConstantPoolGen; +import org.apache.bcel.generic.InstructionFactory; +import org.apache.bcel.generic.InstructionHandle; +import org.apache.bcel.generic.InstructionList; +import org.apache.bcel.generic.MethodGen; +import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.misc.DeclId; @@ -42,6 +50,26 @@ public class Constructor extends Method { ret.addAssumption(new ConstructorAssumption(this, parentClass)); return ret; } + + @Override + public void genByteCode(ClassGen cg) { + ConstantPoolGen _cp = cg.getConstantPool(); + InstructionFactory _factory = new InstructionFactory(cg, _cp); + InstructionList il = new InstructionList(); + Class parentClass = this.getParentClass(); + //TODO: Hier return type und Argument-Typen dynamisch generieren. return type mittels method.getReturnType() ermitteln + MethodGen method = new MethodGen(Constants.ACC_PUBLIC, org.apache.bcel.generic.Type.VOID, org.apache.bcel.generic.Type.NO_ARGS, new String[] { }, "", parentClass.name, il, _cp); + + InstructionHandle ih_0 = il.append(_factory.createLoad(org.apache.bcel.generic.Type.OBJECT, 0)); //creates Constructor + il.append(_factory.createInvoke(this.getParentClass().superclassid.toString(), "", org.apache.bcel.generic.Type.VOID, org.apache.bcel.generic.Type.NO_ARGS, Constants.INVOKESPECIAL)); + InstructionHandle ih_4 = il.append(_factory.createReturn(org.apache.bcel.generic.Type.VOID)); //creates Constructor + method.setMaxStack(); + method.setMaxLocals(); + cg.addMethod(method.getMethod()); + il.dispose(); + } + + /* @Override public void parserPostProcessing(SyntaxTreeNode parent){ diff --git a/src/de/dhbwstuttgart/syntaxtree/Field.java b/src/de/dhbwstuttgart/syntaxtree/Field.java index 2b40a085..cfce0dad 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Field.java +++ b/src/de/dhbwstuttgart/syntaxtree/Field.java @@ -1,7 +1,8 @@ package de.dhbwstuttgart.syntaxtree; -import de.dhbwstuttgart.typeinference.Menge; +import org.apache.bcel.generic.ClassGen; +import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.misc.DeclId; import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; @@ -171,4 +172,10 @@ public abstract class Field extends GTVDeclarationContext implements TypeInserta public boolean isClass() { return false; } + + /** + * Fügt das das Feld zu ClassGen hinzu + * @param cg + */ + public abstract void genByteCode(ClassGen cg); } diff --git a/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java b/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java index b452e3fc..eefd7482 100644 --- a/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java +++ b/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java @@ -1,7 +1,8 @@ package de.dhbwstuttgart.syntaxtree; -import de.dhbwstuttgart.typeinference.Menge; +import org.apache.bcel.generic.ClassGen; +import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.syntaxtree.misc.DeclId; import de.dhbwstuttgart.syntaxtree.statement.Expr; @@ -157,4 +158,10 @@ public class FieldDeclaration extends Field{ if(this.getWert()!=null)this.getWert().wandleRefTypeAttributes2GenericAttributes(paralist, new Menge()); //FieldDeclaration hat keine Generischen Variablen, daher leere Liste übergeben } + @Override + public void genByteCode(ClassGen cg) { + // TODO Auto-generated method stub + + } + } diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index a288aa98..88c3478c 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -5,10 +5,11 @@ package de.dhbwstuttgart.syntaxtree; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; + +import org.apache.bcel.generic.ClassGen; + import de.dhbwstuttgart.typeinference.Menge; - import de.dhbwstuttgart.logger.Logger; - import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.myexception.JVMCodeException; @@ -710,6 +711,13 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable if(!this.parameterlist.equals(equals.parameterlist))return false; return super.equals(obj); } + + @Override + public void genByteCode(ClassGen cg) { + // TODO Auto-generated method stub + + } + } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java index 76461859..8860f9b2 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java @@ -48,7 +48,6 @@ public class MethodCall extends Expr } // ino.end - // ino.attribute.receiver.25639.declaration /** * Diese Variable speichert die Expression, welche die Klasse von welcher die Methode aufgerufen wird darstellt. diff --git a/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java b/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java index e0f2b382..b83a5d65 100644 --- a/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java +++ b/src/de/dhbwstuttgart/typeinference/ByteCodeResult.java @@ -1,38 +1,24 @@ package de.dhbwstuttgart.typeinference; -import de.dhbwstuttgart.typeinference.Menge; +import org.apache.bcel.generic.ClassGen; +import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; public class ByteCodeResult{ - private String byteCode = ""; + private ClassGen byteCode; //TODO: unresolvedTPHs entfernen. BROKEN! private Menge unresolvedTPHs = new Menge(); - public ByteCodeResult(){ - + public ByteCodeResult(ClassGen byteCode){ + this.byteCode = byteCode; } - public ByteCodeResult(String byteCode){ - this.byteCode += byteCode; - } - - public String getByteCode(){ + public ClassGen getByteCode(){ return byteCode; } - public ByteCodeResult attach(ByteCodeResult byteCodeResult){ - this.byteCode += byteCodeResult.getByteCode(); - //Alle TPH anfügen: - for(TypePlaceholder tph : byteCodeResult.getUnresolvedTPH())this.addUnresolvedTPH(tph); - return this; - } - - public ByteCodeResult attach(String javaCode){ - this.byteCode += javaCode; - return this; - } public void addUnresolvedTPH(TypePlaceholder typePlaceholder) { unresolvedTPHs.add(typePlaceholder); @@ -49,7 +35,7 @@ public class ByteCodeResult{ @Override public String toString(){ - return getByteCode(); + return getByteCode().toString(); } @Override diff --git a/test/bytecode/EmptyClass.java b/test/bytecode/EmptyClass.java index 44c78d50..affdf31d 100644 --- a/test/bytecode/EmptyClass.java +++ b/test/bytecode/EmptyClass.java @@ -13,6 +13,7 @@ import plugindevelopment.TypeInsertTester; import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.core.MyCompilerAPI; import de.dhbwstuttgart.logger.LoggerConfiguration; +import de.dhbwstuttgart.logger.Section; import de.dhbwstuttgart.parser.JavaParser.yyException; import de.dhbwstuttgart.typeinference.ByteCodeResult; import de.dhbwstuttgart.typeinference.Menge; @@ -23,16 +24,18 @@ public class EmptyClass { public final static String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/"; public final static String testFile = "EmptyClass.jav"; - + public final static String outputFile = "EmptyClass.class"; + @Test public void test() { - LoggerConfiguration logConfig = new LoggerConfiguration(); + LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out); MyCompilerAPI compiler = MyCompiler.getAPI(logConfig); try { compiler.parse(new File(rootDirectory + testFile)); - compiler.typeReconstruction(); + //compiler.typeReconstruction(); ByteCodeResult bytecode = compiler.generateBytecode(); System.out.println(bytecode); + bytecode.getByteCode().getJavaClass().dump(new File(rootDirectory + outputFile)); } catch (IOException | yyException e) { e.printStackTrace(); TestCase.fail();