diff --git a/src/de/dhbwstuttgart/bytecode/TypePlaceholderType.java b/src/de/dhbwstuttgart/bytecode/TypePlaceholderType.java new file mode 100644 index 00000000..3c0d2929 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/TypePlaceholderType.java @@ -0,0 +1,12 @@ +package de.dhbwstuttgart.bytecode; + +import org.apache.commons.bcel6.Constants; +import org.apache.commons.bcel6.generic.ReferenceType; + +public class TypePlaceholderType extends ReferenceType{ + + public TypePlaceholderType(String name) { + super(Constants.T_REFERENCE, "T" + name + ";"); + } + +} \ No newline at end of file diff --git a/src/de/dhbwstuttgart/bytecode/WildcardType.java b/src/de/dhbwstuttgart/bytecode/WildcardType.java index 9be49eda..2f1cb3ee 100644 --- a/src/de/dhbwstuttgart/bytecode/WildcardType.java +++ b/src/de/dhbwstuttgart/bytecode/WildcardType.java @@ -10,7 +10,7 @@ public class WildcardType extends ReferenceType{ public WildcardType(String class_name, String preString) { super(Constants.T_REFERENCE, preString + "L" + class_name.replace('.', '/') + ";"); - this.type = Constants.T_UNKNOWN; + //this.type = Constants.T_UNKNOWN; } } diff --git a/src/de/dhbwstuttgart/syntaxtree/Class.java b/src/de/dhbwstuttgart/syntaxtree/Class.java index 8d4ee492..908724e3 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Class.java +++ b/src/de/dhbwstuttgart/syntaxtree/Class.java @@ -111,6 +111,20 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I c.genByteCode(_cg, fieldInitializations); } + String typeAttributeSignature = ""; + if(this.getGenericParameter() != null && this.getGenericParameter().size()>0){ + typeAttributeSignature = "<"; + for(GenericTypeVar gp : this.getGenericParameter()){ + typeAttributeSignature+=gp.getBytecodeSignature(_cg); + } + typeAttributeSignature+=">"; + } + String superClassSignature = this.getSuperClass().getBytecodeSignature(_cg); + String classSignature = typeAttributeSignature + superClassSignature; + if(classSignature.length()>0){ + _cg.addAttribute(new Signature(_cp.addUtf8("Signature"),2,_cp.addUtf8(classSignature),_cp.getConstantPool())); + } + ByteCodeResult code = new ByteCodeResult(_cg); return code; } diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index e5b23c39..737feb95 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -12,11 +12,13 @@ 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.bytecode.DHBWInstructionFactory; import de.dhbwstuttgart.myexception.JVMCodeException; import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.misc.DeclId; import de.dhbwstuttgart.syntaxtree.modifier.Modifiers; import de.dhbwstuttgart.syntaxtree.statement.Block; +import de.dhbwstuttgart.syntaxtree.statement.Return; import de.dhbwstuttgart.syntaxtree.statement.SuperCall; import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.RefType; @@ -30,6 +32,7 @@ import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions; +import de.dhbwstuttgart.typeinference.exceptions.DebugException; import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint; import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet; @@ -70,10 +73,13 @@ public class Constructor extends Method { Block block = this.get_Block(); if(block.statements.firstElement() instanceof SuperCall){ block.statements.insertElementAt(new BytecodeInstructionBlock(fieldInitializations), 1); + }else{ + throw new DebugException("Fehlender SuperCall im Konstruktor"); } InstructionList blockInstructions = block.genByteCode(cg); - il.append(blockInstructions);//Die vom Block generierten Instructions an die InstructionList der Methode anfügen + il.append(blockInstructions); + il.append(DHBWInstructionFactory.createReturn( org.apache.commons.bcel6.generic.Type.VOID)); //Konstruktor hat immer VOID Return type this.method.setMaxStack(); //Die Stack Größe automatisch berechnen lassen (erst nach dem alle Instructions angehängt wurden) diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index 7f9a06a1..7f92cb25 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -8,6 +8,7 @@ import java.util.Hashtable; import java.util.Iterator; import org.apache.commons.bcel6.Constants; +import org.apache.commons.bcel6.classfile.Signature; import org.apache.commons.bcel6.generic.ClassGen; import org.apache.commons.bcel6.generic.ConstantPoolGen; import org.apache.commons.bcel6.generic.InstructionFactory; @@ -780,6 +781,16 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable method.setMaxStack(); //Die Stack Größe automatisch berechnen lassen (erst nach dem alle Instructions angehängt wurden) method.setMaxLocals(); + + //Die korrekte Signatur für die Methode anhängen. Hier sind dann auch die Parameter von RefTypes enthalten: + String paramTypesSig = "("; + for(FormalParameter p : this.parameterlist){ + paramTypesSig += p.getType().getBytecodeSignature(cg); + } + paramTypesSig += ")"; + String retTypeSig = this.getType().getBytecodeSignature(cg); + method.addAttribute(new Signature(_cp.addUtf8("Signature"),2,_cp.addUtf8(paramTypesSig+retTypeSig),_cp.getConstantPool())); + cg.addMethod(method.getMethod()); } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java index 378a52c3..6b6d45c3 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java @@ -99,7 +99,7 @@ public class SuperCall extends ThisCall //Instructionhandle dynamisch InstructionHandle ih_0 = il.append(_factory.createLoad( org.apache.commons.bcel6.generic.Type.OBJECT, 0)); il.append(_factory.createInvoke(superClass.getName().toString(), "", org.apache.commons.bcel6.generic.Type.VOID, org.apache.commons.bcel6.generic.Type.NO_ARGS, Constants.INVOKESPECIAL)); - InstructionHandle ih_4 = il.append(_factory.createReturn( org.apache.commons.bcel6.generic.Type.VOID)); + //InstructionHandle ih_4 = il.append(_factory.createReturn( org.apache.commons.bcel6.generic.Type.VOID)); return il; } diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java index 1574b65d..f444b601 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java @@ -814,21 +814,26 @@ public class RefType extends ObjectType implements IMatchable } public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) { + return new org.apache.commons.bcel6.generic.ObjectType(this.getTypeName()); + } + + @Override + public String getBytecodeSignature(ClassGenerator cg) { String paramString = ""; - boolean printParameterList = false; //Die ParameterListe wird wohl nicht in allen Fällen gebraucht - if(printParameterList && - this.parameter != null && this.parameter.size()>0){ + if(this.parameter != null && this.parameter.size()>0){ paramString+="<"; Iterator it = this.parameter.iterator(); while(it.hasNext()){ Type param = it.next(); - paramString+=param.getBytecodeType(cg); + paramString+=param.getBytecodeType(cg).getSignature(); //if(it.hasNext()) //paramString+=";"; //kein Delimiter zwischen den Typen } paramString+=">"; } - return new org.apache.commons.bcel6.generic.ObjectType(this.getTypeName()+paramString); + String typeSignature = this.getBytecodeType(cg).getSignature(); + typeSignature = typeSignature.substring(0, typeSignature.length()-1); + return typeSignature+paramString+";"; } } diff --git a/src/de/dhbwstuttgart/syntaxtree/type/Type.java b/src/de/dhbwstuttgart/syntaxtree/type/Type.java index c365723d..6f2d83e6 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/Type.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/Type.java @@ -306,6 +306,9 @@ public abstract class Type extends SyntaxTreeNode implements IItemWithOffset } public abstract org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg); - + + public String getBytecodeSignature(ClassGenerator cg) { + return this.getBytecodeType(cg).getSignature(); + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java b/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java index 755be5fd..91065f4c 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java @@ -9,6 +9,7 @@ import java.util.Iterator; import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.logger.*; import de.dhbwstuttgart.bytecode.ClassGenerator; +import de.dhbwstuttgart.bytecode.TypePlaceholderType; import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; @@ -431,9 +432,10 @@ public class TypePlaceholder extends ObjectType @Override public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) { - //throw new TypeinferenceException("Zuerst alle Typen einsetzen vor dem Kompiliervorgang",this); Type resolvedType = cg.resolveTPH(this); - if(resolvedType instanceof TypePlaceholder)throw new DebugException("Kann TypePlaceholder nicht auflösen"); + if(resolvedType instanceof TypePlaceholder){ + return new TypePlaceholderType(resolvedType.get_Name()); + } return resolvedType.getBytecodeType(cg); } diff --git a/test/bytecode/Fun1.java b/test/bytecode/Fun1.java new file mode 100644 index 00000000..a082da67 --- /dev/null +++ b/test/bytecode/Fun1.java @@ -0,0 +1,3 @@ +interface Fun1{ +A apply(B p); +} diff --git a/test/bytecode/GenericsTest.java b/test/bytecode/GenericsTest.java new file mode 100644 index 00000000..81fedac0 --- /dev/null +++ b/test/bytecode/GenericsTest.java @@ -0,0 +1,3 @@ +class GenericsTest{ +Fun0 op; +} diff --git a/test/bytecode/Identity.jav b/test/bytecode/Identity.jav new file mode 100644 index 00000000..0c5443cc --- /dev/null +++ b/test/bytecode/Identity.jav @@ -0,0 +1,5 @@ +class Identity{ + +op = (x)->x; + +} \ No newline at end of file diff --git a/test/bytecode/IdentityTest.java b/test/bytecode/IdentityTest.java new file mode 100644 index 00000000..7d5493ee --- /dev/null +++ b/test/bytecode/IdentityTest.java @@ -0,0 +1,14 @@ +package bytecode; + +import org.junit.Test; + +public class IdentityTest { + public final static String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/"; + public final static String testFile = "Identity.jav"; + public final static String outputFile = "Identity.class"; + + @Test + public void test() { + SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile); + } +} diff --git a/test/bytecode/Test.java b/test/bytecode/Test.java index 5b917d36..1e879e4a 100644 --- a/test/bytecode/Test.java +++ b/test/bytecode/Test.java @@ -3,11 +3,12 @@ */ class Test{ public static void main(String[] args){ - /*new EmptyClass(); + new EmptyClass(); new Assign(); System.out.println(new Return().method()); new MethodCall().method(); - System.out.println(new FieldDeclaration().field);*/ + System.out.println(new FieldDeclaration().field); System.out.println(new Runnable().method().apply()); + Runnable r = new Runnable().method().apply(); } }