From accbe5bbfcfc9953aac56d77cdd136ae4d2f8783 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 9 Nov 2016 16:59:08 +0100 Subject: [PATCH] Beginnen der BytecodeTypeFactory --- .../bytecode/BytecodeTypeFactory.java | 93 +++++++++++++++++++ .../bytecode/ClassGenerator.java | 5 +- .../syntaxtree/factory/ASTFactory.java | 5 +- .../syntaxtree/type/GenericTypeVar.java | 19 ++-- .../syntaxtree/type/RefType.java | 20 ++-- test/bytecode/lambda/Simple.jav | 8 ++ test/bytecode/lambda/SimpleTest.java | 19 ++++ test/bytecode/lambda/Test.java | 5 + test/bytecode/lambda/TestInterface.java | 1 + 9 files changed, 160 insertions(+), 15 deletions(-) create mode 100644 src/de/dhbwstuttgart/bytecode/BytecodeTypeFactory.java create mode 100644 test/bytecode/lambda/Simple.jav create mode 100644 test/bytecode/lambda/SimpleTest.java create mode 100644 test/bytecode/lambda/Test.java create mode 100644 test/bytecode/lambda/TestInterface.java diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeTypeFactory.java b/src/de/dhbwstuttgart/bytecode/BytecodeTypeFactory.java new file mode 100644 index 00000000..d55f9daf --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/BytecodeTypeFactory.java @@ -0,0 +1,93 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.syntaxtree.type.BoundedGenericTypeVar; +import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar; +import de.dhbwstuttgart.syntaxtree.type.ObjectType; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.Type; +import de.dhbwstuttgart.typeinference.exceptions.NotImplementedException; + +public class BytecodeTypeFactory { + + /** + * @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-FieldType + */ + public static String generateFieldDescriptor(Type t){ + String ret = ""; + if(t instanceof RefType){ + ret += "L" + t.getName().toString().replace('.', '/') + ";"; + }else{ + throw new NotImplementedException(); + } + return ret; + } + + /** + * @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-ClassSignature + */ + public static String generateClassSignature(de.dhbwstuttgart.syntaxtree.Class c){ + String ret = ""; + if(c.getGenericParameter() != null && c.getGenericParameter().size() > 0){ + ret += "<"; + for(GenericTypeVar gtv : c.getGenericParameter()){ + ret += generateTypeParameter(gtv); + } + ret += ">"; + } + //Add the SuperClassSignature: + c.getSuperClass(); + ret += generateClassTypeSignature(); + return ret; + } + + public static String generateSuperClassSignature(Type superClass){ + String ret = ""; + //TODO: + throw new NotImplementedException(); + } + + private static String generateTypeParameter(GenericTypeVar gtv){ + String ret = gtv.get_Name() + ":"; + for(ObjectType t : gtv.getBounds()){ + ret += generateReferenceTypeSignature(t); + ret += ":"; + } + ret = ret.substring(0, ret.length()-1); + return ret; + } + + /** + * @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-ClassTypeSignature + */ + private static String generateClassTypeSignature(){ + return null; + } + + /** + * @see https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-ReferenceTypeSignature + */ + private static String generateReferenceTypeSignature(Type t){ + if(t instanceof RefType)return generateReferenceTypeSignature((RefType)t); + if(t instanceof GenericTypeVar)return generateReferenceTypeSignature((GenericTypeVar)t); + throw new NotImplementedException(); + } + + private static String generateReferenceTypeSignature(RefType t){ + String ret = "L" + t.get_Name(); + if(t.getParaList() != null && t.getParaList().size() > 0){ + ret += "<"; + for(Type p : t.getParaList()){ + ret += generateReferenceTypeSignature(p); + } + ret+=">"; + } + return ret + ";"; + } + + private static String generateReferenceTypeSignature(GenericTypeVar t){ + String ret = "T" + t.get_Name(); + return ret + ";"; + } + + +} diff --git a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java index a94dda29..2b8fe81e 100644 --- a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java +++ b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java @@ -158,7 +158,8 @@ public class ClassGenerator extends ClassGen{ //Signatur setzen: String typeParameters = this.generateParameterSignature(); - String superClassSignature = this.superClass.get_Name(); + String superClassSignature = BytecodeTypeFactory.generateSuperClassSignature(this.superClass);//"L" + this.superClass.getBytecodeType(cg, rs) + superClassSignature = superClassSignature.substring(0, superClassSignature.length()-1); //Das ";" am Ende entfernen if(this.superClass instanceof RefType && ((RefType)superClass).get_ParaList() != null && ((RefType)superClass).get_ParaList().size() > 0){ @@ -167,7 +168,7 @@ public class ClassGenerator extends ClassGen{ for(Type param : superRefType.get_ParaList()){ superClassSignature += param.getBytecodeSignature(this, null); } - superClassSignature += ">"; + superClassSignature += ">;"; } String classSignature = typeParameters + superClassSignature; //TOOD: Hier noch die Signaturen der SuperInterfaces anfügen if(classSignature.length()>0){ diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java index 0f7a4fc3..ba682476 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -83,7 +83,10 @@ public class ASTFactory { public static Class createObjectClass() { Class generatedClass = new Class("java.lang.Object", 0); - return generatedClass; } + + public static RefType createObjectType(){ + return createObjectClass().getType(); + } } diff --git a/src/de/dhbwstuttgart/syntaxtree/type/GenericTypeVar.java b/src/de/dhbwstuttgart/syntaxtree/type/GenericTypeVar.java index 39c1e690..b68cb9dc 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/GenericTypeVar.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/GenericTypeVar.java @@ -2,9 +2,12 @@ package de.dhbwstuttgart.syntaxtree.type; // ino.end +import java.util.ArrayList; // ino.module.GenericTypeVar.8671.import import java.util.HashMap; import java.util.Iterator; +import java.util.List; + import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.typeinference.ConstraintsSet; @@ -22,17 +25,14 @@ import de.dhbwstuttgart.parser.JavaClassName; import de.dhbwstuttgart.syntaxtree.Class; import de.dhbwstuttgart.syntaxtree.GTVDeclarationContext; import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; -// ino.class.GenericTypeVar.26505.description type=javadoc +import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; + /** * TODO: Diese Klasse überarbeiten. Pair genericTypeVar ist nicht implementiert. * @author J�rg B�uerle * @version $Date: 2013/09/22 20:12:53 $ */ -// ino.end -// ino.class.GenericTypeVar.26505.declaration public class GenericTypeVar extends ObjectType -// ino.end -// ino.class.GenericTypeVar.26505.body { //Type genericTypeVar; //Menge extendVars = new Menge(); @@ -236,7 +236,14 @@ public class GenericTypeVar extends ObjectType // TODO Bytecode return org.apache.bcel.generic.Type.getType(getSignatureType(null));// new org.apache.bcel.generic.ObjectType("Object"); } - + + public List getBounds() + { + //Gibt eine Liste mit "java.lang.Object" zurück, da jede Generic von Object erbt + ArrayList ret = new ArrayList<>(); + ret.add(ASTFactory.createObjectType()); + return ret; + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java index bbd2b533..f45bc1f2 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java @@ -130,12 +130,13 @@ public class RefType extends ObjectType implements IMatchable //this.parameter = null; } - public RefType(JavaClassName jName, SyntaxTreeNode parent, int offset) { - this(jName.toString(), parent, offset); + + public RefType(JavaClassName name, List parameter, int offset) { + super(name.toString(), null, offset); + this.parameter = parameter; } - - /** + /** * Wandelt die Parameter des RefTypes in TPHs um, sofern es sich um Generische Variablen handelt. * @return */ @@ -590,20 +591,26 @@ public class RefType extends ObjectType implements IMatchable //Bsp.: Ljava/util/Vector; StringBuilder sb = new StringBuilder(); String ret; + List newParams = new ArrayList<>(); if(parameter != null && parameter.size() > 0){ sb.append(getName().toString().replace(".", "%")); sb.append("%%"); for(Type type: parameter){ + Type newParameter; if(type instanceof RefType){ sb.append(((RefType) type).getCombinedType(cg, rs).replace(".", "%")); + newParameter = type; }else if(type instanceof TypePlaceholder){ + newParameter = rs.getTypeOfPlaceholder((TypePlaceholder)type); sb.append(((TypePlaceholder) type).getBytecodeType(cg, rs).toString().replace(".", "%")); }else if(type instanceof WildcardType){ + //TODO: unresolved! return this.getName().toString(); }else{ + newParameter = type; sb.append(type.getBytecodeType(cg, rs).toString().replace(".", "%")); } - + newParams.add(newParameter); sb.append("%"); } ret = sb.toString(); @@ -612,7 +619,8 @@ public class RefType extends ObjectType implements IMatchable } if(!ret.equals(getName().toString())){ //getSuperWildcardTypes(); - Class generatedClass = ASTFactory.createInterface(ret, this, null, null, new SourceFile()); + RefType superClass = new RefType(this.getName(),newParams,this.getOffset()); + Class generatedClass = ASTFactory.createInterface(ret, superClass, null, null, new SourceFile()); cg.addExtraClass(generatedClass.genByteCode(new TypeinferenceResults()).getByteCode()); } diff --git a/test/bytecode/lambda/Simple.jav b/test/bytecode/lambda/Simple.jav new file mode 100644 index 00000000..d29da619 --- /dev/null +++ b/test/bytecode/lambda/Simple.jav @@ -0,0 +1,8 @@ +class Simple{ + +op = (i)->i; + +public void main(){ + op.apply(1); +} +} \ No newline at end of file diff --git a/test/bytecode/lambda/SimpleTest.java b/test/bytecode/lambda/SimpleTest.java new file mode 100644 index 00000000..9ca78037 --- /dev/null +++ b/test/bytecode/lambda/SimpleTest.java @@ -0,0 +1,19 @@ +package bytecode.lambda; + +import org.junit.Test; + +import bytecode.SourceFileBytecodeTest; + +public class SimpleTest extends SourceFileBytecodeTest{ + @Override + protected void init() { + testName = "Simple"; + rootDirectory = System.getProperty("user.dir")+"/test/bytecode/lambda/"; + } + + @Test + public void testConstruct() throws Exception{ + this.testMethod("main"); + assertTrue(true); + } +} diff --git a/test/bytecode/lambda/Test.java b/test/bytecode/lambda/Test.java new file mode 100644 index 00000000..70efddea --- /dev/null +++ b/test/bytecode/lambda/Test.java @@ -0,0 +1,5 @@ +class Test{ + public static void main(String[] args){ + new Simple().main(); +} +} diff --git a/test/bytecode/lambda/TestInterface.java b/test/bytecode/lambda/TestInterface.java new file mode 100644 index 00000000..5b92f6c9 --- /dev/null +++ b/test/bytecode/lambda/TestInterface.java @@ -0,0 +1 @@ +interface TestInterface extends Fun1{}