Bytecode für arithmetische Operatoren mit Parametern unterschiedlicher Typen. Testfälle bereinigt und aufgeräumt.

This commit is contained in:
Fayez Abu Alia 2018-03-06 19:14:27 +01:00
parent 35b99a4095
commit f453343f1c
42 changed files with 505 additions and 456 deletions

View File

@ -38,7 +38,7 @@ 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;
@ -49,10 +49,10 @@ public class BytecodeGenMethod implements StatementVisitor{
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;
@ -62,9 +62,9 @@ public class BytecodeGenMethod implements StatementVisitor{
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;
@ -77,13 +77,13 @@ public class BytecodeGenMethod implements StatementVisitor{
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;
@ -92,7 +92,7 @@ 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++;
@ -104,10 +104,9 @@ public class BytecodeGenMethod implements StatementVisitor{
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);
} }
} }
@ -116,8 +115,8 @@ public class BytecodeGenMethod implements StatementVisitor{
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);
} }
// ?? // ??
@ -128,10 +127,11 @@ public class BytecodeGenMethod implements StatementVisitor{
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,41 +141,44 @@ 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: * Die folgeneden Fälle müssen noch betrachtet werden: - Long OPARATION Integer
* - Long OPARATION Integer usw. * 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":
@ -207,6 +210,28 @@ public class BytecodeGenMethod implements StatementVisitor{
} }
} }
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) {
@ -332,59 +357,59 @@ public class BytecodeGenMethod implements StatementVisitor{
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", "metafactory",
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", mt.toMethodDescriptorString(), false);
"metafactory", 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);
@ -392,50 +417,51 @@ public class BytecodeGenMethod implements StatementVisitor{
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) {
@ -453,17 +479,17 @@ public class BytecodeGenMethod implements StatementVisitor{
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
@ -489,21 +515,21 @@ public class BytecodeGenMethod implements StatementVisitor{
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
@ -514,8 +540,8 @@ public class BytecodeGenMethod implements StatementVisitor{
// 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";
@ -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
@ -582,8 +608,7 @@ public class BytecodeGenMethod implements StatementVisitor{
@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);
@ -592,35 +617,29 @@ public class BytecodeGenMethod implements StatementVisitor{
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":
@ -675,40 +694,33 @@ public class BytecodeGenMethod implements StatementVisitor{
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,58 +729,58 @@ 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);
} }
@ -776,39 +788,38 @@ public class BytecodeGenMethod implements StatementVisitor{
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()),
@ -817,9 +828,9 @@ public class BytecodeGenMethod implements StatementVisitor{
@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:::

View File

@ -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());
@ -130,4 +133,26 @@ public class JavaTXCompiler {
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");
}
}
} }

View File

@ -1,8 +0,0 @@
package bytecode;
public class ATest extends JavaTXCompilerTest {
public ATest() {
fileName = "Example";
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class AssignToLitTest extends JavaTXCompilerTest {
public AssignToLitTest() {
this.fileName = "AssignToLit";
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class DuMethodTest extends JavaTXCompilerTest{
public DuMethodTest() {
this.fileName = "DuMethod";
}
}

View File

@ -1,11 +0,0 @@
package bytecode;
import org.objectweb.asm.Opcodes;
public class ForTest extends JavaTXCompilerTest {
public ForTest() {
this.fileName = "For";
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class Generics2Test extends JavaTXCompilerTest{
public Generics2Test() {
this.fileName = "Generics2";
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class GenericsTest extends JavaTXCompilerTest {
public GenericsTest() {
this.fileName = "Generics";
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class ImportTest extends JavaTXCompilerTest{
public ImportTest() {
this.fileName = "Import";
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class InterfaceTest extends JavaTXCompilerTest{
public InterfaceTest() {
this.fileName = "Interface1";
}
}

View File

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

View File

@ -1,7 +0,0 @@
package bytecode;
public class LamAssignTest extends JavaTXCompilerTest{
public LamAssignTest() {
this.fileName = "LamAssign";
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class MethodsTest extends JavaTXCompilerTest {
public MethodsTest() {
this.fileName = "Methods";
}
}

View File

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

View File

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

View File

@ -1,7 +0,0 @@
package bytecode;
public class OverlaodGenTest extends JavaTXCompilerTest {
public OverlaodGenTest() {
this.fileName = "OverlaodGen";
}
}

View File

@ -1,7 +0,0 @@
package bytecode;
public class TestIfTest extends JavaTXCompilerTest{
public TestIfTest() {
this.fileName = "IfTest";
}
}

View 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;
// }
}