forked from JavaTX/JavaCompilerCore
Merge branch 'bytecode2' into simplifyRes
This commit is contained in:
commit
0138e4fe2d
@ -1,9 +1,5 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.invoke.CallSite;
|
import java.lang.invoke.CallSite;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
@ -14,11 +10,10 @@ import java.net.URLClassLoader;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.*;
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr.Operator;
|
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr.Operator;
|
||||||
@ -30,28 +25,15 @@ import org.objectweb.asm.Label;
|
|||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.signature.SignatureVisitor;
|
|
||||||
import org.objectweb.asm.signature.SignatureWriter;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
|
import de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
|
||||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.KindOfLambda;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.Lambda;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.MethodCallHelper;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.Resolver;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
|
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
@ -64,7 +46,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
private MethodVisitor mv;
|
private MethodVisitor mv;
|
||||||
private HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
private HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
||||||
private String className;
|
private String className;
|
||||||
private int lamCounter = -1;
|
private int lamCounter;
|
||||||
private ClassWriter cw;
|
private ClassWriter cw;
|
||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
private boolean isInterface;
|
private boolean isInterface;
|
||||||
@ -114,6 +96,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
this.sf = sf;
|
this.sf = sf;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
|
this.lamCounter = -1;
|
||||||
this.constructorPos = constructorPos;
|
this.constructorPos = constructorPos;
|
||||||
if(block != null)
|
if(block != null)
|
||||||
this.blockFieldInit = block;
|
this.blockFieldInit = block;
|
||||||
@ -140,16 +123,17 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
this.sf = sf;
|
this.sf = sf;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
|
this.lamCounter = -1;
|
||||||
if (!isInterface)
|
if (!isInterface)
|
||||||
this.m.block.accept(this);
|
this.m.block.accept(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BytecodeGenMethod(LambdaExpression lambdaExpression, ArrayList<String> usedVars, ResultSet resultSet, MethodVisitor mv,
|
public BytecodeGenMethod(String className, ClassWriter cw, LambdaExpression lambdaExpression, ArrayList<String> usedVars, ResultSet resultSet, MethodVisitor mv,
|
||||||
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles, String path, int lamCounter, SourceFile sf,HashMap<String, String> genericsAndBoundsMethod,
|
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles, String path, int lamCounter, SourceFile sf,HashMap<String, String> genericsAndBoundsMethod,
|
||||||
HashMap<String, String> genericsAndBounds) {
|
HashMap<String, String> genericsAndBounds) {
|
||||||
|
this.className = className;
|
||||||
|
this.cw = cw;
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.resolver = new Resolver(resultSet);
|
this.resolver = new Resolver(resultSet);
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
@ -192,7 +176,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
stmt.accept(this);
|
stmt.accept(this);
|
||||||
if(stmt instanceof MethodCall) {
|
if(stmt instanceof MethodCall) {
|
||||||
String ret = resolver.getResolvedType(((MethodCall) stmt).getType());
|
String ret = resolver.getResolvedType(((MethodCall) stmt).getType());
|
||||||
if(!ret.equals("void"))
|
if(!ret.equals(CONSTANTS.VOID))
|
||||||
mv.visitInsn(Opcodes.POP);
|
mv.visitInsn(Opcodes.POP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,7 +251,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
System.out.println("ASSIGN TYPE R: " + resolver.getResolvedType(assign.rightSide.getType()));
|
System.out.println("ASSIGN TYPE R: " + resolver.getResolvedType(assign.rightSide.getType()));
|
||||||
String typeOfRightSide = resolver.getResolvedType(assign.rightSide.getType());
|
String typeOfRightSide = resolver.getResolvedType(assign.rightSide.getType());
|
||||||
if(typeOfRightSide.contains("<")) {
|
if(typeOfRightSide.contains(CONSTANTS.ANGLEBRACKET)) {
|
||||||
mv.visitTypeInsn(Opcodes.CHECKCAST, typeOfRightSide.substring(0, typeOfRightSide.indexOf('<')));
|
mv.visitTypeInsn(Opcodes.CHECKCAST, typeOfRightSide.substring(0, typeOfRightSide.indexOf('<')));
|
||||||
}
|
}
|
||||||
assign.lefSide.accept(this);
|
assign.lefSide.accept(this);
|
||||||
@ -380,11 +364,11 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
private void doCast(String sourceType, String dest) {
|
private void doCast(String sourceType, String dest) {
|
||||||
switch (dest) {
|
switch (dest) {
|
||||||
case "java/lang/Long":
|
case CONSTANTS.REFTYPE_LONG:
|
||||||
mv.visitInsn(Opcodes.I2L);
|
mv.visitInsn(Opcodes.I2L);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "java/lang/Double":
|
case CONSTANTS.REFTYPE_DOUBLE:
|
||||||
if (sourceType.equals(Type.getInternalName(Long.class))) {
|
if (sourceType.equals(Type.getInternalName(Long.class))) {
|
||||||
mv.visitInsn(Opcodes.L2D);
|
mv.visitInsn(Opcodes.L2D);
|
||||||
} else if (sourceType.equals(Type.getInternalName(Float.class))) {
|
} else if (sourceType.equals(Type.getInternalName(Float.class))) {
|
||||||
@ -394,7 +378,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "java/lang/Float":
|
case CONSTANTS.REFTYPE_FLOAT:
|
||||||
if (sourceType.equals(Type.getInternalName(Long.class))) {
|
if (sourceType.equals(Type.getInternalName(Long.class))) {
|
||||||
mv.visitInsn(Opcodes.L2F);
|
mv.visitInsn(Opcodes.L2F);
|
||||||
} else {
|
} else {
|
||||||
@ -402,7 +386,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// braucht man eigentlich nicht, muss getestet werden
|
// braucht man eigentlich nicht, muss getestet werden
|
||||||
case "java/lang/String":
|
case CONSTANTS.REFTYPE_STRING:
|
||||||
if (sourceType.equals(Type.getInternalName(Double.class))) {
|
if (sourceType.equals(Type.getInternalName(Double.class))) {
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
|
||||||
"(D)Ljava/lang/String;", false);
|
"(D)Ljava/lang/String;", false);
|
||||||
@ -425,15 +409,15 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
private void doVisitRelOpInsn(Operator op, String typeOfBinary, Label branchLabel, Label endLabel) {
|
private void doVisitRelOpInsn(Operator op, String typeOfBinary, Label branchLabel, Label endLabel) {
|
||||||
System.out.println("TypeOfBinary: " + typeOfBinary);
|
System.out.println("TypeOfBinary: " + typeOfBinary);
|
||||||
switch (typeOfBinary) {
|
switch (typeOfBinary) {
|
||||||
case "java/lang/Long":
|
case CONSTANTS.REFTYPE_LONG:
|
||||||
mv.visitInsn(Opcodes.LCMP);
|
mv.visitInsn(Opcodes.LCMP);
|
||||||
doVisitIfInRelOp(op, branchLabel, endLabel);
|
doVisitIfInRelOp(op, branchLabel, endLabel);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case CONSTANTS.REFTYPE_DOUBLE:
|
||||||
mv.visitInsn(Opcodes.DCMPG);
|
mv.visitInsn(Opcodes.DCMPG);
|
||||||
doVisitIfInRelOp(op, branchLabel, endLabel);
|
doVisitIfInRelOp(op, branchLabel, endLabel);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case CONSTANTS.REFTYPE_FLOAT:
|
||||||
mv.visitInsn(Opcodes.FCMPG);
|
mv.visitInsn(Opcodes.FCMPG);
|
||||||
doVisitIfInRelOp(op, branchLabel, endLabel);
|
doVisitIfInRelOp(op, branchLabel, endLabel);
|
||||||
break;
|
break;
|
||||||
@ -497,13 +481,13 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
private void doVisitModOpInsn(String typeOfBinary) {
|
private void doVisitModOpInsn(String typeOfBinary) {
|
||||||
switch (typeOfBinary) {
|
switch (typeOfBinary) {
|
||||||
case "java/lang/Long":
|
case CONSTANTS.REFTYPE_LONG:
|
||||||
mv.visitInsn(Opcodes.LREM);
|
mv.visitInsn(Opcodes.LREM);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case CONSTANTS.REFTYPE_DOUBLE:
|
||||||
mv.visitInsn(Opcodes.DREM);
|
mv.visitInsn(Opcodes.DREM);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case CONSTANTS.REFTYPE_FLOAT:
|
||||||
mv.visitInsn(Opcodes.FREM);
|
mv.visitInsn(Opcodes.FREM);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -514,13 +498,13 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
private void doVisitDivOpInsn(String typeOfBinary) {
|
private void doVisitDivOpInsn(String typeOfBinary) {
|
||||||
switch (typeOfBinary) {
|
switch (typeOfBinary) {
|
||||||
case "java/lang/Long":
|
case CONSTANTS.REFTYPE_LONG:
|
||||||
mv.visitInsn(Opcodes.LDIV);
|
mv.visitInsn(Opcodes.LDIV);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case CONSTANTS.REFTYPE_DOUBLE:
|
||||||
mv.visitInsn(Opcodes.DDIV);
|
mv.visitInsn(Opcodes.DDIV);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case CONSTANTS.REFTYPE_FLOAT:
|
||||||
mv.visitInsn(Opcodes.FDIV);
|
mv.visitInsn(Opcodes.FDIV);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -531,13 +515,13 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
private void doVisitMulOpInsn(String typeOfBinary) {
|
private void doVisitMulOpInsn(String typeOfBinary) {
|
||||||
switch (typeOfBinary) {
|
switch (typeOfBinary) {
|
||||||
case "java/lang/Long":
|
case CONSTANTS.REFTYPE_LONG:
|
||||||
mv.visitInsn(Opcodes.LMUL);
|
mv.visitInsn(Opcodes.LMUL);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case CONSTANTS.REFTYPE_DOUBLE:
|
||||||
mv.visitInsn(Opcodes.DMUL);
|
mv.visitInsn(Opcodes.DMUL);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case CONSTANTS.REFTYPE_FLOAT:
|
||||||
mv.visitInsn(Opcodes.FMUL);
|
mv.visitInsn(Opcodes.FMUL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -548,13 +532,13 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
private void doVisitSubOpInsn(String typeOfBinary) {
|
private void doVisitSubOpInsn(String typeOfBinary) {
|
||||||
switch (typeOfBinary) {
|
switch (typeOfBinary) {
|
||||||
case "java/lang/Long":
|
case CONSTANTS.REFTYPE_LONG:
|
||||||
mv.visitInsn(Opcodes.LSUB);
|
mv.visitInsn(Opcodes.LSUB);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case CONSTANTS.REFTYPE_DOUBLE:
|
||||||
mv.visitInsn(Opcodes.DSUB);
|
mv.visitInsn(Opcodes.DSUB);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case CONSTANTS.REFTYPE_FLOAT:
|
||||||
mv.visitInsn(Opcodes.FSUB);
|
mv.visitInsn(Opcodes.FSUB);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -566,26 +550,26 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
private void doVisitAddOpInsn(String typeOfBinary) {
|
private void doVisitAddOpInsn(String typeOfBinary) {
|
||||||
switch (typeOfBinary) {
|
switch (typeOfBinary) {
|
||||||
case "java/lang/Byte":
|
case CONSTANTS.REFTYPE_BYTE:
|
||||||
mv.visitInsn(Opcodes.IADD);
|
mv.visitInsn(Opcodes.IADD);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Short":
|
case CONSTANTS.REFTYPE_SHORT:
|
||||||
mv.visitInsn(Opcodes.IADD);
|
mv.visitInsn(Opcodes.IADD);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Integer":
|
case CONSTANTS.REFTYPE_INTEGER:
|
||||||
mv.visitInsn(Opcodes.IADD);
|
mv.visitInsn(Opcodes.IADD);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Long":
|
case CONSTANTS.REFTYPE_LONG:
|
||||||
mv.visitInsn(Opcodes.LADD);
|
mv.visitInsn(Opcodes.LADD);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case CONSTANTS.REFTYPE_DOUBLE:
|
||||||
mv.visitInsn(Opcodes.DADD);
|
mv.visitInsn(Opcodes.DADD);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case CONSTANTS.REFTYPE_FLOAT:
|
||||||
mv.visitInsn(Opcodes.FADD);
|
mv.visitInsn(Opcodes.FADD);
|
||||||
break;
|
break;
|
||||||
case "java/lang/String":
|
case CONSTANTS.REFTYPE_STRING:
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", CONSTANTS.TO_STRING, "()Ljava/lang/String;",
|
||||||
false);
|
false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -596,17 +580,10 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
public void visit(LambdaExpression lambdaExpression) {
|
||||||
this.lamCounter++;
|
this.lamCounter++;
|
||||||
|
|
||||||
String typeErasure = "(";
|
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
|
||||||
while (itr.hasNext()) {
|
|
||||||
itr.next();
|
|
||||||
typeErasure += "L" + Type.getInternalName(Object.class) + ";";
|
|
||||||
}
|
|
||||||
|
|
||||||
typeErasure += ")L" + Type.getInternalName(Object.class) + ";";
|
String typeErasure = createDescriptorWithTypeErasure(lambdaExpression);
|
||||||
|
|
||||||
generateBCForFunN(lambdaExpression, typeErasure);
|
ByteCodeForFunNGenerator.generateBCForFunN(lambdaExpression, typeErasure,path);
|
||||||
|
|
||||||
|
|
||||||
Lambda lam = new Lambda(lambdaExpression);
|
Lambda lam = new Lambda(lambdaExpression);
|
||||||
@ -619,7 +596,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory",
|
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory",
|
||||||
mt.toMethodDescriptorString(), false);
|
mt.toMethodDescriptorString(), false);
|
||||||
String methodName = "lambda$new$" + this.lamCounter;
|
String desugaredMethodName = CONSTANTS.DESUGAREDMETHODNAME + this.lamCounter;
|
||||||
|
|
||||||
// Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die
|
// Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die
|
||||||
// Typlöschung)
|
// Typlöschung)
|
||||||
@ -630,37 +607,22 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
// real Type
|
// real Type
|
||||||
Type arg3 = Type.getMethodType(lamDesc);
|
Type arg3 = Type.getMethodType(lamDesc);
|
||||||
|
|
||||||
int staticOrSpecial = 0;
|
int staticOrSpecial, staticOrInstance = 0, indexOfFirstParamLam = 0;
|
||||||
int staticOrInstance = 0;
|
|
||||||
int indexOfFirstParamLam = 0;
|
|
||||||
this.kindOfLambda = new KindOfLambda(lambdaExpression);
|
this.kindOfLambda = new KindOfLambda(lambdaExpression);
|
||||||
|
|
||||||
if (kindOfLambda.isInstanceCapturingLambda()) {
|
if (kindOfLambda.isInstanceCapturingLambda()) {
|
||||||
// if(!kindOfLambda.getArgumentList().contains(BytecodeGen.THISTYPE))
|
|
||||||
// kindOfLambda.getArgumentList().add(0, BytecodeGen.THISTYPE);
|
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||||
for(String v : kindOfLambda.getUsedVars()) {
|
loadUsedVarsInLambda();
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(v));
|
|
||||||
}
|
|
||||||
staticOrSpecial = Opcodes.H_INVOKESPECIAL;
|
staticOrSpecial = Opcodes.H_INVOKESPECIAL;
|
||||||
indexOfFirstParamLam = 1;
|
indexOfFirstParamLam = 1;
|
||||||
} else {
|
} else {
|
||||||
staticOrSpecial = Opcodes.H_INVOKESTATIC;
|
staticOrSpecial = Opcodes.H_INVOKESTATIC;
|
||||||
staticOrInstance = Opcodes.ACC_STATIC;
|
staticOrInstance = Opcodes.ACC_STATIC;
|
||||||
}
|
}
|
||||||
String newDesc = "(";
|
String newDesc = addUsedVarsToDesugaredMethodDescriptor(lamDesc);
|
||||||
int pos = 0;
|
|
||||||
if(kindOfLambda.isHasThis()) {
|
|
||||||
pos = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i=pos;i<kindOfLambda.getArgumentList().size();i++) {
|
|
||||||
String t = "L" + resolver.getResolvedType(kindOfLambda.getArgumentList().get(i)) + ";";
|
|
||||||
newDesc += t;
|
|
||||||
}
|
|
||||||
newDesc += lamDesc.substring(1);
|
|
||||||
// first check if capturing lambda then invokestatic or invokespecial
|
// first check if capturing lambda then invokestatic or invokespecial
|
||||||
Handle arg2 = new Handle(staticOrSpecial, this.className, methodName, newDesc, false);
|
Handle arg2 = new Handle(staticOrSpecial, this.className, desugaredMethodName, newDesc, false);
|
||||||
// Descriptor of functional interface methode
|
// Descriptor of functional interface methode
|
||||||
SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType());
|
SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType());
|
||||||
// Desc: (this/nothing)TargetType
|
// Desc: (this/nothing)TargetType
|
||||||
@ -668,11 +630,11 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2, arg3);
|
mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2, arg3);
|
||||||
if(constructorPos<2) {
|
if(constructorPos<2) {
|
||||||
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE + staticOrInstance + Opcodes.ACC_SYNTHETIC,
|
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE + staticOrInstance + Opcodes.ACC_SYNTHETIC,
|
||||||
methodName, newDesc, null, null);
|
desugaredMethodName, newDesc, null, null);
|
||||||
|
|
||||||
ArrayList<String> usedVars = kindOfLambda.getUsedVars();
|
ArrayList<String> usedVars = kindOfLambda.getUsedVars();
|
||||||
|
|
||||||
new BytecodeGenMethod(lambdaExpression, usedVars,this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface,
|
new BytecodeGenMethod(className, cw,lambdaExpression, usedVars,this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface,
|
||||||
classFiles,this.path, lamCounter, sf, genericsAndBoundsMethod,
|
classFiles,this.path, lamCounter, sf, genericsAndBoundsMethod,
|
||||||
genericsAndBounds);
|
genericsAndBounds);
|
||||||
|
|
||||||
@ -684,49 +646,41 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
// generateBCForFunN(lambdaExpression, typeErasure);
|
// generateBCForFunN(lambdaExpression, typeErasure);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
|
private String addUsedVarsToDesugaredMethodDescriptor(String lamDesc) {
|
||||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
String newDesc = "(";
|
||||||
|
int pos = 0;
|
||||||
|
if(kindOfLambda.isThisUsed()) {
|
||||||
|
pos = 1;
|
||||||
|
}
|
||||||
|
|
||||||
SignatureWriter methSig = new SignatureWriter();
|
for(int i=pos;i<kindOfLambda.getArgumentList().size();i++) {
|
||||||
|
String t = "L" + resolver.getResolvedType(kindOfLambda.getArgumentList().get(i)) + ";";
|
||||||
|
newDesc += t;
|
||||||
|
}
|
||||||
|
newDesc += lamDesc.substring(1);
|
||||||
|
return newDesc;
|
||||||
|
}
|
||||||
|
|
||||||
int numberOfParams = 0;
|
private void loadUsedVarsInLambda() {
|
||||||
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
for(String v : kindOfLambda.getUsedVars()) {
|
||||||
|
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createDescriptorWithTypeErasure(LambdaExpression lambdaExpression) {
|
||||||
|
String typeErasure = "(";
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
numberOfParams++;
|
|
||||||
// getBounds
|
|
||||||
paramVisitor.visitTypeVariable("T" + numberOfParams);
|
|
||||||
itr.next();
|
itr.next();
|
||||||
}
|
typeErasure += "L" + Type.getInternalName(Object.class) + ";";
|
||||||
methSig.visitReturnType().visitTypeVariable("R");
|
|
||||||
// ")"+lam.getReturn.getBounds
|
|
||||||
Signature sig = new Signature(numberOfParams);
|
|
||||||
String name = "Fun" + numberOfParams + "$$";
|
|
||||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
|
||||||
Type.getInternalName(Object.class), null);
|
|
||||||
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
|
||||||
methSig.toString(), null);
|
|
||||||
mvApply.visitEnd();
|
|
||||||
writeClassFile(classWriter.toByteArray(), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void writeClassFile(byte[] bytecode, String name) {
|
|
||||||
FileOutputStream output;
|
|
||||||
try {
|
|
||||||
System.out.println("generating " + name + ".class file...");
|
|
||||||
output = new FileOutputStream(
|
|
||||||
new File(path + name + ".class"));
|
|
||||||
output.write(bytecode);
|
|
||||||
output.close();
|
|
||||||
System.out.println(name + ".class file generated");
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typeErasure += ")L" + Type.getInternalName(Object.class) + ";";
|
||||||
|
return typeErasure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CastExpr castExpr) {
|
public void visit(CastExpr castExpr) {
|
||||||
|
|
||||||
@ -802,8 +756,6 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
MethodCallHelper helper = new MethodCallHelper(methodCall, sf, resultSet, path);
|
MethodCallHelper helper = new MethodCallHelper(methodCall, sf, resultSet, path);
|
||||||
|
|
||||||
boolean toCreate = false;
|
|
||||||
|
|
||||||
ClassLoader cLoader = ClassLoader.getSystemClassLoader();
|
ClassLoader cLoader = ClassLoader.getSystemClassLoader();
|
||||||
// This will be used if the class is not standard class (not in API)
|
// This will be used if the class is not standard class (not in API)
|
||||||
ClassLoader cLoader2;
|
ClassLoader cLoader2;
|
||||||
@ -811,9 +763,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
String[] typesOfParams = getTypes(methodCall.arglist.getArguments());
|
String[] typesOfParams = getTypes(methodCall.arglist.getArguments());
|
||||||
try {
|
try {
|
||||||
if (receiverName.contains("<")) {
|
clazz = getRawClassName(receiverName, clazz);
|
||||||
clazz = clazz.substring(0, receiverName.indexOf("<"));
|
|
||||||
}
|
|
||||||
|
|
||||||
java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods();
|
java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods();
|
||||||
System.out.println("Methods of " + receiverName + " ");
|
System.out.println("Methods of " + receiverName + " ");
|
||||||
@ -827,19 +777,12 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
String superClazz = superClass.replace("/", ".");
|
String superClazz = superClass.replace("/", ".");
|
||||||
if(superClass.contains("<")) {
|
superClazz = getRawClassName(superClass, superClazz);
|
||||||
superClazz = superClazz.substring(0, superClass.indexOf("<"));
|
|
||||||
}
|
|
||||||
java.lang.reflect.Method[] methods = cLoader.loadClass(superClazz).getMethods();
|
java.lang.reflect.Method[] methods = cLoader.loadClass(superClazz).getMethods();
|
||||||
System.out.println("Methods of " + superClass + " ");
|
System.out.println("Methods of " + superClass + " ");
|
||||||
|
|
||||||
for(java.lang.reflect.Method m : methods) {
|
methodRefl = getMethod(methodCall.name, methodCall.arglist.getArguments().size(), methods);
|
||||||
if(methodCall.name.equals(m.getName())) {
|
|
||||||
methodRefl = m;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} catch (Exception e3) {
|
} catch (Exception e3) {
|
||||||
receiverName = superClass;
|
receiverName = superClass;
|
||||||
@ -854,7 +797,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(methodRefl == null) {
|
if(methodRefl == null) {
|
||||||
toCreate = !receiverName.equals(className) && helper.isInCurrPkg(clazz);
|
boolean toCreate = !receiverName.equals(className) && helper.isInCurrPkg(clazz);
|
||||||
if(toCreate) {
|
if(toCreate) {
|
||||||
try {
|
try {
|
||||||
mDesc = helper.getDesc(clazz);
|
mDesc = helper.getDesc(clazz);
|
||||||
@ -862,8 +805,9 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} else if(!helper.isInCurrPkg(clazz)){
|
} else if(!helper.isInCurrPkg(clazz)){
|
||||||
if(clazz.contains("$$")) {
|
if(clazz.contains(CONSTANTS.$$)) {
|
||||||
mDesc = helper.generateBCForFunN();
|
mDesc = helper.getDescriptorOfApplyMethod(methCallType);
|
||||||
|
helper.generateBCForFunN(mDesc);
|
||||||
// mDesc = helper.generateBCForFunN(methCallType,typesOfParams);
|
// mDesc = helper.generateBCForFunN(methCallType,typesOfParams);
|
||||||
}else {
|
}else {
|
||||||
try {
|
try {
|
||||||
@ -896,18 +840,10 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
} else if(methodRefl != null) {
|
} else if(methodRefl != null) {
|
||||||
System.out.println(methodCall.name + " -> Refl != null");
|
System.out.println(methodCall.name + " -> Refl != null");
|
||||||
receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString();
|
receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString();
|
||||||
for(Parameter p:methodRefl.getParameters()) {
|
getBoolListOfType(methodRefl, argListMethCall);
|
||||||
System.out.println(p.getName() + " und is Primitive = " + p.getType().isPrimitive());
|
|
||||||
argListMethCall.add(p.getType().isPrimitive());
|
|
||||||
}
|
|
||||||
System.out.println("Receiver = " + methodRefl.getAnnotatedReceiverType().getType().toString());
|
System.out.println("Receiver = " + methodRefl.getAnnotatedReceiverType().getType().toString());
|
||||||
mDesc = getMethodDesc(methodRefl);
|
mDesc = getMethodDesc(methodRefl);
|
||||||
for (Expression al : methodCall.arglist.getArguments()) {
|
visitArgumentListOfMethodCallFromStandardAPI(methodCall, argListMethCall);
|
||||||
statement = new ArgumentExpr(al);
|
|
||||||
ArgumentVisitor argV = new ArgumentVisitor(argListMethCall,this);
|
|
||||||
al.accept(argV);
|
|
||||||
statement = null;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
methodCall.arglist.accept(this);
|
methodCall.arglist.accept(this);
|
||||||
}
|
}
|
||||||
@ -916,27 +852,20 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
|
|
||||||
// methodCall.arglist.accept(this);
|
// methodCall.arglist.accept(this);
|
||||||
|
visitInvokeInsn(methodCall, receiverName, methodRefl, clazz, mDesc, receiverRefl);
|
||||||
// is methodCall.receiver functional Interface)?
|
|
||||||
if (varsFunInterface.contains(methodCall.receiver.getType()) || (methodRefl!= null && receiverRefl.contains("interface")) ||
|
|
||||||
receiverName.contains("$$")) {
|
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, clazz.replace(".", "/"), methodCall.name,
|
|
||||||
mDesc, true);
|
|
||||||
} else {
|
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, clazz.replace(".", "/"), methodCall.name,
|
|
||||||
mDesc, isInterface);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) {
|
if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) {
|
||||||
if(methodRefl.getReturnType().equals(Object.class)) {
|
if(methodRefl.getReturnType().equals(Object.class)) {
|
||||||
helper.createCheckCast(methodCall,mv);
|
helper.createCheckCast(methodCall,mv);
|
||||||
}
|
}
|
||||||
if(isBinaryExp) {
|
/*if(isBinaryExp) {
|
||||||
|
doUnboxing(resolver.getResolvedType(methodCall.getType()));
|
||||||
|
}*/
|
||||||
|
if(parentBinary || isBinaryExp) {
|
||||||
doUnboxing(resolver.getResolvedType(methodCall.getType()));
|
doUnboxing(resolver.getResolvedType(methodCall.getType()));
|
||||||
|
|
||||||
}
|
}
|
||||||
} else if(receiverName.contains("$$") && !methCallType.equals(Type.getInternalName(Object.class))) {
|
} else if(receiverName.contains(CONSTANTS.$$) && !methCallType.equals(Type.getInternalName(Object.class))) {
|
||||||
helper.createCheckCast(methodCall,mv);
|
helper.createCheckCast(methodCall,mv);
|
||||||
}
|
}
|
||||||
System.out.println("ISParent Binary = "+isParentBinary +" -> " + parentBinary);
|
System.out.println("ISParent Binary = "+isParentBinary +" -> " + parentBinary);
|
||||||
@ -947,18 +876,39 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void getBoolListOfType(java.lang.reflect.Method methodRefl, List<Boolean> argListMethCall) {
|
||||||
private String getDescForMethInCurrPkg(String name) {
|
for(Parameter p:methodRefl.getParameters()) {
|
||||||
// TODO Auto-generated method stub
|
System.out.println(p.getName() + " und is Primitive = " + p.getType().isPrimitive());
|
||||||
return null;
|
argListMethCall.add(p.getType().isPrimitive());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInCurrPkg(String superClass) {
|
private void visitArgumentListOfMethodCallFromStandardAPI(MethodCall methodCall, List<Boolean> argListMethCall) {
|
||||||
for(ClassOrInterface cl : sf.KlassenVektor) {
|
for (Expression al : methodCall.arglist.getArguments()) {
|
||||||
if(superClass.equals(cl.getClassName().toString()))
|
statement = new ArgumentExpr(al);
|
||||||
return true;
|
ArgumentVisitor argV = new ArgumentVisitor(argListMethCall,this);
|
||||||
|
al.accept(argV);
|
||||||
|
statement = null;
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
private void visitInvokeInsn(MethodCall methodCall, String receiverName, java.lang.reflect.Method methodRefl, String clazz, String mDesc, String receiverRefl) {
|
||||||
|
// is methodCall.receiver functional Interface)?
|
||||||
|
if (varsFunInterface.contains(methodCall.receiver.getType()) || (methodRefl!= null && receiverRefl.contains("interface")) ||
|
||||||
|
receiverName.contains(CONSTANTS.$$)) {
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, clazz.replace(".", "/"), methodCall.name,
|
||||||
|
mDesc, true);
|
||||||
|
} else {
|
||||||
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, clazz.replace(".", "/"), methodCall.name,
|
||||||
|
mDesc, isInterface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRawClassName(String receiverName, String clazz) {
|
||||||
|
if (receiverName.contains(CONSTANTS.ANGLEBRACKET)) {
|
||||||
|
clazz = clazz.substring(0, receiverName.indexOf(CONSTANTS.ANGLEBRACKET));
|
||||||
|
}
|
||||||
|
return clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] getTypes(List<Expression> arguments) {
|
private String[] getTypes(List<Expression> arguments) {
|
||||||
@ -1067,15 +1017,24 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
mv.visitInsn(Opcodes.DUP);
|
mv.visitInsn(Opcodes.DUP);
|
||||||
// creates Descriptor
|
// creates Descriptor
|
||||||
methodCall.arglist.accept(this);
|
methodCall.arglist.accept(this);
|
||||||
String d = "(";
|
String d = createDescriptorForInitMethod(methodCall);
|
||||||
for (Expression e : methodCall.arglist.getArguments()) {
|
|
||||||
d = d + "L" + resolver.getResolvedType(e.getType()) + ";";
|
|
||||||
}
|
|
||||||
d += ")V";
|
|
||||||
|
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "<init>", d, isInterface);
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "<init>", d, isInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String createDescriptorForInitMethod(NewClass methodCall) {
|
||||||
|
String d = "(";
|
||||||
|
for (Expression e : methodCall.arglist.getArguments()) {
|
||||||
|
String type = resolver.getResolvedType(e.getType());
|
||||||
|
if(type.contains("TPH ")){
|
||||||
|
type = Type.getInternalName(Object.class);
|
||||||
|
}
|
||||||
|
d = d + "L" + type + ";";
|
||||||
|
}
|
||||||
|
d += ")V";
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewArray newArray) {
|
public void visit(NewArray newArray) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
@ -1136,13 +1095,13 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
private void doVisitNegIns(String typeOfUnary) {
|
private void doVisitNegIns(String typeOfUnary) {
|
||||||
switch (typeOfUnary) {
|
switch (typeOfUnary) {
|
||||||
case "java/lang/Long":
|
case CONSTANTS.REFTYPE_LONG:
|
||||||
mv.visitInsn(Opcodes.LNEG);
|
mv.visitInsn(Opcodes.LNEG);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case CONSTANTS.REFTYPE_DOUBLE:
|
||||||
mv.visitInsn(Opcodes.DNEG);
|
mv.visitInsn(Opcodes.DNEG);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case CONSTANTS.REFTYPE_FLOAT:
|
||||||
mv.visitInsn(Opcodes.FNEG);
|
mv.visitInsn(Opcodes.FNEG);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1260,23 +1219,23 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
case "java/lang/Boolean":
|
case "java/lang/Boolean":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Byte":
|
case CONSTANTS.REFTYPE_BYTE:
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CONSTANTS.REFTYPE_BYTE, "byteValue", "()B", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Short":
|
case CONSTANTS.REFTYPE_SHORT:
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CONSTANTS.REFTYPE_SHORT, "shortValue", "()S", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Integer":
|
case "java/lang/Integer":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Long":
|
case CONSTANTS.REFTYPE_LONG:
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CONSTANTS.REFTYPE_LONG, "longValue", "()J", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case CONSTANTS.REFTYPE_FLOAT:
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CONSTANTS.REFTYPE_FLOAT, "floatValue", "()F", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case CONSTANTS.REFTYPE_DOUBLE:
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CONSTANTS.REFTYPE_DOUBLE, "doubleValue", "()D", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Character":
|
case "java/lang/Character":
|
||||||
break;
|
break;
|
||||||
@ -1289,19 +1248,19 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
private void loadValue(String type, Object value, boolean isOperator) {
|
private void loadValue(String type, Object value, boolean isOperator) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "java/lang/String":
|
case CONSTANTS.REFTYPE_STRING:
|
||||||
mv.visitLdcInsn(String.valueOf(value));
|
mv.visitLdcInsn(String.valueOf(value));
|
||||||
break;
|
break;
|
||||||
case "java/lang/Boolean":
|
case "java/lang/Boolean":
|
||||||
visitBooleanLiteral((Boolean) value);
|
visitBooleanLiteral((Boolean) value);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Byte":
|
case CONSTANTS.REFTYPE_BYTE:
|
||||||
if(value instanceof Double)
|
if(value instanceof Double)
|
||||||
visitByteLiteral(((Double) value).byteValue(), false);
|
visitByteLiteral(((Double) value).byteValue(), false);
|
||||||
if(value instanceof Integer)
|
if(value instanceof Integer)
|
||||||
visitByteLiteral(((Integer) value).byteValue(), false);
|
visitByteLiteral(((Integer) value).byteValue(), false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Short":
|
case CONSTANTS.REFTYPE_SHORT:
|
||||||
if(value instanceof Double)
|
if(value instanceof Double)
|
||||||
visitShortLiteral(((Double) value).shortValue(), false);
|
visitShortLiteral(((Double) value).shortValue(), false);
|
||||||
if(value instanceof Integer)
|
if(value instanceof Integer)
|
||||||
@ -1315,19 +1274,19 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
if(value instanceof Integer)
|
if(value instanceof Integer)
|
||||||
visitIntegerLiteral(((Integer) value).intValue(), false);
|
visitIntegerLiteral(((Integer) value).intValue(), false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Long":
|
case CONSTANTS.REFTYPE_LONG:
|
||||||
if(value instanceof Double)
|
if(value instanceof Double)
|
||||||
visitLongLiteral(((Double) value).longValue(), true);
|
visitLongLiteral(((Double) value).longValue(), true);
|
||||||
if(value instanceof Integer)
|
if(value instanceof Integer)
|
||||||
visitLongLiteral(((Integer) value).longValue(), true);
|
visitLongLiteral(((Integer) value).longValue(), true);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case CONSTANTS.REFTYPE_FLOAT:
|
||||||
if(value instanceof Double)
|
if(value instanceof Double)
|
||||||
visitFloatLiteral(((Double) value).floatValue());
|
visitFloatLiteral(((Double) value).floatValue());
|
||||||
if(value instanceof Integer)
|
if(value instanceof Integer)
|
||||||
visitFloatLiteral(((Integer) value).floatValue());
|
visitFloatLiteral(((Integer) value).floatValue());
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case CONSTANTS.REFTYPE_DOUBLE:
|
||||||
if(value instanceof Double)
|
if(value instanceof Double)
|
||||||
visitDoubleLiteral((Double) value);
|
visitDoubleLiteral((Double) value);
|
||||||
if(value instanceof Integer)
|
if(value instanceof Integer)
|
||||||
@ -1343,7 +1302,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Boxing
|
// Boxing
|
||||||
if (!type.equals("java/lang/String") && !type.equals("java/lang/Boolean")) {
|
if (!type.equals(CONSTANTS.REFTYPE_STRING) && !type.equals("java/lang/Boolean")) {
|
||||||
if (!this.isBinaryExp && !isOperator)
|
if (!this.isBinaryExp && !isOperator)
|
||||||
doBoxing(type);
|
doBoxing(type);
|
||||||
}
|
}
|
||||||
@ -1360,23 +1319,23 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
case "java/lang/Boolean":
|
case "java/lang/Boolean":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Byte":
|
case CONSTANTS.REFTYPE_BYTE:
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, CONSTANTS.REFTYPE_BYTE, "valueOf", "(B)Ljava/lang/Byte;", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Short":
|
case CONSTANTS.REFTYPE_SHORT:
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, CONSTANTS.REFTYPE_SHORT, "valueOf", "(S)Ljava/lang/Short;", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Integer":
|
case "java/lang/Integer":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Long":
|
case CONSTANTS.REFTYPE_LONG:
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, CONSTANTS.REFTYPE_LONG, "valueOf", "(J)Ljava/lang/Long;", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case CONSTANTS.REFTYPE_FLOAT:
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, CONSTANTS.REFTYPE_FLOAT, "valueOf", "(F)Ljava/lang/Float;", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case CONSTANTS.REFTYPE_DOUBLE:
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, CONSTANTS.REFTYPE_DOUBLE, "valueOf", "(D)Ljava/lang/Double;", false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Character":
|
case "java/lang/Character":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;",
|
||||||
|
@ -3,29 +3,27 @@ package de.dhbwstuttgart.bytecode.descriptor;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.*;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.Lambda;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
|
||||||
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
public class DescriptorToString implements DescriptorVisitor{
|
public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
|
||||||
ResultSet resultSet;
|
ResultSet resultSet;
|
||||||
|
|
||||||
|
public DescriptorToString() {
|
||||||
|
}
|
||||||
|
|
||||||
public DescriptorToString(ResultSet resultSet) {
|
public DescriptorToString(ResultSet resultSet) {
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String addReturnType(String desc, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) {
|
private String addReturnType(String desc, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) {
|
||||||
if(resultSet.resolveType(returnType).resolvedType.toString().equals("void")){
|
if(resultSet.resolveType(returnType).resolvedType.toString().equals(CONSTANTS.VOID)){
|
||||||
desc = desc + ")V";
|
desc = desc + ")V";
|
||||||
}else {
|
}else {
|
||||||
desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||||
@ -53,7 +51,7 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
}else {
|
}else {
|
||||||
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||||
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
if(resType.contains("TPH ")/*resType.subSequence(0, 4).equals("TPH ")*/) {
|
if(resType.contains(CONSTANTS.TPH)/*resType.subSequence(0, 4).equals("TPH ")*/) {
|
||||||
// Bound ist immer Object
|
// Bound ist immer Object
|
||||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||||
} else {
|
} else {
|
||||||
@ -71,15 +69,15 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO: generate a class java%% ... %%
|
//TODO: generate a class java%% ... %%
|
||||||
else if(resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()).contains("<")){
|
else if(resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()).contains(CONSTANTS.ANGLEBRACKET)){
|
||||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "$$").replace("<", "$$$").replace(">", "$$$")+ ";";
|
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "$$").replace(CONSTANTS.ANGLEBRACKET, "$$$").replace(">", "$$$")+ ";";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(resultSet.resolveType(method.getReturnType()).resolvedType.toString().equals("void")) {
|
if(resultSet.resolveType(method.getReturnType()).resolvedType.toString().equals(CONSTANTS.VOID)) {
|
||||||
desc += ")V";
|
desc += ")V";
|
||||||
}else {
|
}else {
|
||||||
if(method.hasGen()) {
|
if(method.hasGen()) {
|
||||||
@ -90,7 +88,7 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
desc += ")L"+method.getGenericsAndBounds().get(ret)+ ";";
|
desc += ")L"+method.getGenericsAndBounds().get(ret)+ ";";
|
||||||
}else {
|
}else {
|
||||||
String resType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String resType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
if(resType.contains("TPH ")/*resType.subSequence(0, 4).equals("TPH ")*/) {
|
if(resType.contains(CONSTANTS.TPH)/*resType.subSequence(0, 4).equals("TPH ")*/) {
|
||||||
// desc += ")" + "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";";
|
// desc += ")" + "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";";
|
||||||
desc += ")" + "L"+Type.getInternalName(Object.class)+ ";";
|
desc += ")" + "L"+Type.getInternalName(Object.class)+ ";";
|
||||||
} else {
|
} else {
|
||||||
@ -139,7 +137,7 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
}else {
|
}else {
|
||||||
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||||
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
if(resType.subSequence(0, 4).equals("TPH ")) {
|
if(resType.subSequence(0, 4).equals(CONSTANTS.TPH)) {
|
||||||
// Bound ist immer Object
|
// Bound ist immer Object
|
||||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||||
} else {
|
} else {
|
||||||
@ -162,7 +160,7 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
while(itr.hasNext()) {
|
while(itr.hasNext()) {
|
||||||
FormalParameter fp = itr.next();
|
FormalParameter fp = itr.next();
|
||||||
String d = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String d = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
if(d.contains("TPH ") ||d.contains("<")) {
|
if(d.contains(CONSTANTS.TPH) ||d.contains(CONSTANTS.ANGLEBRACKET)) {
|
||||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||||
}else {
|
}else {
|
||||||
desc = desc + "L"+ d + ";";
|
desc = desc + "L"+ d + ";";
|
||||||
@ -171,7 +169,7 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
|
|
||||||
String retType = resultSet.resolveType(lambdaExpression.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String retType = resultSet.resolveType(lambdaExpression.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
|
|
||||||
if(retType.contains("TPH ")|| retType.contains("<")){
|
if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET)){
|
||||||
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
||||||
}else {
|
}else {
|
||||||
desc = desc + ")"+"L"+retType+";";
|
desc = desc + ")"+"L"+retType+";";
|
||||||
@ -187,7 +185,7 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
RefTypeOrTPHOrWildcardOrGeneric rt = itr.next();
|
RefTypeOrTPHOrWildcardOrGeneric rt = itr.next();
|
||||||
String d = resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor());
|
String d = resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
|
|
||||||
if(d.contains("TPH ") ||d.contains("<")) {
|
if(d.contains(CONSTANTS.TPH) ||d.contains(CONSTANTS.ANGLEBRACKET)) {
|
||||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||||
}else {
|
}else {
|
||||||
desc += "L"+ d + ";";
|
desc += "L"+ d + ";";
|
||||||
@ -196,7 +194,7 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
}
|
}
|
||||||
String retType = resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String retType = resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
|
|
||||||
if(retType.contains("TPH ")|| retType.contains("<")){
|
if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET)){
|
||||||
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
||||||
}else {
|
}else {
|
||||||
desc = desc + ")"+"L"+retType+";";
|
desc = desc + ")"+"L"+retType+";";
|
||||||
@ -210,7 +208,7 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
for(Expression e : methodFromMethodCall.getArgList().getArguments()) {
|
for(Expression e : methodFromMethodCall.getArgList().getArguments()) {
|
||||||
String d = resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String d = resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
|
|
||||||
if(d.contains("TPH ") ||d.contains("<") || methodFromMethodCall.getReceiverName().contains("$$")) {
|
if(d.contains(CONSTANTS.TPH) ||d.contains(CONSTANTS.ANGLEBRACKET) || methodFromMethodCall.getReceiverName().contains("$$")) {
|
||||||
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||||
}else {
|
}else {
|
||||||
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(d)) {
|
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(d)) {
|
||||||
@ -225,9 +223,9 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
}
|
}
|
||||||
String retType = resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String retType = resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
System.out.println("DescriptorToString retType = " + retType);
|
System.out.println("DescriptorToString retType = " + retType);
|
||||||
if(retType.equals("void")) {
|
if(retType.equals(CONSTANTS.VOID)) {
|
||||||
desc += ")V";
|
desc += ")V";
|
||||||
}else if(retType.contains("TPH ")|| retType.contains("<") || methodFromMethodCall.getReceiverName().contains("$$")){
|
}else if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET) || methodFromMethodCall.getReceiverName().contains("$$")){
|
||||||
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
||||||
}else {
|
}else {
|
||||||
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(retType)) {
|
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(retType)) {
|
||||||
@ -241,5 +239,21 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
// desc = addReturnType(desc, methodFromMethodCall.getReturnType(), resultSet);
|
// desc = addReturnType(desc, methodFromMethodCall.getReturnType(), resultSet);
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String createDescForFunN(ArgumentList argumentList, String returnType) {
|
||||||
|
Iterator<Expression> itr1 = argumentList.getArguments().iterator();
|
||||||
|
String methDesc = "(";
|
||||||
|
while(itr1.hasNext()) {
|
||||||
|
methDesc += "L" + Type.getInternalName(Object.class) + ";";
|
||||||
|
itr1.next();
|
||||||
|
}
|
||||||
|
if (returnType.equals(CONSTANTS.VOID)){
|
||||||
|
methDesc += ")V";
|
||||||
|
} else {
|
||||||
|
methDesc += ")L" + Type.getInternalName(Object.class) + ";";
|
||||||
|
}
|
||||||
|
return methDesc;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,13 @@ import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
|
|||||||
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
|
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||||
|
|
||||||
public interface DescriptorVisitor {
|
public interface DescriptorVisitor {
|
||||||
public String visit(NormalMethod method);
|
String visit(NormalMethod method);
|
||||||
public String visit(NormalConstructor constructor);
|
String visit(NormalConstructor constructor);
|
||||||
public String visit(Lambda lambdaExpression);
|
String visit(Lambda lambdaExpression);
|
||||||
public String visit(SamMethod samMethod);
|
String visit(SamMethod samMethod);
|
||||||
public String visit(MethodFromMethodCall methodFromMethodCall);
|
String visit(MethodFromMethodCall methodFromMethodCall);
|
||||||
|
String createDescForFunN(ArgumentList argumentList, String returnType);
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ public class GenericsGenerator {
|
|||||||
|
|
||||||
return new GenericsGeneratorResult(constraint, equalSet);
|
return new GenericsGeneratorResult(constraint, equalSet);
|
||||||
}
|
}
|
||||||
/* TODO Remove this method*/
|
/* TODO Remove this methoda*/
|
||||||
private static GenericsGeneratorResult generateGGResultForClass(LinkedList<String> tphsInRel,
|
private static GenericsGeneratorResult generateGGResultForClass(LinkedList<String> tphsInRel,
|
||||||
ConstraintsSimplierResult simplifiedConstraints, List<String> tphsClass) {
|
ConstraintsSimplierResult simplifiedConstraints, List<String> tphsClass) {
|
||||||
String subType = tphsInRel.getFirst();
|
String subType = tphsInRel.getFirst();
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||||
|
import org.objectweb.asm.ClassWriter;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.signature.SignatureVisitor;
|
||||||
|
import org.objectweb.asm.signature.SignatureWriter;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public class ByteCodeForFunNGenerator {
|
||||||
|
|
||||||
|
public static void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc, String path) {
|
||||||
|
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||||
|
|
||||||
|
SignatureWriter methSig = new SignatureWriter();
|
||||||
|
|
||||||
|
int numberOfParams = 0;
|
||||||
|
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
||||||
|
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
numberOfParams++;
|
||||||
|
// getBounds
|
||||||
|
paramVisitor.visitTypeVariable(CONSTANTS.T + numberOfParams);
|
||||||
|
itr.next();
|
||||||
|
}
|
||||||
|
methSig.visitReturnType().visitTypeVariable(CONSTANTS.R);
|
||||||
|
// ")"+lam.getReturn.getBounds
|
||||||
|
Signature sig = new Signature(numberOfParams);
|
||||||
|
String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
|
||||||
|
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
||||||
|
Type.getInternalName(Object.class), null);
|
||||||
|
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
||||||
|
methSig.toString(), null);
|
||||||
|
mvApply.visitEnd();
|
||||||
|
writeClassFile(classWriter.toByteArray(), name, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void generateBCForFunN(ArgumentList argumentList, String methDesc, String path) {
|
||||||
|
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||||
|
|
||||||
|
SignatureWriter methSig = new SignatureWriter();
|
||||||
|
|
||||||
|
int numberOfParams = 0;
|
||||||
|
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
||||||
|
Iterator<Expression> itr1 = argumentList.getArguments().iterator();
|
||||||
|
|
||||||
|
while(itr1.hasNext()) {
|
||||||
|
numberOfParams++;
|
||||||
|
// getBounds
|
||||||
|
paramVisitor.visitTypeVariable(CONSTANTS.T + numberOfParams);
|
||||||
|
itr1.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
methSig.visitReturnType().visitTypeVariable(CONSTANTS.R);
|
||||||
|
// ")"+lam.getReturn.getBounds
|
||||||
|
Signature sig = new Signature(numberOfParams);
|
||||||
|
String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
|
||||||
|
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
||||||
|
Type.getInternalName(Object.class), null);
|
||||||
|
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
||||||
|
methSig.toString(), null);
|
||||||
|
mvApply.visitEnd();
|
||||||
|
writeClassFile(classWriter.toByteArray(), name, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void writeClassFile(byte[] bytecode, String name, String path) {
|
||||||
|
FileOutputStream output;
|
||||||
|
try {
|
||||||
|
System.out.println("generating " + name + ".class file...");
|
||||||
|
output = new FileOutputStream(
|
||||||
|
new File(path + name + CONSTANTS.EXTENSIONCLASS));
|
||||||
|
output.write(bytecode);
|
||||||
|
output.close();
|
||||||
|
System.out.println(name + ".class file generated");
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
|
public interface CONSTANTS {
|
||||||
|
|
||||||
|
String VOID = "void";
|
||||||
|
String TPH = "TPH ";
|
||||||
|
String ANGLEBRACKET = "<";
|
||||||
|
String FUN = "Fun";
|
||||||
|
String EXTENSIONCLASS = ".class";
|
||||||
|
String $$ = "$$";
|
||||||
|
String T = "T";
|
||||||
|
String R = "R";
|
||||||
|
String DESUGAREDMETHODNAME = "lambda$new$";
|
||||||
|
String REFTYPE_BYTE = "java/lang/Byte";
|
||||||
|
String REFTYPE_SHORT = "java/lang/Short";
|
||||||
|
String REFTYPE_INTEGER = "java/lang/Integer";
|
||||||
|
String REFTYPE_LONG = "java/lang/Long";
|
||||||
|
String REFTYPE_DOUBLE = "java/lang/Double";
|
||||||
|
String REFTYPE_FLOAT = "java/lang/Float";
|
||||||
|
String REFTYPE_STRING = "java/lang/String";
|
||||||
|
String TO_STRING = "toString";
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package de.dhbwstuttgart.bytecode.utilities;
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.*;
|
import de.dhbwstuttgart.syntaxtree.statement.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -19,7 +18,8 @@ public class KindOfLambda implements StatementVisitor{
|
|||||||
private boolean isInstanceCapturingLambda = false;
|
private boolean isInstanceCapturingLambda = false;
|
||||||
private List<RefTypeOrTPHOrWildcardOrGeneric> argumentList = new ArrayList<>();
|
private List<RefTypeOrTPHOrWildcardOrGeneric> argumentList = new ArrayList<>();
|
||||||
private ArrayList<String> usedVars = new ArrayList<>();
|
private ArrayList<String> usedVars = new ArrayList<>();
|
||||||
private boolean hasThis = false;
|
private ArrayList<String> varsFromInnerLambdas = new ArrayList<>();
|
||||||
|
private boolean thisUsed = false;
|
||||||
private ArrayList<String> definedLocals = new ArrayList<>();
|
private ArrayList<String> definedLocals = new ArrayList<>();
|
||||||
|
|
||||||
public KindOfLambda(LambdaExpression lambdaExpression) {
|
public KindOfLambda(LambdaExpression lambdaExpression) {
|
||||||
@ -40,19 +40,20 @@ public class KindOfLambda implements StatementVisitor{
|
|||||||
return argumentList;
|
return argumentList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHasThis() {
|
public boolean isThisUsed() {
|
||||||
return hasThis;
|
return thisUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ArgumentList argumentList) {
|
public void visit(ArgumentList argumentList) {
|
||||||
// TODO Auto-generated method stub
|
argumentList.getArguments().forEach(a->a.accept(this));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
public void visit(LambdaExpression lambdaExpression) {
|
||||||
|
lambdaExpression.params.getFormalparalist().forEach(p->varsFromInnerLambdas.add(p.getName()));
|
||||||
|
lambdaExpression.methodBody.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -111,9 +112,11 @@ public class KindOfLambda implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVar localVar) {
|
public void visit(LocalVar localVar) {
|
||||||
if(!contain(params, localVar.name) && !definedLocals.contains(localVar.name)) {
|
boolean addVar = !contain(params, localVar.name) && !definedLocals.contains(localVar.name) &&
|
||||||
|
!varsFromInnerLambdas.contains(localVar.name) && !usedVars.contains(localVar.name);
|
||||||
|
if(addVar) {
|
||||||
argumentList.add(localVar.getType());
|
argumentList.add(localVar.getType());
|
||||||
if(hasThis) {
|
if(thisUsed) {
|
||||||
usedVars.add(1, localVar.name);
|
usedVars.add(1, localVar.name);
|
||||||
} else {
|
} else {
|
||||||
usedVars.add(0, localVar.name);
|
usedVars.add(0, localVar.name);
|
||||||
@ -141,12 +144,13 @@ public class KindOfLambda implements StatementVisitor{
|
|||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
methodCall.receiver.accept(this);
|
methodCall.receiver.accept(this);
|
||||||
|
methodCall.arglist.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewClass methodCall) {
|
public void visit(NewClass methodCall) {
|
||||||
// TODO Auto-generated method stub
|
methodCall.receiver.accept(this);
|
||||||
|
methodCall.arglist.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -190,8 +194,8 @@ public class KindOfLambda implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(This aThis) {
|
public void visit(This aThis) {
|
||||||
if(!hasThis) {
|
if(!thisUsed) {
|
||||||
hasThis = true;
|
thisUsed = true;
|
||||||
this.argumentList.add(0,aThis.getType());
|
this.argumentList.add(0,aThis.getType());
|
||||||
}
|
}
|
||||||
if(!isInstanceCapturingLambda) {
|
if(!isInstanceCapturingLambda) {
|
||||||
|
@ -3,45 +3,20 @@
|
|||||||
*/
|
*/
|
||||||
package de.dhbwstuttgart.bytecode.utilities;
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.objectweb.asm.ClassWriter;
|
|
||||||
import org.objectweb.asm.MethodVisitor;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.signature.SignatureVisitor;
|
|
||||||
import org.objectweb.asm.signature.SignatureWriter;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
|
import de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
|
||||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.ParameterList;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
|
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
import javassist.NotFoundException;
|
import javassist.NotFoundException;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author fayez
|
* @author fayez
|
||||||
@ -244,83 +219,12 @@ public class MethodCallHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String generateBCForFunN() {
|
public void generateBCForFunN(String methodDescriptor) {
|
||||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
ByteCodeForFunNGenerator.generateBCForFunN(methCall.arglist,methodDescriptor,path);
|
||||||
|
|
||||||
SignatureWriter methSig = new SignatureWriter();
|
|
||||||
|
|
||||||
int numberOfParams = 0;
|
|
||||||
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
|
||||||
Iterator<Expression> itr1 = methCall.arglist.getArguments().iterator();
|
|
||||||
String methDesc = "(";
|
|
||||||
while(itr1.hasNext()) {
|
|
||||||
numberOfParams++;
|
|
||||||
// getBounds
|
|
||||||
paramVisitor.visitTypeVariable("T" + numberOfParams);
|
|
||||||
methDesc += "L" + Type.getInternalName(Object.class) + ";";
|
|
||||||
itr1.next();
|
|
||||||
}
|
|
||||||
methDesc += ")L" + Type.getInternalName(Object.class) + ";";
|
|
||||||
|
|
||||||
methSig.visitReturnType().visitTypeVariable("R");
|
|
||||||
// ")"+lam.getReturn.getBounds
|
|
||||||
Signature sig = new Signature(numberOfParams);
|
|
||||||
String name = "Fun" + numberOfParams + "$$";
|
|
||||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
|
||||||
Type.getInternalName(Object.class), null);
|
|
||||||
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
|
||||||
methSig.toString(), null);
|
|
||||||
mvApply.visitEnd();
|
|
||||||
writeClassFile(classWriter.toByteArray(), name);
|
|
||||||
return methDesc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String generateBCForFunN(String returnType, String[] paramTypes) {
|
|
||||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
|
||||||
|
|
||||||
SignatureWriter methSig = new SignatureWriter();
|
|
||||||
|
|
||||||
int numberOfParams = 0;
|
|
||||||
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
|
||||||
Iterator<Expression> itr1 = methCall.arglist.getArguments().iterator();
|
|
||||||
String methDesc = "(";
|
|
||||||
while(itr1.hasNext()) {
|
|
||||||
numberOfParams++;
|
|
||||||
// getBounds
|
|
||||||
paramVisitor.visitTypeVariable("T" + numberOfParams);
|
|
||||||
methDesc += "L" + paramTypes[numberOfParams-1] + ";";
|
|
||||||
itr1.next();
|
|
||||||
}
|
|
||||||
methDesc += ")L" + returnType + ";";
|
|
||||||
|
|
||||||
methSig.visitReturnType().visitTypeVariable("R");
|
|
||||||
// ")"+lam.getReturn.getBounds
|
|
||||||
Signature sig = new Signature(numberOfParams,returnType,paramTypes);
|
|
||||||
String name = "Fun" + numberOfParams + "$$";
|
|
||||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
|
||||||
Type.getInternalName(Object.class), null);
|
|
||||||
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
|
||||||
methSig.toString(), null);
|
|
||||||
mvApply.visitEnd();
|
|
||||||
writeClassFile(classWriter.toByteArray(), name);
|
|
||||||
return methDesc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeClassFile(byte[] bytecode, String name) {
|
public String getDescriptorOfApplyMethod(String methodCallType) {
|
||||||
FileOutputStream output;
|
return new DescriptorToString().createDescForFunN(methCall.arglist, methodCallType);
|
||||||
try {
|
|
||||||
System.out.println("generating " + name + ".class file...");
|
|
||||||
output = new FileOutputStream(
|
|
||||||
new File(path + name + ".class"));
|
|
||||||
output.write(bytecode);
|
|
||||||
output.close();
|
|
||||||
System.out.println(name + ".class file generated");
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,11 +25,11 @@ public class YTest {
|
|||||||
public void generateBC() throws Exception {
|
public void generateBC() throws Exception {
|
||||||
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/Y.jav";
|
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/Y.jav";
|
||||||
fileToTest = new File(path);
|
fileToTest = new File(path);
|
||||||
// compiler = new JavaTXCompiler(fileToTest);
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
// compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/");
|
compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/");
|
||||||
// pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
|
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
|
||||||
// loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
// classToTest = loader.loadClass("Y");
|
classToTest = loader.loadClass("Y");
|
||||||
/*
|
/*
|
||||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ public class mathStrucTest {
|
|||||||
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
|
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
|
||||||
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
classToTest = loader.loadClass("mathStruc");
|
classToTest = loader.loadClass("mathStruc");
|
||||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
instanceOfClass = classToTest.getDeclaredConstructor(Object.class).newInstance("A");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
public class FieldTphConsMeth {
|
public class FieldTphConsMeth {
|
||||||
|
|
||||||
a;
|
a;
|
||||||
/*public FieldTphConsMeth(c) {
|
public FieldTphConsMeth(c) {
|
||||||
a = id(c);
|
a = id(c);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
id(b) {
|
id(b) {
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
setA(x) {
|
/*setA(x) {
|
||||||
a = x;
|
a = x;
|
||||||
return a;
|
return a;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
m(x,y) {
|
m(x,y) {
|
||||||
x = id(y);
|
x = id(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
m2(x,y) {
|
/*m2(x,y) {
|
||||||
x = setA(y);
|
x = setA(y);
|
||||||
return x;
|
return x;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
}
|
}
|
@ -1,10 +1,10 @@
|
|||||||
class mathStruc {
|
public class mathStruc {
|
||||||
model;
|
model;
|
||||||
|
|
||||||
//Fun1*<Fun2*<A,A,A>, Fun1*<MathStruc <A>,MathStruc <A>>>
|
//Fun1*<Fun2*<A,A,A>, Fun1*<MathStruc <A>,MathStruc <A>>>
|
||||||
innerOp = (o) -> (ms) -> new mathStruc<>(o.apply(model,ms.model));
|
innerOp = (o) -> (ms) -> new mathStruc<>(o.apply(model,ms.model));
|
||||||
|
|
||||||
mathStruc(m) {
|
public mathStruc(m) {
|
||||||
model =m;
|
model =m;
|
||||||
//innerOp = (o) -> (ms) -> new mathStruc<>(o.apply(this.model,ms.model));
|
//innerOp = (o) -> (ms) -> new mathStruc<>(o.apply(this.model,ms.model));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user