forked from JavaTX/JavaCompilerCore
Bytecode für arithmetische Operatoren mit Parametern unterschiedlicher Typen. Testfälle bereinigt und aufgeräumt.
This commit is contained in:
parent
35b99a4095
commit
f453343f1c
@ -38,34 +38,34 @@ import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
|||||||
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 BytecodeGenMethod implements StatementVisitor{
|
public class BytecodeGenMethod implements StatementVisitor {
|
||||||
|
|
||||||
private Method m;
|
private Method m;
|
||||||
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 = -1;
|
||||||
private ClassWriter cw;
|
private ClassWriter cw;
|
||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
private boolean isInterface;
|
private boolean isInterface;
|
||||||
HashMap<String, String> genericsAndBoundsMethod;
|
HashMap<String, String> genericsAndBoundsMethod;
|
||||||
private HashMap<String,String> genericsAndBounds;
|
private HashMap<String, String> genericsAndBounds;
|
||||||
private boolean isBinaryExp = false;
|
private boolean isBinaryExp = false;
|
||||||
|
|
||||||
//for tests **
|
// for tests **
|
||||||
private String fieldName;
|
private String fieldName;
|
||||||
private String fieldDesc;
|
private String fieldDesc;
|
||||||
private Expression rightSideTemp;
|
private Expression rightSideTemp;
|
||||||
private boolean isRightSideALambda = false;
|
private boolean isRightSideALambda = false;
|
||||||
private KindOfLambda kindOfLambda;
|
private KindOfLambda kindOfLambda;
|
||||||
private HashMap<String, byte[]> classFiles;
|
private HashMap<String, byte[]> classFiles;
|
||||||
|
|
||||||
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
|
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
|
||||||
|
|
||||||
public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv,
|
public BytecodeGenMethod(String className, ResultSet resultSet, Method m, MethodVisitor mv,
|
||||||
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
|
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
|
||||||
HashMap<String,String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
HashMap<String, String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
||||||
|
|
||||||
this.className = className;
|
this.className = className;
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.m = m;
|
this.m = m;
|
||||||
@ -76,15 +76,15 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
this.genericsAndBounds = genericsAndBounds;
|
this.genericsAndBounds = genericsAndBounds;
|
||||||
this.isInterface = isInterface;
|
this.isInterface = isInterface;
|
||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
|
|
||||||
if(!isInterface)
|
if (!isInterface)
|
||||||
this.m.block.accept(this);
|
this.m.block.accept(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv,
|
public BytecodeGenMethod(LambdaExpression lambdaExpression, ResultSet resultSet, MethodVisitor mv,
|
||||||
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
||||||
|
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
this.isInterface = isInterface;
|
this.isInterface = isInterface;
|
||||||
@ -92,46 +92,46 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||||
int i = indexOfFirstParamLam;
|
int i = indexOfFirstParamLam;
|
||||||
while(itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
FormalParameter fp = itr.next();
|
FormalParameter fp = itr.next();
|
||||||
this.paramsAndLocals.put(fp.getName(), i);
|
this.paramsAndLocals.put(fp.getName(), i);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
lambdaExpression.methodBody.accept(this);
|
lambdaExpression.methodBody.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Block block) {
|
public void visit(Block block) {
|
||||||
for(Statement stmt : block.getStatements()) {
|
for (Statement stmt : block.getStatements()) {
|
||||||
stmt.accept(this);
|
stmt.accept(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(SuperCall superCall) {
|
public void visit(SuperCall superCall) {
|
||||||
superCall.receiver.accept(this);
|
superCall.receiver.accept(this);
|
||||||
superCall.arglist.accept(this);
|
superCall.arglist.accept(this);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class),
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",
|
||||||
superCall.name, "()V",isInterface);
|
isInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ??
|
// ??
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVar localVar) {
|
public void visit(LocalVar localVar) {
|
||||||
// wenn String + String zuerst wird ein StringBuilder initialisiert dann
|
// wenn String + String zuerst wird ein StringBuilder initialisiert dann
|
||||||
// wird die lokale Var geladen. Sonst wird zuerst die lokale Var geladen.
|
// wird die lokale Var geladen. Sonst wird zuerst die lokale Var geladen.
|
||||||
|
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
|
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
|
||||||
|
|
||||||
if(isBinaryExp) {
|
if (isBinaryExp) {
|
||||||
getVlaueIns(getResolvedType(localVar.getType()));
|
getVlaueIns(getResolvedType(localVar.getType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ??
|
// ??
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVarDecl localVarDecl) {
|
public void visit(LocalVarDecl localVarDecl) {
|
||||||
@ -141,72 +141,97 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
@Override
|
@Override
|
||||||
public void visit(Assign assign) {
|
public void visit(Assign assign) {
|
||||||
// if the right side is a lambda => the left side must be a functional interface
|
// if the right side is a lambda => the left side must be a functional interface
|
||||||
if(assign.rightSide instanceof LambdaExpression) {
|
if (assign.rightSide instanceof LambdaExpression) {
|
||||||
isRightSideALambda = true;
|
isRightSideALambda = true;
|
||||||
}else {
|
} else {
|
||||||
isRightSideALambda = false;
|
isRightSideALambda = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(assign.rightSide instanceof BinaryExpr)
|
if (assign.rightSide instanceof BinaryExpr)
|
||||||
isBinaryExp = true;
|
isBinaryExp = true;
|
||||||
|
|
||||||
if(assign.lefSide instanceof AssignToField) {
|
if (assign.lefSide instanceof AssignToField) {
|
||||||
// load_0, ldc or .. then putfield
|
// load_0, ldc or .. then putfield
|
||||||
this.rightSideTemp = assign.rightSide;
|
this.rightSideTemp = assign.rightSide;
|
||||||
}else {
|
} else {
|
||||||
assign.rightSide.accept(this);
|
assign.rightSide.accept(this);
|
||||||
}
|
}
|
||||||
if(isBinaryExp) {
|
if (isBinaryExp) {
|
||||||
getValueOfIns(getResolvedType(assign.lefSide.getType()));
|
getValueOfIns(getResolvedType(assign.lefSide.getType()));
|
||||||
isBinaryExp = false;
|
isBinaryExp = false;
|
||||||
}
|
}
|
||||||
assign.lefSide.accept(this);
|
assign.lefSide.accept(this);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* Die folgeneden Fälle müssen noch betrachtet werden:
|
/*
|
||||||
* - Long OPARATION Integer usw.
|
* Die folgeneden Fälle müssen noch betrachtet werden: - Long OPARATION Integer
|
||||||
* */
|
* usw.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void visit(BinaryExpr binary) {
|
public void visit(BinaryExpr binary) {
|
||||||
String typeOfBinary = getResolvedType(binary.getType());
|
String typeOfBinary = getResolvedType(binary.getType());
|
||||||
if(typeOfBinary.equals(Type.getInternalName(String.class))) {
|
if (typeOfBinary.equals(Type.getInternalName(String.class))) {
|
||||||
mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class));
|
mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class));
|
||||||
mv.visitInsn(Opcodes.DUP);
|
mv.visitInsn(Opcodes.DUP);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class),
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class), "<init>", "()V",
|
||||||
"<init>", "()V", false);
|
false);
|
||||||
}
|
}
|
||||||
binary.lexpr.accept(this);
|
binary.lexpr.accept(this);
|
||||||
|
if(!getResolvedType(binary.lexpr.getType()).equals(typeOfBinary))
|
||||||
|
doCast(getResolvedType(binary.lexpr.getType()), typeOfBinary);
|
||||||
binary.rexpr.accept(this);
|
binary.rexpr.accept(this);
|
||||||
switch (binary.operation.toString()) {
|
switch (binary.operation.toString()) {
|
||||||
case "ADD":
|
case "ADD":
|
||||||
doVisitAddOpInsn(typeOfBinary);
|
doVisitAddOpInsn(typeOfBinary);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "SUB":
|
case "SUB":
|
||||||
doVisitSubOpInsn(typeOfBinary);
|
doVisitSubOpInsn(typeOfBinary);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "MUL":
|
case "MUL":
|
||||||
doVisitMulOpInsn(typeOfBinary);
|
doVisitMulOpInsn(typeOfBinary);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "DIV":
|
case "DIV":
|
||||||
doVisitDivOpInsn(typeOfBinary);
|
doVisitDivOpInsn(typeOfBinary);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "MOD":
|
case "MOD":
|
||||||
doVisitModOpInsn(typeOfBinary);
|
doVisitModOpInsn(typeOfBinary);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "LESSTHAN":
|
case "LESSTHAN":
|
||||||
doVisitLessOpInsn(typeOfBinary);
|
doVisitLessOpInsn(typeOfBinary);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doCast(String typeOfExp, String typeOfBinary) {
|
||||||
|
switch (typeOfBinary) {
|
||||||
|
case "java/lang/Long":
|
||||||
|
mv.visitInsn(Opcodes.I2L);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "java/lang/Double":
|
||||||
|
if(typeOfExp.equals(Type.getInternalName(Long.class))) {
|
||||||
|
mv.visitInsn(Opcodes.L2D);
|
||||||
|
} else if(typeOfExp.equals(Type.getInternalName(Float.class))) {
|
||||||
|
mv.visitInsn(Opcodes.F2D);
|
||||||
|
} else {
|
||||||
|
mv.visitInsn(Opcodes.I2D);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
private void doVisitLessOpInsn(String typeOfBinary) {
|
private void doVisitLessOpInsn(String typeOfBinary) {
|
||||||
switch (typeOfBinary) {
|
switch (typeOfBinary) {
|
||||||
@ -298,7 +323,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
mv.visitInsn(Opcodes.ISUB);
|
mv.visitInsn(Opcodes.ISUB);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doVisitAddOpInsn(String typeOfBinary) {
|
private void doVisitAddOpInsn(String typeOfBinary) {
|
||||||
@ -329,147 +354,148 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
@Override
|
@Override
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
public void visit(LambdaExpression lambdaExpression) {
|
||||||
this.lamCounter++;
|
this.lamCounter++;
|
||||||
|
|
||||||
Lambda lam = new Lambda(lambdaExpression);
|
Lambda lam = new Lambda(lambdaExpression);
|
||||||
String lamDesc = lam.accept(new DescriptorToString(resultSet));
|
String lamDesc = lam.accept(new DescriptorToString(resultSet));
|
||||||
//Call site, which, when invoked, returns an instance of the functional interface to which
|
// Call site, which, when invoked, returns an instance of the functional
|
||||||
//the lambda is being converted
|
// interface to which
|
||||||
|
// the lambda is being converted
|
||||||
MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
|
MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
|
||||||
MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
|
MethodType.class, MethodType.class, MethodHandle.class, MethodType.class);
|
||||||
|
|
||||||
|
|
||||||
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory",
|
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory",
|
||||||
"metafactory", mt.toMethodDescriptorString(), false);
|
mt.toMethodDescriptorString(), false);
|
||||||
String methodName = "lambda$new$" + this.lamCounter;
|
String methodName = "lambda$new$" + this.lamCounter;
|
||||||
|
|
||||||
// Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die Typlöschung)
|
// Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die
|
||||||
|
// Typlöschung)
|
||||||
|
|
||||||
String typeErasure = "(";
|
String typeErasure = "(";
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||||
while(itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
itr.next();
|
itr.next();
|
||||||
typeErasure += "L"+Type.getInternalName(Object.class) + ";";
|
typeErasure += "L" + Type.getInternalName(Object.class) + ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
typeErasure += ")L"+Type.getInternalName(Object.class) + ";";
|
typeErasure += ")L" + Type.getInternalName(Object.class) + ";";
|
||||||
// Type erasure
|
// Type erasure
|
||||||
Type arg1 = Type.getMethodType(typeErasure);
|
Type arg1 = Type.getMethodType(typeErasure);
|
||||||
// Type arg1 = Type.getMethodType(lamDesc);
|
// Type arg1 = Type.getMethodType(lamDesc);
|
||||||
// real Type
|
// real Type
|
||||||
Type arg3 = Type.getMethodType(lamDesc);
|
Type arg3 = Type.getMethodType(lamDesc);
|
||||||
|
|
||||||
int staticOrSpecial=0;
|
int staticOrSpecial = 0;
|
||||||
int staticOrInstance=0;
|
int staticOrInstance = 0;
|
||||||
int indexOfFirstParamLam = 0;
|
int indexOfFirstParamLam = 0;
|
||||||
this.kindOfLambda = new KindOfLambda(lambdaExpression);
|
this.kindOfLambda = new KindOfLambda(lambdaExpression);
|
||||||
|
|
||||||
if(kindOfLambda.isInstanceCapturingLambda()) {
|
if (kindOfLambda.isInstanceCapturingLambda()) {
|
||||||
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
mv.visitVarInsn(Opcodes.ALOAD, 0);
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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,
|
Handle arg2 = new Handle(staticOrSpecial, this.className, methodName, arg3.toString(), false);
|
||||||
arg3.toString(),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
|
||||||
String fiMethodDesc = samMethod.accept(new DescriptorToString(resultSet));
|
String fiMethodDesc = samMethod.accept(new DescriptorToString(resultSet));
|
||||||
mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2,arg3);
|
mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2, arg3);
|
||||||
|
|
||||||
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ staticOrInstance + Opcodes.ACC_SYNTHETIC,
|
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE + staticOrInstance + Opcodes.ACC_SYNTHETIC,
|
||||||
methodName, arg3.toString(), null, null);
|
methodName, arg3.toString(), null, null);
|
||||||
|
|
||||||
new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,indexOfFirstParamLam,isInterface,
|
new BytecodeGenMethod(lambdaExpression, this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface,
|
||||||
classFiles);
|
classFiles);
|
||||||
|
|
||||||
mvLambdaBody.visitMaxs(0, 0);
|
mvLambdaBody.visitMaxs(0, 0);
|
||||||
mvLambdaBody.visitEnd();
|
mvLambdaBody.visitEnd();
|
||||||
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
|
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
|
||||||
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
|
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
|
||||||
|
|
||||||
// generateBCForFunN(lambdaExpression,typeErasure);
|
// generateBCForFunN(lambdaExpression,typeErasure);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
|
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
|
||||||
ClassWriter classWriter =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||||
|
|
||||||
SignatureWriter methSig = new SignatureWriter();
|
SignatureWriter methSig = new SignatureWriter();
|
||||||
|
|
||||||
int numberOfParams = 0;
|
int numberOfParams = 0;
|
||||||
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||||
while(itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
numberOfParams++;
|
numberOfParams++;
|
||||||
// getBounds
|
// getBounds
|
||||||
paramVisitor.visitTypeVariable("T"+numberOfParams);
|
paramVisitor.visitTypeVariable("T" + numberOfParams);
|
||||||
itr.next();
|
itr.next();
|
||||||
}
|
}
|
||||||
methSig.visitReturnType().visitTypeVariable("R");
|
methSig.visitReturnType().visitTypeVariable("R");
|
||||||
// ")"+lam.getReturn.getBounds
|
// ")"+lam.getReturn.getBounds
|
||||||
Signature sig = new Signature(lambdaExpression,numberOfParams);
|
Signature sig = new Signature(lambdaExpression, numberOfParams);
|
||||||
String name = "Fun"+numberOfParams;
|
String name = "Fun" + numberOfParams;
|
||||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_INTERFACE+Opcodes.ACC_ABSTRACT, name,
|
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
||||||
sig.toString(), Type.getInternalName(Object.class), null);
|
Type.getInternalName(Object.class), null);
|
||||||
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT, "apply",
|
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
||||||
methDesc, methSig.toString(), null);
|
methSig.toString(), null);
|
||||||
mvApply.visitEnd();
|
mvApply.visitEnd();
|
||||||
writeClassFile(classWriter.toByteArray(),name);
|
writeClassFile(classWriter.toByteArray(), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeClassFile(byte[] bytecode, String name) {
|
public void writeClassFile(byte[] bytecode, String name) {
|
||||||
FileOutputStream output;
|
FileOutputStream output;
|
||||||
try {
|
try {
|
||||||
System.out.println("generating "+name+ ".class file...");
|
System.out.println("generating " + name + ".class file...");
|
||||||
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/examples/" +name+".class"));
|
output = new FileOutputStream(
|
||||||
|
new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/examples/" + name + ".class"));
|
||||||
output.write(bytecode);
|
output.write(bytecode);
|
||||||
output.close();
|
output.close();
|
||||||
System.out.println(name+".class file generated");
|
System.out.println(name + ".class file generated");
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CastExpr castExpr) {
|
public void visit(CastExpr castExpr) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(EmptyStmt emptyStmt) {
|
public void visit(EmptyStmt emptyStmt) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(FieldVar fieldVar) {
|
public void visit(FieldVar fieldVar) {
|
||||||
|
|
||||||
fieldName = fieldVar.fieldVarName;
|
fieldName = fieldVar.fieldVarName;
|
||||||
fieldDesc = "L"+getResolvedType(fieldVar.getType())+";";
|
fieldDesc = "L" + getResolvedType(fieldVar.getType()) + ";";
|
||||||
|
|
||||||
fieldVar.receiver.accept(this);
|
fieldVar.receiver.accept(this);
|
||||||
// test (if)
|
// test (if)
|
||||||
if(!fieldVar.receiver.getClass().equals(StaticClassName.class)) {
|
if (!fieldVar.receiver.getClass().equals(StaticClassName.class)) {
|
||||||
mv.visitFieldInsn(Opcodes.GETFIELD,getResolvedType(fieldVar.receiver.getType()),
|
mv.visitFieldInsn(Opcodes.GETFIELD, getResolvedType(fieldVar.receiver.getType()), fieldName, fieldDesc);
|
||||||
fieldName ,fieldDesc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mv.visitFieldInsn(Opcodes.GETSTATIC, fieldVar.receiver.getType().toString().replace(".", "/"),
|
// mv.visitFieldInsn(Opcodes.GETSTATIC,
|
||||||
// fieldVar.fieldVarName, fieldVar.getType().toString());
|
// fieldVar.receiver.getType().toString().replace(".", "/"),
|
||||||
|
// fieldVar.fieldVarName, fieldVar.getType().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ForStmt forStmt) {
|
public void visit(ForStmt forStmt) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -480,52 +506,52 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
@Override
|
@Override
|
||||||
public void visit(InstanceOf instanceOf) {
|
public void visit(InstanceOf instanceOf) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
methodCall.receiver.accept(this);
|
methodCall.receiver.accept(this);
|
||||||
methodCall.arglist.accept(this);
|
methodCall.arglist.accept(this);
|
||||||
|
|
||||||
MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
|
MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
|
||||||
genericsAndBoundsMethod,genericsAndBounds);
|
genericsAndBoundsMethod, genericsAndBounds);
|
||||||
String mDesc = method.accept(new DescriptorToString(resultSet));
|
String mDesc = method.accept(new DescriptorToString(resultSet));
|
||||||
|
|
||||||
// is methodCall.receiver functional Interface)?
|
// is methodCall.receiver functional Interface)?
|
||||||
if(varsFunInterface.contains(methodCall.receiver.getType())) {
|
if (varsFunInterface.contains(methodCall.receiver.getType())) {
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()),
|
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), methodCall.name,
|
||||||
methodCall.name, mDesc, false);
|
mDesc, false);
|
||||||
}else {
|
} else {
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()),
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()), methodCall.name,
|
||||||
methodCall.name, mDesc, isInterface);
|
mDesc, isInterface);
|
||||||
}
|
}
|
||||||
// test
|
// test
|
||||||
// if(!methodCall.getType().toString().equals("V")) {
|
// if(!methodCall.getType().toString().equals("V")) {
|
||||||
// mv.visitInsn(Opcodes.POP);
|
// mv.visitInsn(Opcodes.POP);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewClass methodCall) {
|
public void visit(NewClass methodCall) {
|
||||||
|
|
||||||
mv.visitTypeInsn(Opcodes.NEW, methodCall.name.replace(".", "/"));
|
mv.visitTypeInsn(Opcodes.NEW, methodCall.name.replace(".", "/"));
|
||||||
mv.visitInsn(Opcodes.DUP);
|
mv.visitInsn(Opcodes.DUP);
|
||||||
// creates Descriptor
|
// creates Descriptor
|
||||||
methodCall.arglist.accept(this);
|
methodCall.arglist.accept(this);
|
||||||
String d = "(";
|
String d = "(";
|
||||||
for(Expression e : methodCall.arglist.getArguments()) {
|
for (Expression e : methodCall.arglist.getArguments()) {
|
||||||
d = d + "L"+getResolvedType(e.getType()) + ";";
|
d = d + "L" + getResolvedType(e.getType()) + ";";
|
||||||
}
|
}
|
||||||
d += ")V";
|
d += ")V";
|
||||||
|
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "<init>", d, isInterface);
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "<init>", d, isInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewArray newArray) {
|
public void visit(NewArray newArray) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -551,10 +577,10 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
// mv.visitMethodInsn(Opcodes.INVOKESTATIC, staticClassName.getType().toString().replace(".", "/"),
|
// mv.visitMethodInsn(Opcodes.INVOKESTATIC,
|
||||||
// staticClassName.toString(), staticClassName.getType().toString(), false);
|
// staticClassName.getType().toString().replace(".", "/"),
|
||||||
mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()),
|
// staticClassName.toString(), staticClassName.getType().toString(), false);
|
||||||
fieldName, fieldDesc);
|
mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()), fieldName, fieldDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -576,51 +602,44 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
@Override
|
@Override
|
||||||
public void visit(DoStmt whileStmt) {
|
public void visit(DoStmt whileStmt) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Literal literal) {
|
public void visit(Literal literal) {
|
||||||
Object value = literal.value;
|
Object value = literal.value;
|
||||||
String typeOfLiteral = resultSet.resolveType(
|
String typeOfLiteral = resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
literal.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
|
||||||
|
|
||||||
doAssign(typeOfLiteral, value);
|
doAssign(typeOfLiteral, value);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getVlaueIns(String type) {
|
private void getVlaueIns(String type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "java/lang/String":
|
case "java/lang/String":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class),
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
|
||||||
"append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
|
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Boolean":
|
case "java/lang/Boolean":
|
||||||
break;
|
break;
|
||||||
case "java/lang/Byte":
|
case "java/lang/Byte":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
|
||||||
"()B", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Short":
|
case "java/lang/Short":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
|
||||||
"()S", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Integer":
|
case "java/lang/Integer":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
|
||||||
"()I", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Long":
|
case "java/lang/Long":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
|
||||||
"()J", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case "java/lang/Float":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
|
||||||
"()F", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case "java/lang/Double":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
|
||||||
"()D", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Character":
|
case "java/lang/Character":
|
||||||
break;
|
break;
|
||||||
@ -638,24 +657,24 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
visitBooleanLiteral((Boolean) value);
|
visitBooleanLiteral((Boolean) value);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Byte":
|
case "java/lang/Byte":
|
||||||
visitByteLiteral(((Double) value).byteValue(),false);
|
visitByteLiteral(((Double) value).byteValue(), false);
|
||||||
if(!this.isBinaryExp)
|
if (!this.isBinaryExp)
|
||||||
getValueOfIns(type);
|
getValueOfIns(type);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Short":
|
case "java/lang/Short":
|
||||||
visitShortLiteral(((Double) value).shortValue(),false);
|
visitShortLiteral(((Double) value).shortValue(), false);
|
||||||
if(!this.isBinaryExp)
|
if (!this.isBinaryExp)
|
||||||
getValueOfIns(type);
|
getValueOfIns(type);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Integer":
|
case "java/lang/Integer":
|
||||||
//zweite Argument isLong
|
// zweite Argument isLong
|
||||||
visitIntegerLiteral(((Double) value).intValue(), false);
|
visitIntegerLiteral(((Double) value).intValue(), false);
|
||||||
if(!this.isBinaryExp)
|
if (!this.isBinaryExp)
|
||||||
getValueOfIns(type);
|
getValueOfIns(type);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Long":
|
case "java/lang/Long":
|
||||||
visitLongLiteral(((Double) value).longValue(), true);
|
visitLongLiteral(((Double) value).longValue(), true);
|
||||||
if(!this.isBinaryExp)
|
if (!this.isBinaryExp)
|
||||||
getValueOfIns(type);
|
getValueOfIns(type);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case "java/lang/Float":
|
||||||
@ -671,44 +690,37 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getValueOfIns(String type) {
|
private void getValueOfIns(String type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "java/lang/String":
|
case "java/lang/String":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
|
||||||
"()Ljava/lang/String;", false);
|
false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Boolean":
|
case "java/lang/Boolean":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
||||||
"(Z)Ljava/lang/Boolean;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Byte":
|
case "java/lang/Byte":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
|
||||||
"(B)Ljava/lang/Byte;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Short":
|
case "java/lang/Short":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
|
||||||
"(S)Ljava/lang/Short;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Integer":
|
case "java/lang/Integer":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
|
||||||
"(I)Ljava/lang/Integer;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Long":
|
case "java/lang/Long":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
|
||||||
"(J)Ljava/lang/Long;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case "java/lang/Float":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
|
||||||
"(F)Ljava/lang/Float;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case "java/lang/Double":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
|
||||||
"(D)Ljava/lang/Double;", false);
|
|
||||||
break;
|
break;
|
||||||
case "java/lang/Character":
|
case "java/lang/Character":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;",
|
||||||
"(C)Ljava/lang/Character;", false);
|
false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -717,112 +729,111 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
private void visitCharLiteral(Character value) {
|
private void visitCharLiteral(Character value) {
|
||||||
mv.visitIntInsn(Opcodes.BIPUSH, (int) value);
|
mv.visitIntInsn(Opcodes.BIPUSH, (int) value);
|
||||||
if(!this.isBinaryExp)
|
if (!this.isBinaryExp)
|
||||||
getValueOfIns(Type.getInternalName(Character.class));
|
getValueOfIns(Type.getInternalName(Character.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitDoubleLiteral(Double value) {
|
private void visitDoubleLiteral(Double value) {
|
||||||
if(value == 0) {
|
if (value == 0) {
|
||||||
mv.visitInsn(Opcodes.DCONST_0);
|
mv.visitInsn(Opcodes.DCONST_0);
|
||||||
}else if(value == 1) {
|
} else if (value == 1) {
|
||||||
mv.visitInsn(Opcodes.DCONST_1);
|
mv.visitInsn(Opcodes.DCONST_1);
|
||||||
}else {
|
} else {
|
||||||
mv.visitLdcInsn(value);
|
mv.visitLdcInsn(value);
|
||||||
}
|
}
|
||||||
if(!this.isBinaryExp)
|
if (!this.isBinaryExp)
|
||||||
getValueOfIns(Type.getInternalName(Double.class));
|
getValueOfIns(Type.getInternalName(Double.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitFloatLiteral(Float value) {
|
private void visitFloatLiteral(Float value) {
|
||||||
if(value.intValue()>-1 && value.intValue() < 3) {
|
if (value.intValue() > -1 && value.intValue() < 3) {
|
||||||
//Opcodes.FCONST_0 = 11, Opcodes.FCONST_1 = 12, usw
|
// Opcodes.FCONST_0 = 11, Opcodes.FCONST_1 = 12, usw
|
||||||
mv.visitInsn(value.intValue()+11);
|
mv.visitInsn(value.intValue() + 11);
|
||||||
}else {
|
} else {
|
||||||
mv.visitLdcInsn(value);
|
mv.visitLdcInsn(value);
|
||||||
}
|
}
|
||||||
if(!this.isBinaryExp)
|
if (!this.isBinaryExp)
|
||||||
getValueOfIns(Type.getInternalName(Float.class));
|
getValueOfIns(Type.getInternalName(Float.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitLongLiteral(Long value, boolean isLong) {
|
private void visitLongLiteral(Long value, boolean isLong) {
|
||||||
if(value<Math.pow(2, 15) || (value>=-Math.pow(2, 15))&&value<-128) {
|
if (value < Math.pow(2, 15) || (value >= -Math.pow(2, 15)) && value < -128) {
|
||||||
visitShortLiteral(value.shortValue(),isLong);
|
visitShortLiteral(value.shortValue(), isLong);
|
||||||
}else {
|
} else {
|
||||||
mv.visitLdcInsn(value);
|
mv.visitLdcInsn(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitShortLiteral(Short value,boolean isLong) {
|
private void visitShortLiteral(Short value, boolean isLong) {
|
||||||
if(value< 128 || (value>-129 && value<-1)) {
|
if (value < 128 || (value > -129 && value < -1)) {
|
||||||
visitByteLiteral(value.byteValue(), isLong);
|
visitByteLiteral(value.byteValue(), isLong);
|
||||||
}else if(value<Math.pow(2, 15) || (value>=-Math.pow(2, 15))&&value<-128) {
|
} else if (value < Math.pow(2, 15) || (value >= -Math.pow(2, 15)) && value < -128) {
|
||||||
mv.visitIntInsn(Opcodes.SIPUSH, value);
|
mv.visitIntInsn(Opcodes.SIPUSH, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitByteLiteral(Byte value, boolean isLong) {
|
private void visitByteLiteral(Byte value, boolean isLong) {
|
||||||
|
|
||||||
if(!isLong && value<6 && value>-1) {
|
if (!isLong && value < 6 && value > -1) {
|
||||||
//Opcodes.ICONST_0 = 3, Opcodes.ICONST_1 = 4, usw
|
// Opcodes.ICONST_0 = 3, Opcodes.ICONST_1 = 4, usw
|
||||||
mv.visitInsn(value+3);
|
mv.visitInsn(value + 3);
|
||||||
}else if(isLong && value>-1 && value<2){
|
} else if (isLong && value > -1 && value < 2) {
|
||||||
//Opcodes.LCONST_0 = 9, Opcodes.LCONST_1 = 10
|
// Opcodes.LCONST_0 = 9, Opcodes.LCONST_1 = 10
|
||||||
mv.visitInsn(value+9);
|
mv.visitInsn(value + 9);
|
||||||
}else {
|
} else {
|
||||||
mv.visitIntInsn(Opcodes.BIPUSH, value);
|
mv.visitIntInsn(Opcodes.BIPUSH, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitIntegerLiteral(Integer value, boolean isLong) {
|
private void visitIntegerLiteral(Integer value, boolean isLong) {
|
||||||
|
|
||||||
if(value<Math.pow(2, 15) || (value>=-Math.pow(2, 15))&&value<-128) {
|
if (value < Math.pow(2, 15) || (value >= -Math.pow(2, 15)) && value < -128) {
|
||||||
visitShortLiteral(value.shortValue(),isLong);
|
visitShortLiteral(value.shortValue(), isLong);
|
||||||
}else {
|
} else {
|
||||||
mv.visitLdcInsn(value);
|
mv.visitLdcInsn(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitBooleanLiteral(Boolean b) {
|
private void visitBooleanLiteral(Boolean b) {
|
||||||
if(b) {
|
if (b) {
|
||||||
mv.visitInsn(Opcodes.ICONST_1);
|
mv.visitInsn(Opcodes.ICONST_1);
|
||||||
}else {
|
} else {
|
||||||
mv.visitInsn(Opcodes.ICONST_0);
|
mv.visitInsn(Opcodes.ICONST_0);
|
||||||
}
|
}
|
||||||
// muss noch getestet werden.
|
// muss noch getestet werden.
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf",
|
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
||||||
"(Z)Ljava/lang/Boolean;", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ArgumentList argumentList) {
|
public void visit(ArgumentList argumentList) {
|
||||||
for(Expression al : argumentList.getArguments()) {
|
for (Expression al : argumentList.getArguments()) {
|
||||||
al.accept(this);
|
al.accept(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignToField assignLeftSide) {
|
public void visit(AssignToField assignLeftSide) {
|
||||||
// temporäre Lösung für testen, bis ich weiss wie man funktionale
|
// temporäre Lösung für testen, bis ich weiss wie man funktionale
|
||||||
// interfaces erkennt
|
// interfaces erkennt
|
||||||
if(isRightSideALambda)
|
if (isRightSideALambda)
|
||||||
varsFunInterface.add(assignLeftSide.field.getType());
|
varsFunInterface.add(assignLeftSide.field.getType());
|
||||||
// Loads the an object reference from the local variable
|
// Loads the an object reference from the local variable
|
||||||
// array slot onto the top of the operand stack.
|
// array slot onto the top of the operand stack.
|
||||||
assignLeftSide.field.receiver.accept(this);
|
assignLeftSide.field.receiver.accept(this);
|
||||||
this.rightSideTemp.accept(this);
|
this.rightSideTemp.accept(this);
|
||||||
mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()),
|
mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()),
|
||||||
assignLeftSide.field.fieldVarName, getResolvedType(assignLeftSide.field.getType()));
|
assignLeftSide.field.fieldVarName, getResolvedType(assignLeftSide.field.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignToLocal assignLeftSide) {
|
public void visit(AssignToLocal assignLeftSide) {
|
||||||
if(isRightSideALambda)
|
if (isRightSideALambda)
|
||||||
varsFunInterface.add(assignLeftSide.localVar.getType());
|
varsFunInterface.add(assignLeftSide.localVar.getType());
|
||||||
paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size()+1);
|
paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size() + 1);
|
||||||
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.size());
|
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.size());
|
||||||
// Debug:::
|
// Debug:::
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package de.dhbwstuttgart.core;
|
package de.dhbwstuttgart.core;
|
||||||
|
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.BytecodeGen;
|
||||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||||
@ -23,6 +24,8 @@ import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
|||||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -103,7 +106,7 @@ public class JavaTXCompiler {
|
|||||||
System.out.println(xConsSet);
|
System.out.println(xConsSet);
|
||||||
Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
||||||
System.out.println("RESULT: " + result.size());
|
System.out.println("RESULT: " + result.size());
|
||||||
//results.addAll(result);
|
results.addAll(result);
|
||||||
}
|
}
|
||||||
return results.stream().map((unifyPairs ->
|
return results.stream().map((unifyPairs ->
|
||||||
new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList());
|
new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList());
|
||||||
@ -129,5 +132,27 @@ public class JavaTXCompiler {
|
|||||||
SourceFile ret = generator.convert(tree, environment.packageCrawler);
|
SourceFile ret = generator.convert(tree, environment.packageCrawler);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void generateBytecode() throws ClassNotFoundException, IOException {
|
||||||
|
for(File f : sourceFiles.keySet()) {
|
||||||
|
HashMap<String,byte[]> classFiles = new HashMap<>();
|
||||||
|
SourceFile sf = sourceFiles.get(f);
|
||||||
|
List<ResultSet> typeinferenceResult = this.typeInference();
|
||||||
|
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0));
|
||||||
|
bytecodeGen.visit(sf);
|
||||||
|
this.writeClassFile(bytecodeGen.getClassFiles());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeClassFile(HashMap<String, byte[]> classFiles) throws IOException {
|
||||||
|
FileOutputStream output;
|
||||||
|
for(String name : classFiles.keySet()) {
|
||||||
|
byte[] bytecode = classFiles.get(name);
|
||||||
|
System.out.println("generating "+name+ ".class file ...");
|
||||||
|
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class"));
|
||||||
|
output.write(bytecode);
|
||||||
|
output.close();
|
||||||
|
System.out.println(name+".class file generated");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,8 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class ATest extends JavaTXCompilerTest {
|
|
||||||
public ATest() {
|
|
||||||
fileName = "Example";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class AssignToLitTest extends JavaTXCompilerTest {
|
|
||||||
public AssignToLitTest() {
|
|
||||||
this.fileName = "AssignToLit";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class DuMethodTest extends JavaTXCompilerTest{
|
|
||||||
public DuMethodTest() {
|
|
||||||
this.fileName = "DuMethod";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
import org.objectweb.asm.Opcodes;
|
|
||||||
|
|
||||||
public class ForTest extends JavaTXCompilerTest {
|
|
||||||
|
|
||||||
public ForTest() {
|
|
||||||
this.fileName = "For";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class Generics2Test extends JavaTXCompilerTest{
|
|
||||||
public Generics2Test() {
|
|
||||||
this.fileName = "Generics2";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class GenericsTest extends JavaTXCompilerTest {
|
|
||||||
public GenericsTest() {
|
|
||||||
this.fileName = "Generics";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class ImportTest extends JavaTXCompilerTest{
|
|
||||||
public ImportTest() {
|
|
||||||
this.fileName = "Import";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class InterfaceTest extends JavaTXCompilerTest{
|
|
||||||
public InterfaceTest() {
|
|
||||||
this.fileName = "Interface1";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.BytecodeGen;
|
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
public class JavaTXCompilerTest {
|
|
||||||
|
|
||||||
private static final String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
|
|
||||||
private static final List<File> filesToTest = new ArrayList<>();
|
|
||||||
|
|
||||||
protected String fileName = "";
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test() throws IOException, java.lang.ClassNotFoundException {
|
|
||||||
System.out.println(rootDirectory);
|
|
||||||
filesToTest.add(new File(rootDirectory+fileName+".jav"));
|
|
||||||
System.out.println(rootDirectory+fileName+".jav");
|
|
||||||
JavaTXCompiler compiler = new JavaTXCompiler(filesToTest);
|
|
||||||
for(File f : filesToTest){
|
|
||||||
String content = readFile(f.getPath(), StandardCharsets.UTF_8);
|
|
||||||
List<ResultSet> typeinferenceResult = compiler.typeInference();
|
|
||||||
HashMap<String,byte[]> bytecode = this.getBytecode(compiler.sourceFiles.get(f), typeinferenceResult.get(0));
|
|
||||||
|
|
||||||
// for(ResultPair ep : typeinferenceResult.get(0).results) {
|
|
||||||
// System.out.println(ep.getLeft() + " ->" + ep.getRight());
|
|
||||||
// }
|
|
||||||
|
|
||||||
String name;
|
|
||||||
int pos = f.getName().lastIndexOf(".");
|
|
||||||
if(pos != -1) {
|
|
||||||
name = f.getName().substring(0, pos);
|
|
||||||
}
|
|
||||||
this.writeClassFile(bytecode);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public HashMap<String,byte[]> getBytecode(SourceFile sf, ResultSet resultSet) {
|
|
||||||
HashMap<String,byte[]> classFiles = new HashMap<>();
|
|
||||||
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,resultSet);
|
|
||||||
bytecodeGen.visit(sf);
|
|
||||||
return bytecodeGen.getClassFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void writeClassFile(HashMap<String,byte[]> classFiles) {
|
|
||||||
FileOutputStream output;
|
|
||||||
for(String name : classFiles.keySet()) {
|
|
||||||
byte[] bytecode = classFiles.get(name);
|
|
||||||
try {
|
|
||||||
System.out.println("generating "+name+ ".class file ...");
|
|
||||||
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class"));
|
|
||||||
output.write(bytecode);
|
|
||||||
output.close();
|
|
||||||
System.out.println(name+".class file generated");
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static String readFile(String path, Charset encoding)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
byte[] encoded = Files.readAllBytes(Paths.get(path));
|
|
||||||
return new String(encoded, encoding);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class LamAssignTest extends JavaTXCompilerTest{
|
|
||||||
public LamAssignTest() {
|
|
||||||
this.fileName = "LamAssign";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class MethodsTest extends JavaTXCompilerTest {
|
|
||||||
public MethodsTest() {
|
|
||||||
this.fileName = "Methods";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
import java.lang.Integer;
|
|
||||||
import java.lang.String;
|
|
||||||
import java.lang.Long;
|
|
||||||
import java.lang.Float;
|
|
||||||
import java.lang.Double;
|
|
||||||
import java.lang.Boolean;
|
|
||||||
|
|
||||||
class Op {
|
|
||||||
addInt(Integer a, Integer b) {
|
|
||||||
Integer c = a+b;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
addString(String a, String b) {
|
|
||||||
String c = a+b;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
addLong(Long a, Long b) {
|
|
||||||
Long c = a+b;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
addFloat(Float a, Float b) {
|
|
||||||
Float c = a+b;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
addDouble(Double a, Double b) {
|
|
||||||
Double c = a+b;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
subInt(Integer a, Integer b) {
|
|
||||||
Integer c = a-b;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
subLong(Long a, Long b) {
|
|
||||||
Long c = a-b;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
subFloat(Float a, Float b) {
|
|
||||||
Float c = a-b;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
subDouble(Double a, Double b) {
|
|
||||||
Double c = a-b;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,157 @@
|
|||||||
package bytecode;
|
package bytecode;
|
||||||
|
|
||||||
public class OpTest extends JavaTXCompilerTest {
|
import static org.junit.Assert.*;
|
||||||
public OpTest() {
|
|
||||||
this.fileName = "Op";
|
import java.io.File;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class OpTest {
|
||||||
|
private static String path;
|
||||||
|
private static File fileToTest;
|
||||||
|
private static JavaTXCompiler compiler;
|
||||||
|
private static ClassLoader loader;
|
||||||
|
private static Class<?> classToTest;
|
||||||
|
private static String pathToClassFile;
|
||||||
|
private static Object instanceOfClass;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Op.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode();
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("Op");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassname() {
|
||||||
|
assertEquals("Op", classToTest.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassModifiers() {
|
||||||
|
assertEquals(Opcodes.ACC_PUBLIC, classToTest.getModifiers());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNumberOfMethods() {
|
||||||
|
int numOfMeth = classToTest.getDeclaredMethods().length;
|
||||||
|
assertEquals(5, numOfMeth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddString() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
Method addString = classToTest.getDeclaredMethod("addString", String.class,String.class);
|
||||||
|
String result = (String) addString.invoke(instanceOfClass, "Byte","Code");
|
||||||
|
assertEquals("ByteCode", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddInt() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
Method addInt = classToTest.getDeclaredMethod("addInt", Integer.class,Integer.class);
|
||||||
|
Integer result = (Integer) addInt.invoke(instanceOfClass, 7,3);
|
||||||
|
assertEquals(10, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddLong() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
Method addLong = classToTest.getDeclaredMethod("addLong", Long.class,Long.class);
|
||||||
|
Long result = (Long) addLong.invoke(instanceOfClass, 7L,3L);
|
||||||
|
assertEquals(10L, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
Method addFloat = classToTest.getDeclaredMethod("addFloat", Float.class,Float.class);
|
||||||
|
Float result = (Float) addFloat.invoke(instanceOfClass, 7f,3f);
|
||||||
|
assertEquals(10f, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
Method addDouble = classToTest.getDeclaredMethod("addDouble", Double.class,Double.class);
|
||||||
|
Double result = (Double) addDouble.invoke(instanceOfClass, 7.0,3.0);
|
||||||
|
assertEquals(10.0, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// public void testAddIntLong() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
// Method add = classToTest.getDeclaredMethod("add", Integer.class,Long.class);
|
||||||
|
// Long result = (Long) add.invoke(instanceOfClass, 7,3L);
|
||||||
|
// assertEquals(10L, result);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// public void testAddDLong() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
// Method add = classToTest.getDeclaredMethod("add", Double.class,Long.class);
|
||||||
|
// Double result = (Double) add.invoke(instanceOfClass, 7d,3L);
|
||||||
|
// assertEquals(10d, result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void testAddIntShort() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
// Method add = classToTest.getDeclaredMethod("add", Integer.class,Short.class);
|
||||||
|
// Integer result = (Integer) add.invoke(instanceOfClass, 7,3);
|
||||||
|
// assertEquals(10, result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void testAddIntByte() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
// Method add = classToTest.getDeclaredMethod("add", Integer.class,Byte.class);
|
||||||
|
// Integer result = (Integer) add.invoke(instanceOfClass, 7,3);
|
||||||
|
// assertEquals(10, result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void testAddDFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
// Method add = classToTest.getDeclaredMethod("add", Float.class,Double.class);
|
||||||
|
// Double result = (Double) add.invoke(instanceOfClass, 7f,3d);
|
||||||
|
// assertEquals(10d, result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void testAddIntD() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
// Method add = classToTest.getDeclaredMethod("add", Integer.class,Double.class);
|
||||||
|
// Double result = (Double) add.invoke(instanceOfClass, 7,3d);
|
||||||
|
// assertEquals(10d, result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void testAddShortD() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
// Method add = classToTest.getDeclaredMethod("add", Short.class,Double.class);
|
||||||
|
// Double result = (Double) add.invoke(instanceOfClass, 7,3d);
|
||||||
|
// assertEquals(10d, result);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Test
|
||||||
|
// public void testAddByteD() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||||
|
// IllegalArgumentException, InvocationTargetException, InstantiationException {
|
||||||
|
// Method add = classToTest.getDeclaredMethod("add", Byte.class,Double.class);
|
||||||
|
// Double result = (Double) add.invoke(instanceOfClass, 7,3d);
|
||||||
|
// assertEquals(10d, result);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class OverlaodGenTest extends JavaTXCompilerTest {
|
|
||||||
public OverlaodGenTest() {
|
|
||||||
this.fileName = "OverlaodGen";
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package bytecode;
|
|
||||||
|
|
||||||
public class TestIfTest extends JavaTXCompilerTest{
|
|
||||||
public TestIfTest() {
|
|
||||||
this.fileName = "IfTest";
|
|
||||||
}
|
|
||||||
}
|
|
88
test/bytecode/javFiles/Op.jav
Normal file
88
test/bytecode/javFiles/Op.jav
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.String;
|
||||||
|
import java.lang.Long;
|
||||||
|
import java.lang.Float;
|
||||||
|
import java.lang.Double;
|
||||||
|
import java.lang.Boolean;
|
||||||
|
import java.lang.Short;
|
||||||
|
import java.lang.Byte;
|
||||||
|
|
||||||
|
public class Op {
|
||||||
|
addInt(Integer a, Integer b) {
|
||||||
|
Integer c = a+b;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
addString(String a, String b) {
|
||||||
|
String c = a+b;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
addLong(Long a, Long b) {
|
||||||
|
Long c = a+b;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
addFloat(Float a, Float b) {
|
||||||
|
Float c = a+b;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
addDouble(Double a, Double b) {
|
||||||
|
Double c = a+b;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// subInt(Integer a, Integer b) {
|
||||||
|
// Integer c = a-b;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
// subLong(Long a, Long b) {
|
||||||
|
// Long c = a-b;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
// subFloat(Float a, Float b) {
|
||||||
|
// Float c = a-b;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
// subDouble(Double a, Double b) {
|
||||||
|
// Double c = a-b;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Long add(Integer a, Long b) {
|
||||||
|
// Long c = a+b;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// add(Double a, Long b) {
|
||||||
|
// Double c = a+b;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// add(Integer a, Short b) {
|
||||||
|
// Integer c = a+b;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// add(Integer a, Byte b) {
|
||||||
|
// Integer c = a+b;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// add(Float a, Double b) {
|
||||||
|
// Double c = a+b;
|
||||||
|
// return c;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
// add(Integer a, Double b) {
|
||||||
|
// Double c = a+b;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// add(Short a, Double b) {
|
||||||
|
// Double c = a+b;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// add(Byte a, Double b) {
|
||||||
|
// Double c = a+b;
|
||||||
|
// return c;
|
||||||
|
// }
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user