From bfe6b0360563208362397a44b255b4f520df89a1 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Thu, 10 Sep 2015 16:21:30 +0200 Subject: [PATCH] =?UTF-8?q?Umstieg=20auf=20BCEL6=20SourceCode.=20Einf?= =?UTF-8?q?=C3=BChren=20von=20DHBWInstructionFactory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .classpath | 2 +- BCEL/bcelifier/JavaToBCEL.java | 1 + BCEL/bcelifier/LocalVarAccess.java | 10 +++ BCEL/bcelifier/LocalVarAccessCreator.java | 61 +++++++++++++++++++ .../bytecode/ClassGenerator.java | 37 ++++++++++- .../bytecode/DHBWConstantPoolGen.java | 35 +++++++++++ .../bytecode/DHBWInstructionFactory.java | 58 +++++++++++------- src/de/dhbwstuttgart/syntaxtree/Class.java | 6 +- .../dhbwstuttgart/syntaxtree/Constructor.java | 3 +- src/de/dhbwstuttgart/syntaxtree/Method.java | 8 ++- .../syntaxtree/ParameterList.java | 21 +++++++ .../statement/LambdaExpression.java | 23 +++---- .../syntaxtree/statement/LocalOrFieldVar.java | 21 ++++++- test/bytecode/Runnable.jav | 5 ++ test/bytecode/RunnableTest.java | 14 +++++ test/bytecode/Test.java | 1 + 16 files changed, 255 insertions(+), 51 deletions(-) create mode 100644 BCEL/bcelifier/LocalVarAccess.java create mode 100644 BCEL/bcelifier/LocalVarAccessCreator.java create mode 100644 src/de/dhbwstuttgart/bytecode/DHBWConstantPoolGen.java create mode 100644 test/bytecode/Runnable.jav create mode 100644 test/bytecode/RunnableTest.java diff --git a/.classpath b/.classpath index 6af9d44ff..ea96f442c 100755 --- a/.classpath +++ b/.classpath @@ -8,7 +8,7 @@ - + diff --git a/BCEL/bcelifier/JavaToBCEL.java b/BCEL/bcelifier/JavaToBCEL.java index bcd9524d4..ef1555d18 100644 --- a/BCEL/bcelifier/JavaToBCEL.java +++ b/BCEL/bcelifier/JavaToBCEL.java @@ -29,6 +29,7 @@ public class JavaToBCEL { new BCELifier(new ClassParser(rootDirectory+"MethodCall.class").parse(), new FileOutputStream(new File(rootDirectory+"MethodCallCreator.java"))).start(); new BCELifier(new ClassParser(rootDirectory+"FieldDeclaration.class").parse(), new FileOutputStream(new File(rootDirectory+"FieldDeclarationCreator.java"))).start(); new BCELifier(new ClassParser(rootDirectory+"Null.class").parse(), new FileOutputStream(new File(rootDirectory+"NullCreator.java"))).start(); + new BCELifier(new ClassParser(rootDirectory+"LocalVarAccess.class").parse(), new FileOutputStream(new File(rootDirectory+"LocalVarAccessCreator.java"))).start(); } catch (ClassFormatException | IOException e) { e.printStackTrace(); diff --git a/BCEL/bcelifier/LocalVarAccess.java b/BCEL/bcelifier/LocalVarAccess.java new file mode 100644 index 000000000..116becbc2 --- /dev/null +++ b/BCEL/bcelifier/LocalVarAccess.java @@ -0,0 +1,10 @@ +package bcelifier; + +public class LocalVarAccess { + Integer methode(Integer i){ + Integer var; + var = 10 + i; + return var; + } + +} diff --git a/BCEL/bcelifier/LocalVarAccessCreator.java b/BCEL/bcelifier/LocalVarAccessCreator.java new file mode 100644 index 000000000..b85fcadb5 --- /dev/null +++ b/BCEL/bcelifier/LocalVarAccessCreator.java @@ -0,0 +1,61 @@ +package bcelifier; + +import org.apache.commons.bcel6.generic.*; +import org.apache.commons.bcel6.classfile.*; +import org.apache.commons.bcel6.*; +import java.io.*; + +public class LocalVarAccessCreator implements Constants { + private InstructionFactory _factory; + private ConstantPoolGen _cp; + private ClassGen _cg; + + public LocalVarAccessCreator() { + _cg = new ClassGen("bcelifier.LocalVarAccess", "java.lang.Object", "LocalVarAccess.java", ACC_PUBLIC | ACC_SUPER, new String[] { }); + + _cp = _cg.getConstantPool(); + _factory = new InstructionFactory(_cg, _cp); + } + + public void create(OutputStream out) throws IOException { + createMethod_0(); + createMethod_1(); + _cg.getJavaClass().dump(out); + } + + private void createMethod_0() { + InstructionList il = new InstructionList(); + MethodGen method = new MethodGen(ACC_PUBLIC, Type.VOID, Type.NO_ARGS, new String[] { }, "", "bcelifier.LocalVarAccess", il, _cp); + + InstructionHandle ih_0 = il.append(_factory.createLoad(Type.OBJECT, 0)); + il.append(_factory.createInvoke("java.lang.Object", "", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); + InstructionHandle ih_4 = il.append(_factory.createReturn(Type.VOID)); + method.setMaxStack(); + method.setMaxLocals(); + _cg.addMethod(method.getMethod()); + il.dispose(); + } + + private void createMethod_1() { + InstructionList il = new InstructionList(); + MethodGen method = new MethodGen(0, new ObjectType("java.lang.Integer"), new Type[] { new ObjectType("java.lang.Integer") }, new String[] { "arg0" }, "methode", "bcelifier.LocalVarAccess", il, _cp); + + InstructionHandle ih_0 = il.append(new PUSH(_cp, 10)); + il.append(_factory.createLoad(Type.OBJECT, 1)); + il.append(_factory.createInvoke("java.lang.Integer", "intValue", Type.INT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); + il.append(InstructionConstants.IADD); + il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC)); + il.append(_factory.createStore(Type.OBJECT, 2)); + InstructionHandle ih_11 = il.append(_factory.createLoad(Type.OBJECT, 2)); + InstructionHandle ih_12 = il.append(_factory.createReturn(Type.OBJECT)); + method.setMaxStack(); + method.setMaxLocals(); + _cg.addMethod(method.getMethod()); + il.dispose(); + } + + public static void main(String[] args) throws Exception { + bcelifier.LocalVarAccessCreator creator = new bcelifier.LocalVarAccessCreator(); + creator.create(new FileOutputStream("bcelifier.LocalVarAccess.class")); + } +} diff --git a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java index f5d0017c9..800a7703a 100644 --- a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java +++ b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java @@ -1,5 +1,7 @@ package de.dhbwstuttgart.bytecode; +import org.apache.commons.bcel6.classfile.InnerClass; +import org.apache.commons.bcel6.classfile.InnerClasses; import org.apache.commons.bcel6.generic.ClassGen; import org.apache.commons.bcel6.generic.ConstantPoolGen; @@ -7,16 +9,22 @@ import de.dhbwstuttgart.syntaxtree.type.Type; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; +import de.dhbwstuttgart.typeinference.exceptions.DebugException; public class ClassGenerator extends ClassGen{ - private DHBWInstructionFactory factory = new DHBWInstructionFactory(this, this.getConstantPool()); + private DHBWConstantPoolGen cp; + private DHBWInstructionFactory factory; private TypeinferenceResultSet tiResult; + private int lambdaMethodeNr = 0; public ClassGenerator(String name, String get_Name, String string, short accPublic, String[] strings, TypeinferenceResultSet resultSet) { - super(name,get_Name,string,accPublic,strings); + super(name,get_Name,string,accPublic,strings, new DHBWConstantPoolGen()); this.tiResult = resultSet; + + cp = (DHBWConstantPoolGen) super.getConstantPool(); + factory = new DHBWInstructionFactory(this, cp); } public DHBWInstructionFactory getInstructionFactory() { @@ -27,4 +35,29 @@ public class ClassGenerator extends ClassGen{ return tiResult.getTypeOfPlaceholder(typePlaceholder); } + public String createLambdaMethodName() { + return "lambda$methode$"+(lambdaMethodeNr++); + } + + @Override + public DHBWConstantPoolGen getConstantPool(){ + return this.cp; + } + + @Override + public void setConstantPool(ConstantPoolGen gen){ + throw new DebugException("Ungültige Operation. ClassGenerator muss ein DHBWConstantPool besitzen"); + } + + /** + * Anmerkung: Kann in diesem Zustand nur einmal aufgerufen werden. + * @param innerClassAttribute + */ + public void addInnerClass(InnerClass innerClassAttribute) { + //TODO: Muss vor dem ausführen von getJavaClass ausgeführt werden. getJavaClass überschreiben! + InnerClass[] innerClasses = new InnerClass[1]; + innerClasses[0] = innerClassAttribute; + int innerClassesUTF8 = this.getConstantPool().addUtf8("InnerClassses"); + this.addAttribute(new InnerClasses(innerClassesUTF8,1,innerClasses,this.getConstantPool().getConstantPool())); + } } diff --git a/src/de/dhbwstuttgart/bytecode/DHBWConstantPoolGen.java b/src/de/dhbwstuttgart/bytecode/DHBWConstantPoolGen.java new file mode 100644 index 000000000..9bcd75d99 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/DHBWConstantPoolGen.java @@ -0,0 +1,35 @@ +package de.dhbwstuttgart.bytecode; + +import java.util.HashMap; + +import org.apache.commons.bcel6.classfile.Constant; +import org.apache.commons.bcel6.classfile.ConstantMethodHandle; +import org.apache.commons.bcel6.classfile.ConstantMethodType; +import org.apache.commons.bcel6.generic.ConstantPoolGen; + +public class DHBWConstantPoolGen extends ConstantPoolGen{ + private static final long serialVersionUID = -8282768548793548585L; + + private final HashMap constantTable = new HashMap<>(); + //private static final String DELIMITER = "$"; + + /* + public int addConstantMethodType(ConstantMethodType methodType) { + if(constantTable.containsKey(methodType))return constantTable.get(methodType); + + } + + public int addConstantMethodHandle(ConstantMethodHandle methodHandle) { + if(constantTable.containsKey(methodHandle))return constantTable.get(methodHandle); + int ret = this.index; + return ret; + } + */ + public int addConstant(Constant c){ + if(constantTable.containsKey(c))return constantTable.get(c); + int ret = this.index; + this.constants[this.index++] = c; + constantTable.put(c, ret); + return ret; + } +} diff --git a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java index 6d0c8e2a4..f8ea3b3c5 100644 --- a/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java +++ b/src/de/dhbwstuttgart/bytecode/DHBWInstructionFactory.java @@ -6,24 +6,28 @@ import java.util.ArrayList; import org.apache.commons.bcel6.Constants; import org.apache.commons.bcel6.classfile.BootstrapMethod; import org.apache.commons.bcel6.classfile.ConstantInvokeDynamic; +import org.apache.commons.bcel6.classfile.ConstantMethodHandle; +import org.apache.commons.bcel6.classfile.ConstantMethodType; import org.apache.commons.bcel6.classfile.InnerClass; import org.apache.commons.bcel6.classfile.Method; import org.apache.commons.bcel6.generic.ClassGen; import org.apache.commons.bcel6.generic.ConstantPoolGen; import org.apache.commons.bcel6.generic.INVOKEDYNAMIC; import org.apache.commons.bcel6.generic.InstructionFactory; +import org.apache.commons.bcel6.generic.InstructionList; +import org.apache.commons.bcel6.generic.LocalVariableInstruction; import org.apache.commons.bcel6.generic.MethodGen; import org.apache.commons.bcel6.generic.Type; public class DHBWInstructionFactory extends InstructionFactory{ - public DHBWInstructionFactory(ClassGen cg, ConstantPoolGen cp) { - super(cg, cp); - } + private DHBWConstantPoolGen cp; + private ClassGenerator cg; - private BootstrapMethod createBootstrapMethod(){ - //TODO - return null; + public DHBWInstructionFactory(ClassGenerator cg, DHBWConstantPoolGen cp) { + super(cg, cp); + this.cp = cp; + this.cg = cg; } public INVOKEDYNAMIC createInvokeDynamic( MethodGen lambdaMethod ) { @@ -38,11 +42,22 @@ public class DHBWInstructionFactory extends InstructionFactory{ * #19 ()V * * #20 ist ein MethodHandle_info Structure - * TODO: Rausfinden, was es mit den Argumenten auf sich hat: - * -> Das sind Informationen die die Lambda Funktion zum Ausführen benötigt. (This-Referenz, Variablen, welche vom Lambda Ausdruck benutzt werden) - * Anmerkung: Bei der momentanen Implementierung der Lambda Ausdrücke wird nur this übergeben. + * Die Argumente werden der Bootstrap Methode beim Aufrufen übergeben: @see https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/LambdaMetafactory.html#metafactory-java.lang.invoke.MethodHandles.Lookup-java.lang.String-java.lang.invoke.MethodType-java.lang.invoke.MethodType-java.lang.invoke.MethodHandle-java.lang.invoke.MethodType- + * TODO: Die korrekten Argumente anfügen. + * - samMethodType - Signature and return type of method to be implemented by the function object. + * - implMethod - A direct method handle describing the implementation method which should be called (with suitable adaptation of argument types, return types, and with captured arguments prepended to the invocation arguments) at invocation time. + * - instantiatedMethodType - The signature and return type that should be enforced dynamically at invocation time. This may be the same as samMethodType, or may be a specialization of it. */ + ConstantMethodType lambdaMethodType = new ConstantMethodType(this.cp.addUtf8(lambdaMethod.getSignature())); + int implMethodKind = 7; // 7 = InvokeSpecial @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.5 + ConstantMethodHandle implMethod = new ConstantMethodHandle(implMethodKind,cg.getConstantPool().addMethodref(lambdaMethod)); //Das zweite Argument ist der MethodRef zur LambdaMethode + + //Argumentliste für die Bootstrap Methode zusammensetzen: + arguments.add(cp.addConstant(lambdaMethodType)); + arguments.add(cp.addConstant(implMethod)); + arguments.add(cp.addConstant(lambdaMethodType)); + int innerClassIndex = cp.addClass("java.lang.invoke.MethodHandles$Lookup"); int innerClassName = cp.addUtf8("Lookup"); @@ -52,6 +67,7 @@ public class DHBWInstructionFactory extends InstructionFactory{ InnerClass innerClassAttribute = new InnerClass(innerClassIndex, outerClassIndex, innerClassName,accessFlags); //Diese InnereKlasse muss später im ClassFile vorkommen, da sie von der Bootstrap Methode benutzt wird. //TODO: Dies kann man möglicherweise auslagern. Die ClassGen Klasse erweiter, welche sich dann die InnerenKlassen mertk, welche gebraucht werden + cg.addInnerClass(innerClassAttribute); String bootstrapSignature = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"; int lambdaMethodIndex = cp.addMethodref("java.lang.invoke.LambdaMetafactory", "metafactory", bootstrapSignature); @@ -62,18 +78,7 @@ public class DHBWInstructionFactory extends InstructionFactory{ } BootstrapMethod bMethod = new BootstrapMethod(lambdaMethodIndex, arguments.size(), argumentsArray); - final short opcode = 186; int index; - /* - int nargs = 0; - String signature = Type.getMethodSignature(ret_type, arg_types); - for (int i = 0; i < arg_types.length; i++) { - nargs += arg_types[i].getSize(); - } - */ - - //index = cp.addInvokeDynamic(bootstrap_index, name, signature); - //Adding invokeDynamic to Constant_Pool: /* * Spezifikation: @see https://docs.oracle.com/javase/specs/jvms/se8/html/index.html @@ -87,11 +92,13 @@ public class DHBWInstructionFactory extends InstructionFactory{ /* * - * TODO: Rausfinden, was es mit der Inneren Klasse auf sich hat + * Was es mit der Inneren Klasse auf sich hat: * (public static final #48= #47 of #51; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles + * Lösung: Ist wohl einfach nur nötig, um die Metafactory durch die Bootstrap-Methode aufzurufen * * TODO: Rausfinden was es mit dem NameAndType Eintrag in der InvokeDynamic_info Struktur auf sich hat: * Für ein Runnable ()->{}; ist es: run:(LLambda3;)Ljava/lang/Runnable; + * Wieso das zusätzliche Argument vom Typ (this) * * TODO: bootstrap_methode den Klassenattributen hinzufügen * @@ -99,13 +106,18 @@ public class DHBWInstructionFactory extends InstructionFactory{ int bootstrap_method_attr_index = bMethod.getBootstrapMethodRef(); //TODO: der Typ der Lambda Methode muss den Typ von this als erstes Argument enthalten, damit this innerhalb der Lambda Methode verwendet werden kann - int name_and_type_index = cp.addNameAndType(lambdaMethod.getName(), lambdaMethod.getType().getSignature()); + int name_and_type_index = cp.addNameAndType(lambdaMethod.getName(), lambdaMethod.getSignature()); ConstantInvokeDynamic cInvokeDynamic = new ConstantInvokeDynamic(bootstrap_method_attr_index, name_and_type_index); - index = cp.addConstant(cInvokeDynamic, cp); + index = cp.addConstant(cInvokeDynamic); return new INVOKEDYNAMIC(index); } + public LocalVariableInstruction createLoad(org.apache.commons.bcel6.generic.Type bytecodeType, String variableName) { + int index = 1; //TODO: Hier muss ein Logger her, welcher aufzeichnet, an welcher Position welche Variable liegt. + return InstructionFactory.createLoad(bytecodeType, index); + } + } diff --git a/src/de/dhbwstuttgart/syntaxtree/Class.java b/src/de/dhbwstuttgart/syntaxtree/Class.java index 804a7af7b..8d4ee492c 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Class.java +++ b/src/de/dhbwstuttgart/syntaxtree/Class.java @@ -20,6 +20,8 @@ import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.logger.Section; import de.dhbwstuttgart.logger.SectionLogger; import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen; +import de.dhbwstuttgart.bytecode.DHBWInstructionFactory; import de.dhbwstuttgart.core.AClassOrInterface; import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.parser.JavaClassName; @@ -75,7 +77,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I */ public ByteCodeResult genByteCode(TypeinferenceResultSet resultSet) { InstructionFactory _factory; - ConstantPoolGen _cp; + DHBWConstantPoolGen _cp; ClassGenerator _cg; SectionLogger logger = Logger.getSectionLogger(this.getClass().getName(), Section.CODEGEN); @@ -84,7 +86,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I if(pkgName != null)throw new NotImplementedException(); _cg = new ClassGenerator(name, superClass.get_Name(), name + ".java", Constants.ACC_PUBLIC , new String[] { }, resultSet); //letzter Parameter sind implementierte Interfaces _cp = _cg.getConstantPool(); - _factory = new InstructionFactory(_cg, _cp); + _factory = new DHBWInstructionFactory(_cg, _cp); //Die Felder in Methoden Felder und Konstruktoren aufteilen: Menge fieldDeclarations = new Menge<>(); diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index 3482d2ef9..e5b23c39c 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -11,6 +11,7 @@ import org.apache.commons.bcel6.generic.MethodGen; import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.misc.DeclId; @@ -57,7 +58,7 @@ public class Constructor extends Method { } public void genByteCode(ClassGenerator cg, InstructionList fieldInitializations){ - ConstantPoolGen _cp = cg.getConstantPool(); + DHBWConstantPoolGen _cp = cg.getConstantPool(); InstructionList il = new InstructionList(); //sollte nicht new sein sondern aus Block kommen Class parentClass = this.getParentClass(); diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index 6029462e4..953391d99 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -18,6 +18,8 @@ import org.apache.commons.bcel6.generic.MethodGen; import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen; +import de.dhbwstuttgart.bytecode.DHBWInstructionFactory; import de.dhbwstuttgart.core.IItemWithOffset; import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.myexception.JVMCodeException; @@ -741,8 +743,8 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable } public void genByteCode(ClassGenerator cg) { - ConstantPoolGen _cp = cg.getConstantPool(); - InstructionFactory _factory = new InstructionFactory(cg, _cp); + DHBWConstantPoolGen _cp = cg.getConstantPool(); + DHBWInstructionFactory _factory = new DHBWInstructionFactory(cg, _cp); InstructionList il = new InstructionList(); Class parentClass = this.getParentClass(); @@ -751,7 +753,7 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable String[] argumentNames = new String[]{}; if(this.parameterlist != null && this.parameterlist.size() > 0){ - argumentTypes = new org.apache.commons.bcel6.generic.Type[this.parameterlist.size()]; + argumentTypes = new org.apache.commons.bcel6.generic.Type[this.parameterlist.size()]; argumentNames = new String[this.parameterlist.size()]; int i = 0; for(FormalParameter parameter : this.parameterlist){ diff --git a/src/de/dhbwstuttgart/syntaxtree/ParameterList.java b/src/de/dhbwstuttgart/syntaxtree/ParameterList.java index acf0934b7..e88ad0ef4 100755 --- a/src/de/dhbwstuttgart/syntaxtree/ParameterList.java +++ b/src/de/dhbwstuttgart/syntaxtree/ParameterList.java @@ -7,6 +7,7 @@ import de.dhbwstuttgart.typeinference.Menge; import java.util.Iterator; +import de.dhbwstuttgart.bytecode.ClassGenerator; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; @@ -144,5 +145,25 @@ public class ParameterList extends SyntaxTreeNode implements Iterable this; } + +} \ No newline at end of file diff --git a/test/bytecode/RunnableTest.java b/test/bytecode/RunnableTest.java new file mode 100644 index 000000000..2eb55d856 --- /dev/null +++ b/test/bytecode/RunnableTest.java @@ -0,0 +1,14 @@ +package bytecode; + +import org.junit.Test; + +public class RunnableTest { + public final static String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/"; + public final static String testFile = "Runnable.jav"; + public final static String outputFile = "Runnable.class"; + + @Test + public void test() { + SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile); + } +} diff --git a/test/bytecode/Test.java b/test/bytecode/Test.java index ed9c705dd..69ff36f6e 100644 --- a/test/bytecode/Test.java +++ b/test/bytecode/Test.java @@ -8,5 +8,6 @@ public static void main(String[] args){ System.out.println(new Return().method()); new MethodCall().method(); System.out.println(new FieldDeclaration().field); + //new Runnable().method().run(); } }