diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 6f7acd64..1b6ef47b 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -88,11 +88,12 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(Constructor field) { - Descriptor desc = new Descriptor(field, resultSet); - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", desc.getDesc(), null, null); + NormalConstructor constructor = new NormalConstructor(field); + String desc = constructor.accept(new DescriptorToString(resultSet)); + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", desc, null, null); mv.visitCode(); System.out.println("-----Constructor-----"); - BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,desc.getDesc(),cw,isInterface); + BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,desc,cw,isInterface); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); @@ -104,12 +105,15 @@ public class BytecodeGen implements ASTVisitor { // TODO: check if the method is static => if static then the first param will be stored in pos 0 // else it will be stored in pos 1 and this will be stored in pos 0 method.getParameterList().accept(this); - Descriptor methDesc = new Descriptor(method,resultSet); + + NormalMethod meth = new NormalMethod(method); + String methDesc = meth.accept(new DescriptorToString(resultSet)); + System.out.println("-----Method-----"); - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methDesc.getDesc(), null, null); + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methDesc, null, null); mv.visitCode(); - BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,methDesc.getDesc(),cw,isInterface); + BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,methDesc,cw,isInterface); mv.visitMaxs(0, 0); mv.visitEnd(); } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index c2acaba0..ffdf1450 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -94,7 +94,8 @@ public class BytecodeGenMethod implements StatementVisitor{ } private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) { - return resultSet.resolveType(type).resolvedType.toString().replace(".", "/"); +// return resultSet.resolveType(type).resolvedType.toString().replace(".", "/"); + return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor()); } @@ -164,7 +165,9 @@ public class BytecodeGenMethod implements StatementVisitor{ public void visit(LambdaExpression lambdaExpression) { System.out.println("\n++ In Lambda: "); this.lamCounter++; - Descriptor lamDesc = new Descriptor(lambdaExpression, resultSet); + + Lambda lam = new Lambda(lambdaExpression); + String lamDesc = lam.accept(new DescriptorToString(resultSet)); //Call site, which, when invoked, returns an instance of the functional interface to which //the lambda is being converted MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, @@ -175,9 +178,9 @@ public class BytecodeGenMethod implements StatementVisitor{ "metafactory", mt.toMethodDescriptorString(), false); String methodName = "lambda$new$" + this.lamCounter; // Type erasure - Type arg1 = Type.getMethodType(lamDesc.getDesc()); + Type arg1 = Type.getMethodType(lamDesc); // real Type - Type arg3 = Type.getMethodType(lamDesc.getDesc()); + Type arg3 = Type.getMethodType(lamDesc); int staticOrSpecial=0; int staticOrInstance=0; @@ -197,12 +200,12 @@ public class BytecodeGenMethod implements StatementVisitor{ Handle arg2 = new Handle(staticOrSpecial, this.className, methodName, arg3.toString(),false); // Descriptor of functional interface methode - Descriptor fiMethodDesc = new Descriptor(kindOfLambda.getArgumentList(), lambdaExpression.getType(),resultSet); - + SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType()); // Desc: (this/nothing)TargetType - mv.visitInvokeDynamicInsn("apply", fiMethodDesc.getDesc(), bootstrap, + String fiMethodDesc = samMethod.accept(new DescriptorToString(resultSet)); + mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2,arg3); - + MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ staticOrInstance + Opcodes.ACC_SYNTHETIC, methodName, arg3.toString(), null, null); @@ -274,17 +277,18 @@ public class BytecodeGenMethod implements StatementVisitor{ methodCall.receiver.accept(this); methodCall.arglist.accept(this); - Descriptor mDesc = new Descriptor(methodCall.arglist, methodCall.getType(),resultSet); + MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType()); + String mDesc = method.accept(new DescriptorToString(resultSet)); System.out.println("is Vars empty: "+varsFunInterface.isEmpty()); // is methodCall.receiver functional Interface)? if(varsFunInterface.contains(methodCall.receiver.getType())) { mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), - methodCall.name, mDesc.getDesc(), false); + methodCall.name, mDesc, false); }else { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()), - methodCall.name, mDesc.getDesc(), isInterface); + methodCall.name, mDesc, isInterface); } // test // if(!methodCall.getType().toString().equals("V")) { @@ -303,7 +307,7 @@ public class BytecodeGenMethod implements StatementVisitor{ methodCall.arglist.accept(this); String d = "("; for(Expression e : methodCall.arglist.getArguments()) { - d = d + "L"+e.getType().toString().replace(".", "/") + ";"; + d = d + "L"+getResolvedType(e.getType()) + ";"; } d += ")V"; @@ -339,7 +343,7 @@ public class BytecodeGenMethod implements StatementVisitor{ System.out.println("In StaticClassName: "); // mv.visitMethodInsn(Opcodes.INVOKESTATIC, staticClassName.getType().toString().replace(".", "/"), // staticClassName.toString(), staticClassName.getType().toString(), false); - mv.visitFieldInsn(Opcodes.GETSTATIC, staticClassName.getType().toString().replace(".", "/"), + mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()), fieldName, fieldDesc); } @@ -379,7 +383,7 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(Literal literal) { // value? - mv.visitLdcInsn(literal.getType().toString()); + mv.visitLdcInsn(getResolvedType(literal.getType())); } @Override @@ -399,8 +403,8 @@ public class BytecodeGenMethod implements StatementVisitor{ // array slot onto the top of the operand stack. assignLeftSide.field.receiver.accept(this); this.rightSideTemp.accept(this); - mv.visitFieldInsn(Opcodes.PUTFIELD, assignLeftSide.field.receiver.getType().toString(), - assignLeftSide.field.fieldVarName, assignLeftSide.field.getType().toString()); + mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()), + assignLeftSide.field.fieldVarName, getResolvedType(assignLeftSide.field.getType())); } @Override diff --git a/src/de/dhbwstuttgart/bytecode/Descriptor.java b/src/de/dhbwstuttgart/bytecode/Descriptor.java deleted file mode 100644 index 3b024d71..00000000 --- a/src/de/dhbwstuttgart/bytecode/Descriptor.java +++ /dev/null @@ -1,112 +0,0 @@ -package de.dhbwstuttgart.bytecode; - -import java.util.List; -import java.util.Iterator; - -import de.dhbwstuttgart.exceptions.NotImplementedException; -import de.dhbwstuttgart.syntaxtree.Constructor; -import de.dhbwstuttgart.syntaxtree.FormalParameter; -import de.dhbwstuttgart.syntaxtree.Method; -import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; -import de.dhbwstuttgart.syntaxtree.statement.Expression; -import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; -import de.dhbwstuttgart.syntaxtree.type.*; -import de.dhbwstuttgart.typeinference.result.ResultSet; - -public class Descriptor { - String desc; - - public Descriptor(Method method, ResultSet resultSet) { - desc = "("; - Iterator itr = method.getParameterList().iterator(); - while(itr.hasNext()) { - FormalParameter fp = itr.next(); - desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; - } - desc = addReturnType(desc,method.getReturnType(), resultSet); - - - } - - private class TypeToDescriptor implements TypeVisitor{ - - @Override - public String visit(RefType refType) { - return refType.getName().toString().replace(".", "/"); - } - - @Override - public String visit(SuperWildcardType superWildcardType) { - throw new NotImplementedException(); - } - - @Override - public String visit(TypePlaceholder typePlaceholder) { - return typePlaceholder.toString(); - } - - @Override - public String visit(ExtendsWildcardType extendsWildcardType) { - throw new NotImplementedException(); - } - - @Override - public String visit(GenericRefType genericRefType) { - return genericRefType.getParsedName(); - } - } - - private String addReturnType(String desc2, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) { - System.out.println("DescType = "+returnType.toString()); - if(resultSet.resolveType(returnType).resolvedType.toString().equals("void")){ - desc = desc + ")V"; - }else { - desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.toString().replace(".", "/")+";"; - } - return desc; - } - - public Descriptor(Constructor constructor, ResultSet resultSet) { - desc = "("; - Iterator itr = constructor.getParameterList().iterator(); - while(itr.hasNext()) { - FormalParameter fp = itr.next(); - desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "/") + ";"; - } - desc = desc + ")V"; - } - - public Descriptor(LambdaExpression lambdaExpr, ResultSet resultSet) { - desc = "("; - Iterator itr = lambdaExpr.params.iterator(); - while(itr.hasNext()) { - FormalParameter fp = itr.next(); - desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "/") + ";"; - } - desc = addReturnType(desc, lambdaExpr.getReturnType(), resultSet); - } - - public Descriptor(ArgumentList argList, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) { - desc = "("; - for(Expression e : argList.getArguments()) { - desc = desc + "L"+resultSet.resolveType(e.getType()).resolvedType.toString().replace(".", "/") + ";"; - } - desc = addReturnType(desc, returnType, resultSet); - - } - - public Descriptor(List argumentList,RefTypeOrTPHOrWildcardOrGeneric returnType ,ResultSet resultSet) { - desc = "("; - Iterator itr = argumentList.iterator(); - while(itr.hasNext()) { - RefTypeOrTPHOrWildcardOrGeneric rt = itr.next(); - desc = desc + "L"+resultSet.resolveType(rt).resolvedType.toString().replace(".", "/")+";"; - } - desc = desc + ")"+"L"+resultSet.resolveType(returnType).resolvedType.toString().replace(".", "/")+";"; - } - - public String getDesc() { - return this.desc; - } - -} diff --git a/src/de/dhbwstuttgart/bytecode/DescriptorToString.java b/src/de/dhbwstuttgart/bytecode/DescriptorToString.java new file mode 100644 index 00000000..044218e4 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/DescriptorToString.java @@ -0,0 +1,85 @@ +package de.dhbwstuttgart.bytecode; + +import java.util.Iterator; + +import de.dhbwstuttgart.syntaxtree.FormalParameter; +import de.dhbwstuttgart.syntaxtree.statement.Expression; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.typeinference.result.ResultSet; + +public class DescriptorToString implements DescriptorVisitor{ + ResultSet resultSet; + + public DescriptorToString(ResultSet resultSet) { + this.resultSet = resultSet; + } + + private String addReturnType(String desc, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) { + if(resultSet.resolveType(returnType).resolvedType.toString().equals("void")){ + desc = desc + ")V"; + }else { + desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + return desc; + } + + @Override + public String visit(NormalMethod method) { + + String desc = "("; + Iterator itr = method.getParameterList().iterator(); + while(itr.hasNext()) { + FormalParameter fp = itr.next(); + desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + desc = addReturnType(desc,method.getReturnType(), resultSet); + return desc; + } + + @Override + public String visit(NormalConstructor constructor) { + String desc = "("; + Iterator itr = constructor.getParameterList().iterator(); + while(itr.hasNext()) { + FormalParameter fp = itr.next(); + desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + desc = desc + ")V"; + return desc; + } + + @Override + public String visit(Lambda lambdaExpression) { + String desc = "("; + Iterator itr = lambdaExpression.getParams().iterator(); + while(itr.hasNext()) { + FormalParameter fp = itr.next(); + desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";"; + } + desc = addReturnType(desc, lambdaExpression.getReturnType(), resultSet); + return desc; + } + + @Override + public String visit(SamMethod samMethod) { + String desc = "("; + Iterator itr = samMethod.getArgumentList().iterator(); + while(itr.hasNext()) { + RefTypeOrTPHOrWildcardOrGeneric rt = itr.next(); + desc = desc + "L"+resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor())+";"; + } + desc = desc + ")"+"L"+resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+";"; + return desc; + } + + @Override + public String visit(MethodFromMethodCall methodFromMethodCall) { + String desc = "("; + for(Expression e : methodFromMethodCall.argList.getArguments()) { + desc = desc + "L"+resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + desc = addReturnType(desc, methodFromMethodCall.returnType, resultSet); + return desc; + } + +} diff --git a/src/de/dhbwstuttgart/bytecode/DescriptorVisitor.java b/src/de/dhbwstuttgart/bytecode/DescriptorVisitor.java new file mode 100644 index 00000000..63198828 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/DescriptorVisitor.java @@ -0,0 +1,9 @@ +package de.dhbwstuttgart.bytecode; + +public interface DescriptorVisitor { + public String visit(NormalMethod method); + public String visit(NormalConstructor constructor); + public String visit(Lambda lambdaExpression); + public String visit(SamMethod samMethod); + public String visit(MethodFromMethodCall methodFromMethodCall); +} diff --git a/src/de/dhbwstuttgart/bytecode/Lambda.java b/src/de/dhbwstuttgart/bytecode/Lambda.java new file mode 100644 index 00000000..283b7393 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/Lambda.java @@ -0,0 +1,25 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + +public class Lambda { + private LambdaExpression lambdaExpression; + + public Lambda(LambdaExpression lambdaExpression) { + this.lambdaExpression = lambdaExpression; + } + + public ParameterList getParams() { + return lambdaExpression.params; + } + + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { + return lambdaExpression.getReturnType(); + } + + public String accept(DescriptorVisitor descVisitor) { + return descVisitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java b/src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java new file mode 100644 index 00000000..034e2abf --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java @@ -0,0 +1,18 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + +public class MethodFromMethodCall { + ArgumentList argList; + RefTypeOrTPHOrWildcardOrGeneric returnType; + + public MethodFromMethodCall(ArgumentList argList,RefTypeOrTPHOrWildcardOrGeneric returnType) { + this.argList = argList; + this.returnType = returnType; + } + + public String accept(DescriptorVisitor descVisitor) { + return descVisitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/bytecode/NormalConstructor.java b/src/de/dhbwstuttgart/bytecode/NormalConstructor.java new file mode 100644 index 00000000..d029d21e --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/NormalConstructor.java @@ -0,0 +1,20 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.syntaxtree.Constructor; +import de.dhbwstuttgart.syntaxtree.ParameterList; + +public class NormalConstructor { + private Constructor constructor; + + public NormalConstructor(Constructor constructor) { + this.constructor = constructor; + } + + public ParameterList getParameterList() { + return constructor.getParameterList(); + } + + public String accept(DescriptorVisitor descVisitor) { + return descVisitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/bytecode/NormalMethod.java b/src/de/dhbwstuttgart/bytecode/NormalMethod.java new file mode 100644 index 00000000..2dd81d78 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/NormalMethod.java @@ -0,0 +1,29 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + +public class NormalMethod { + private Method method; + + public NormalMethod(Method method) { + this.method = method; + } + + public Method getMethod() { + return method; + } + + public ParameterList getParameterList() { + return method.getParameterList(); + } + + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { + return method.getType(); + } + + public String accept(DescriptorVisitor descVisitor) { + return descVisitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/bytecode/SamMethod.java b/src/de/dhbwstuttgart/bytecode/SamMethod.java new file mode 100644 index 00000000..9cf039a2 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/SamMethod.java @@ -0,0 +1,31 @@ +package de.dhbwstuttgart.bytecode; + +import java.util.List; + +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + +public class SamMethod { + private List argumentList; + private RefTypeOrTPHOrWildcardOrGeneric returnType; + + public SamMethod(List argumentList, RefTypeOrTPHOrWildcardOrGeneric returnType) { + this.argumentList = argumentList; + this.returnType = returnType; + } + + public List getArgumentList() { + return argumentList; + } + + + + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { + return returnType; + } + + + + public String accept(DescriptorVisitor descVisitor) { + return descVisitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/bytecode/TypeToDescriptor.java b/src/de/dhbwstuttgart/bytecode/TypeToDescriptor.java new file mode 100644 index 00000000..5271e63d --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/TypeToDescriptor.java @@ -0,0 +1,37 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.exceptions.NotImplementedException; +import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.syntaxtree.type.TypeVisitor; + +public class TypeToDescriptor implements TypeVisitor{ + + @Override + public String visit(RefType refType) { + return refType.getName().toString().replace(".", "/"); + } + + @Override + public String visit(SuperWildcardType superWildcardType) { + throw new NotImplementedException(); + } + + @Override + public String visit(TypePlaceholder typePlaceholder) { + return typePlaceholder.toString().replace(".", "/"); + } + + @Override + public String visit(ExtendsWildcardType extendsWildcardType) { + throw new NotImplementedException(); + } + + @Override + public String visit(GenericRefType genericRefType) { + return genericRefType.getParsedName().replace(".", "/"); + } +} \ No newline at end of file diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java index f43a0740..39ff5084 100644 --- a/test/bytecode/JavaTXCompilerTest.java +++ b/test/bytecode/JavaTXCompilerTest.java @@ -29,7 +29,7 @@ public class JavaTXCompilerTest { @Test public void test() throws IOException, java.lang.ClassNotFoundException { System.out.println(rootDirectory); - String fileName = "Generics"; + String fileName = "Faculty"; filesToTest.add(new File(rootDirectory+fileName+".jav")); System.out.println(rootDirectory+fileName+".jav"); JavaTXCompiler compiler = new JavaTXCompiler(filesToTest);