Descriptor-Erzeugen neu mit Visitor-pattern implementiert

This commit is contained in:
Fayez Abu Alia 2017-12-28 10:20:28 +01:00
parent 719d1a5ced
commit 01339ca7ec
12 changed files with 285 additions and 135 deletions

View File

@ -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, "<init>", desc.getDesc(), null, null);
NormalConstructor constructor = new NormalConstructor(field);
String desc = constructor.accept(new DescriptorToString(resultSet));
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", 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();
}

View File

@ -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

View File

@ -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<FormalParameter> 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<String>{
@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<FormalParameter> 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<FormalParameter> 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<RefTypeOrTPHOrWildcardOrGeneric> argumentList,RefTypeOrTPHOrWildcardOrGeneric returnType ,ResultSet resultSet) {
desc = "(";
Iterator<RefTypeOrTPHOrWildcardOrGeneric> 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;
}
}

View File

@ -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<FormalParameter> 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<FormalParameter> 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<FormalParameter> 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<RefTypeOrTPHOrWildcardOrGeneric> 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;
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,31 @@
package de.dhbwstuttgart.bytecode;
import java.util.List;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class SamMethod {
private List<RefTypeOrTPHOrWildcardOrGeneric> argumentList;
private RefTypeOrTPHOrWildcardOrGeneric returnType;
public SamMethod(List<RefTypeOrTPHOrWildcardOrGeneric> argumentList, RefTypeOrTPHOrWildcardOrGeneric returnType) {
this.argumentList = argumentList;
this.returnType = returnType;
}
public List<RefTypeOrTPHOrWildcardOrGeneric> getArgumentList() {
return argumentList;
}
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
return returnType;
}
public String accept(DescriptorVisitor descVisitor) {
return descVisitor.visit(this);
}
}

View File

@ -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<String>{
@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(".", "/");
}
}

View File

@ -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);