Test cases and some fixes
This commit is contained in:
parent
699155e21a
commit
6e1786ec7c
@ -1,6 +1,5 @@
|
|||||||
package de.dhbwstuttgart.target.bytecode;
|
package de.dhbwstuttgart.target.bytecode;
|
||||||
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
|
||||||
import de.dhbwstuttgart.target.tree.*;
|
import de.dhbwstuttgart.target.tree.*;
|
||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetFunNType;
|
import de.dhbwstuttgart.target.tree.type.TargetFunNType;
|
||||||
@ -13,20 +12,22 @@ import java.lang.invoke.MethodHandle;
|
|||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.*;
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
|
import static de.dhbwstuttgart.target.tree.expression.TargetBinaryOp.*;
|
||||||
import static de.dhbwstuttgart.target.tree.expression.TargetLiteral.*;
|
import static de.dhbwstuttgart.target.tree.expression.TargetLiteral.*;
|
||||||
|
|
||||||
public class Codegen {
|
public class Codegen {
|
||||||
private TargetClass clazz;
|
private final TargetClass clazz;
|
||||||
private ClassWriter cw;
|
private final ClassWriter cw;
|
||||||
|
public final String className;
|
||||||
|
|
||||||
public Codegen(TargetClass clazz) {
|
public Codegen(TargetClass clazz) {
|
||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
|
this.className = clazz.qualifiedName();
|
||||||
this.cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
this.cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,14 +126,14 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateRelationalOperator(State state, TargetRelationalOp op, int code) {
|
private void generateRelationalOperator(State state, TargetRelationalOp op, TargetType type, int code) {
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
Label if_true = new Label();
|
Label if_true = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
generate(state, op.left());
|
generate(state, op.left());
|
||||||
convertTo(state, op.exprType(), op.type());
|
convertTo(state, op.left().type(), type);
|
||||||
generate(state, op.right());
|
generate(state, op.right());
|
||||||
convertTo(state, op.exprType(), op.type());
|
convertTo(state, op.right().type(), type);
|
||||||
mv.visitJumpInsn(code, if_true);
|
mv.visitJumpInsn(code, if_true);
|
||||||
mv.visitInsn(ICONST_0);
|
mv.visitInsn(ICONST_0);
|
||||||
mv.visitJumpInsn(GOTO, end);
|
mv.visitJumpInsn(GOTO, end);
|
||||||
@ -141,16 +142,15 @@ public class Codegen {
|
|||||||
mv.visitLabel(end);
|
mv.visitLabel(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateRelationalOperator(State state, TargetRelationalOp op, int cmp, int code) {
|
private void generateRelationalOperator(State state, TargetRelationalOp op, TargetType type, int cmp, int code) {
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
Label if_true = new Label();
|
Label if_true = new Label();
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
generate(state, op.left());
|
generate(state, op.left());
|
||||||
convertTo(state, op.left().type(), op.exprType());
|
convertTo(state, op.left().type(), type);
|
||||||
generate(state, op.right());
|
generate(state, op.right());
|
||||||
convertTo(state, op.right().type(), op.exprType());
|
convertTo(state, op.right().type(), type);
|
||||||
mv.visitInsn(cmp);
|
mv.visitInsn(cmp);
|
||||||
mv.visitInsn(code);
|
|
||||||
mv.visitJumpInsn(code, if_true);
|
mv.visitJumpInsn(code, if_true);
|
||||||
mv.visitInsn(ICONST_0);
|
mv.visitInsn(ICONST_0);
|
||||||
mv.visitJumpInsn(GOTO, end);
|
mv.visitJumpInsn(GOTO, end);
|
||||||
@ -159,14 +159,35 @@ public class Codegen {
|
|||||||
mv.visitLabel(end);
|
mv.visitLabel(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void convertToString(State state, TargetType type) {
|
||||||
|
var mv = state.mv;
|
||||||
|
if (type.equals(TargetType.Boolean)) {
|
||||||
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(Z)Ljava/lang/Boolean;", false);
|
||||||
|
} else if (type.equals(TargetType.Byte)) {
|
||||||
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(B)Ljava/lang/Byte;", false);
|
||||||
|
} else if (type.equals(TargetType.Double)) {
|
||||||
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(D)Ljava/lang/Double;", false);
|
||||||
|
} else if (type.equals(TargetType.Long)) {
|
||||||
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(J)Ljava/lang/Long;", false);
|
||||||
|
} else if (type.equals(TargetType.Integer)) {
|
||||||
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(I)Ljava/lang/Integer;", false);
|
||||||
|
} else if (type.equals(TargetType.Float)) {
|
||||||
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(F)Ljava/lang/Float;", false);
|
||||||
|
} else if (type.equals(TargetType.Short)) {
|
||||||
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(S)Ljava/lang/Short;", false);
|
||||||
|
} else if (type.equals(TargetType.Char)) {
|
||||||
|
mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(C)Ljava/lang/Char;", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void convertTo(State state, TargetType source, TargetType dest) {
|
private void convertTo(State state, TargetType source, TargetType dest) {
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
if (source.equals(dest))
|
if (source.equals(dest))
|
||||||
return;
|
return;
|
||||||
if (source.equals(TargetType.Long)) {
|
if (source.equals(TargetType.Long)) {
|
||||||
if (dest.equals(TargetType.Integer))
|
if (dest.equals(TargetType.Integer)) {
|
||||||
mv.visitInsn(L2I);
|
mv.visitInsn(L2I);
|
||||||
else if (dest.equals(TargetType.Float))
|
} else if (dest.equals(TargetType.Float))
|
||||||
mv.visitInsn(L2F);
|
mv.visitInsn(L2F);
|
||||||
else if (dest.equals(TargetType.Double))
|
else if (dest.equals(TargetType.Double))
|
||||||
mv.visitInsn(L2D);
|
mv.visitInsn(L2D);
|
||||||
@ -174,7 +195,7 @@ public class Codegen {
|
|||||||
|| dest.equals(TargetType.Char)
|
|| dest.equals(TargetType.Char)
|
||||||
|| dest.equals(TargetType.Short)) {
|
|| dest.equals(TargetType.Short)) {
|
||||||
mv.visitInsn(L2I);
|
mv.visitInsn(L2I);
|
||||||
source = TargetType.Integer;
|
convertTo(state, TargetType.Integer, dest);
|
||||||
}
|
}
|
||||||
} else if (source.equals(TargetType.Float)) {
|
} else if (source.equals(TargetType.Float)) {
|
||||||
if (dest.equals(TargetType.Integer))
|
if (dest.equals(TargetType.Integer))
|
||||||
@ -187,7 +208,7 @@ public class Codegen {
|
|||||||
|| dest.equals(TargetType.Char)
|
|| dest.equals(TargetType.Char)
|
||||||
|| dest.equals(TargetType.Short)) {
|
|| dest.equals(TargetType.Short)) {
|
||||||
mv.visitInsn(F2I);
|
mv.visitInsn(F2I);
|
||||||
source = TargetType.Integer;
|
convertTo(state, TargetType.Integer, dest);
|
||||||
}
|
}
|
||||||
} else if (source.equals(TargetType.Double)) {
|
} else if (source.equals(TargetType.Double)) {
|
||||||
if (dest.equals(TargetType.Integer))
|
if (dest.equals(TargetType.Integer))
|
||||||
@ -200,10 +221,9 @@ public class Codegen {
|
|||||||
|| dest.equals(TargetType.Char)
|
|| dest.equals(TargetType.Char)
|
||||||
|| dest.equals(TargetType.Short)) {
|
|| dest.equals(TargetType.Short)) {
|
||||||
mv.visitInsn(D2I);
|
mv.visitInsn(D2I);
|
||||||
source = TargetType.Integer;
|
convertTo(state, TargetType.Integer, dest);
|
||||||
}
|
}
|
||||||
}
|
} else if (source.equals(TargetType.Byte)
|
||||||
if (source.equals(TargetType.Byte)
|
|
||||||
|| source.equals(TargetType.Char)
|
|| source.equals(TargetType.Char)
|
||||||
|| source.equals(TargetType.Short)
|
|| source.equals(TargetType.Short)
|
||||||
|| source.equals(TargetType.Integer)) {
|
|| source.equals(TargetType.Integer)) {
|
||||||
@ -220,33 +240,62 @@ public class Codegen {
|
|||||||
else if (dest.equals(TargetType.Double))
|
else if (dest.equals(TargetType.Double))
|
||||||
mv.visitInsn(I2D);
|
mv.visitInsn(I2D);
|
||||||
} else {
|
} else {
|
||||||
|
boxPrimitive(state, source);
|
||||||
mv.visitTypeInsn(CHECKCAST, dest.getName());
|
mv.visitTypeInsn(CHECKCAST, dest.getName());
|
||||||
unboxPrimitive(state, dest);
|
unboxPrimitive(state, dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TargetType largerType(TargetType left, TargetType right) {
|
||||||
|
if (left.equals(TargetType.String) || right.equals(TargetType.String)) {
|
||||||
|
return TargetType.String;
|
||||||
|
} else if (left.equals(TargetType.Double) || right.equals(TargetType.Double)) {
|
||||||
|
return TargetType.Double;
|
||||||
|
} else if (left.equals(TargetType.Float) || right.equals(TargetType.Float)) {
|
||||||
|
return TargetType.Float;
|
||||||
|
} else if (left.equals(TargetType.Long) || right.equals(TargetType.Long)) {
|
||||||
|
return TargetType.Long;
|
||||||
|
} else {
|
||||||
|
return TargetType.Integer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void generateBinaryOp(State state, TargetBinaryOp op) {
|
private void generateBinaryOp(State state, TargetBinaryOp op) {
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Add add: {
|
case Add add: {
|
||||||
generate(state, add.left());
|
if (add.type().equals(TargetType.String)) {
|
||||||
convertTo(state, add.left().type(), op.type());
|
mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
|
||||||
generate(state, add.right());
|
mv.visitInsn(DUP);
|
||||||
convertTo(state, add.right().type(), op.type());
|
generate(state, add.left());
|
||||||
var type = add.type();
|
convertToString(state, add.left().type());
|
||||||
if (type.equals(TargetType.Byte)
|
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false);
|
||||||
|| type.equals(TargetType.Char)
|
|
||||||
|| type.equals(TargetType.Integer)
|
|
||||||
|| type.equals(TargetType.Short)) {
|
|
||||||
mv.visitInsn(IADD);
|
|
||||||
} else if (type.equals(TargetType.Long)) {
|
|
||||||
mv.visitInsn(LADD);
|
|
||||||
} else if (type.equals(TargetType.Float)) {
|
|
||||||
mv.visitInsn(FADD);
|
|
||||||
} else if (type.equals(TargetType.Double)) {
|
|
||||||
mv.visitInsn(DADD);
|
|
||||||
} else {
|
} else {
|
||||||
throw new CodeGenException("Invalid argument to Add expression");
|
generate(state, add.left());
|
||||||
|
convertTo(state, add.left().type(), add.type());
|
||||||
|
generate(state, add.right());
|
||||||
|
convertTo(state, add.right().type(), add.type());
|
||||||
|
var type = add.type();
|
||||||
|
if (type.equals(TargetType.Byte)
|
||||||
|
|| type.equals(TargetType.Char)
|
||||||
|
|| type.equals(TargetType.Integer)
|
||||||
|
|| type.equals(TargetType.Short)) {
|
||||||
|
mv.visitInsn(IADD);
|
||||||
|
} else if (type.equals(TargetType.Long)) {
|
||||||
|
mv.visitInsn(LADD);
|
||||||
|
} else if (type.equals(TargetType.Float)) {
|
||||||
|
mv.visitInsn(FADD);
|
||||||
|
} else if (type.equals(TargetType.Double)) {
|
||||||
|
mv.visitInsn(DADD);
|
||||||
|
} else {
|
||||||
|
throw new CodeGenException("Invalid argument to Add expression");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (add.type().equals(TargetType.String)) {
|
||||||
|
generate(state, add.right());
|
||||||
|
convertToString(state, add.right().type());
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -429,106 +478,231 @@ public class Codegen {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Greater greater: {
|
case Greater greater: {
|
||||||
var type = greater.exprType();
|
var type = largerType(greater.left().type(), greater.right().type());
|
||||||
if (type.equals(TargetType.Long)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, greater, LCMP, IFGT);
|
generateRelationalOperator(state, greater, type, LCMP, IFGT);
|
||||||
} else if (type.equals(TargetType.Float)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, greater, FCMPL, IFGT);
|
generateRelationalOperator(state, greater, type, FCMPL, IFGT);
|
||||||
} else if (type.equals(TargetType.Double)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, greater, DCMPL, IFGT);
|
generateRelationalOperator(state, greater, type, DCMPL, IFGT);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, greater, IF_ICMPGT);
|
generateRelationalOperator(state, greater, type, IF_ICMPGT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Less less: {
|
case Less less: {
|
||||||
var type = less.exprType();
|
var type = largerType(less.left().type(), less.right().type());
|
||||||
if (type.equals(TargetType.Long)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, less, LCMP, IFLT);
|
generateRelationalOperator(state, less, type, LCMP, IFLT);
|
||||||
} else if (type.equals(TargetType.Float)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, less, FCMPL, IFLT);
|
generateRelationalOperator(state, less, type, FCMPL, IFLT);
|
||||||
} else if (type.equals(TargetType.Double)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, less, DCMPL, IFLT);
|
generateRelationalOperator(state, less, type, DCMPL, IFLT);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, less, IF_ICMPLT);
|
generateRelationalOperator(state, less, type, IF_ICMPLT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GreaterOrEqual greaterOrEqual: {
|
case GreaterOrEqual greaterOrEqual: {
|
||||||
var type = greaterOrEqual.exprType();
|
var type = largerType(greaterOrEqual.left().type(), greaterOrEqual.right().type());
|
||||||
if (type.equals(TargetType.Long)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, greaterOrEqual, LCMP, IFGE);
|
generateRelationalOperator(state, greaterOrEqual, type, LCMP, IFGE);
|
||||||
} else if (type.equals(TargetType.Float)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, greaterOrEqual, FCMPL, IFGE);
|
generateRelationalOperator(state, greaterOrEqual, type, FCMPL, IFGE);
|
||||||
} else if (type.equals(TargetType.Double)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, greaterOrEqual, DCMPL, IFGE);
|
generateRelationalOperator(state, greaterOrEqual, type, DCMPL, IFGE);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, greaterOrEqual, IF_ICMPGE);
|
generateRelationalOperator(state, greaterOrEqual, type, IF_ICMPGE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LessOrEqual lessOrEqual: {
|
case LessOrEqual lessOrEqual: {
|
||||||
var type = lessOrEqual.exprType();
|
var type = largerType(lessOrEqual.left().type(), lessOrEqual.right().type());
|
||||||
if (type.equals(TargetType.Long)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, lessOrEqual, LCMP, IFLE);
|
generateRelationalOperator(state, lessOrEqual, type, LCMP, IFLE);
|
||||||
} else if (type.equals(TargetType.Float)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, lessOrEqual, FCMPL, IFLE);
|
generateRelationalOperator(state, lessOrEqual, type, FCMPL, IFLE);
|
||||||
} else if (type.equals(TargetType.Double)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, lessOrEqual, DCMPL, IFLE);
|
generateRelationalOperator(state, lessOrEqual, type, DCMPL, IFLE);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, lessOrEqual, IF_ICMPLE);
|
generateRelationalOperator(state, lessOrEqual, type, IF_ICMPLE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Equal equal: {
|
case Equal equal: {
|
||||||
var type = equal.exprType();
|
var type = largerType(equal.left().type(), equal.right().type());
|
||||||
if (type.equals(TargetType.Long)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, equal, LCMP, IFEQ);
|
generateRelationalOperator(state, equal, type, LCMP, IFEQ);
|
||||||
} else if (type.equals(TargetType.Float)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, equal, FCMPL, IFEQ);
|
generateRelationalOperator(state, equal, type, FCMPL, IFEQ);
|
||||||
} else if (type.equals(TargetType.Double)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, equal, DCMPL, IFEQ);
|
generateRelationalOperator(state, equal, type, DCMPL, IFEQ);
|
||||||
} else if (type.equals(TargetType.Char)
|
} else if (type.equals(TargetType.Char)
|
||||||
|| type.equals(TargetType.Short)
|
|| type.equals(TargetType.Short)
|
||||||
|| type.equals(TargetType.Byte)
|
|| type.equals(TargetType.Byte)
|
||||||
|| type.equals(TargetType.Integer)) {
|
|| type.equals(TargetType.Integer)
|
||||||
generateRelationalOperator(state, equal, IF_ICMPEQ);
|
|| type.equals(TargetType.Boolean)) {
|
||||||
|
generateRelationalOperator(state, equal, type, IF_ICMPEQ);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, equal, IF_ACMPEQ);
|
generateRelationalOperator(state, equal, type, IF_ACMPEQ);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NotEqual notEqual: {
|
case NotEqual notEqual: {
|
||||||
var type = notEqual.exprType();
|
var type = largerType(notEqual.left().type(), notEqual.right().type());
|
||||||
if (type.equals(TargetType.Long)) {
|
if (type.equals(TargetType.Long)) {
|
||||||
generateRelationalOperator(state, notEqual, LCMP, IFNE);
|
generateRelationalOperator(state, notEqual, type, LCMP, IFNE);
|
||||||
} else if (type.equals(TargetType.Float)) {
|
} else if (type.equals(TargetType.Float)) {
|
||||||
generateRelationalOperator(state, notEqual, FCMPL, IFNE);
|
generateRelationalOperator(state, notEqual, type, FCMPL, IFNE);
|
||||||
} else if (type.equals(TargetType.Double)) {
|
} else if (type.equals(TargetType.Double)) {
|
||||||
generateRelationalOperator(state, notEqual, DCMPL, IFNE);
|
generateRelationalOperator(state, notEqual, type, DCMPL, IFNE);
|
||||||
} else if (type.equals(TargetType.Char)
|
} else if (type.equals(TargetType.Char)
|
||||||
|| type.equals(TargetType.Short)
|
|| type.equals(TargetType.Short)
|
||||||
|| type.equals(TargetType.Byte)
|
|| type.equals(TargetType.Byte)
|
||||||
|| type.equals(TargetType.Integer)) {
|
|| type.equals(TargetType.Integer)) {
|
||||||
generateRelationalOperator(state, notEqual, IF_ICMPNE);
|
generateRelationalOperator(state, notEqual, type, IF_ICMPNE);
|
||||||
} else {
|
} else {
|
||||||
generateRelationalOperator(state, notEqual, IF_ACMPNE);
|
generateRelationalOperator(state, notEqual, type, IF_ACMPNE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void afterIncDec(State state, TargetUnaryOp op) {
|
||||||
|
var mv = state.mv;
|
||||||
|
if (op.expr() instanceof TargetLocalVar localVar) {
|
||||||
|
mv.visitVarInsn(ASTORE, state.scope.get(localVar.name()).index);
|
||||||
|
} else if (op.expr() instanceof TargetFieldVar fieldVar) {
|
||||||
|
generate(state, fieldVar.left());
|
||||||
|
mv.visitInsn(SWAP);
|
||||||
|
mv.visitFieldInsn(PUTFIELD, fieldVar.owner().getName(), fieldVar.right(), fieldVar.type().toSignature());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void generateUnaryOp(State state, TargetUnaryOp op) {
|
private void generateUnaryOp(State state, TargetUnaryOp op) {
|
||||||
// TODO
|
var mv = state.mv;
|
||||||
throw new NotImplementedException();
|
switch (op) {
|
||||||
|
case TargetUnaryOp.Add add:
|
||||||
|
// This literally does nothing
|
||||||
|
generate(state, add.expr());
|
||||||
|
break;
|
||||||
|
case TargetUnaryOp.Negate negate:
|
||||||
|
generate(state, negate.expr());
|
||||||
|
if (negate.type().equals(TargetType.Double))
|
||||||
|
mv.visitInsn(DNEG);
|
||||||
|
else if (negate.type().equals(TargetType.Float))
|
||||||
|
mv.visitInsn(FNEG);
|
||||||
|
else if (negate.type().equals(TargetType.Long))
|
||||||
|
mv.visitInsn(LNEG);
|
||||||
|
else mv.visitInsn(INEG);
|
||||||
|
break;
|
||||||
|
case TargetUnaryOp.Not not:
|
||||||
|
generate(state, not.expr());
|
||||||
|
if (not.type().equals(TargetType.Long)) {
|
||||||
|
mv.visitLdcInsn(-1L);
|
||||||
|
mv.visitInsn(LXOR);
|
||||||
|
} else {
|
||||||
|
mv.visitInsn(ICONST_M1);
|
||||||
|
mv.visitInsn(IXOR);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TargetUnaryOp.PreIncrement preIncrement:
|
||||||
|
generate(state, preIncrement.expr());
|
||||||
|
if (preIncrement.type().equals(TargetType.Float)) {
|
||||||
|
mv.visitLdcInsn(1F);
|
||||||
|
mv.visitInsn(FADD);
|
||||||
|
mv.visitInsn(DUP);
|
||||||
|
} else if (preIncrement.type().equals(TargetType.Double)) {
|
||||||
|
mv.visitLdcInsn(1D);
|
||||||
|
mv.visitInsn(DADD);
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
|
} else if (preIncrement.type().equals(TargetType.Long)) {
|
||||||
|
mv.visitLdcInsn(1L);
|
||||||
|
mv.visitInsn(LADD);
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
|
} else {
|
||||||
|
mv.visitLdcInsn(1);
|
||||||
|
mv.visitInsn(IADD);
|
||||||
|
mv.visitInsn(DUP);
|
||||||
|
}
|
||||||
|
boxPrimitive(state, preIncrement.type());
|
||||||
|
afterIncDec(state, preIncrement);
|
||||||
|
break;
|
||||||
|
case TargetUnaryOp.PreDecrement preDecrement:
|
||||||
|
generate(state, preDecrement.expr());
|
||||||
|
if (preDecrement.type().equals(TargetType.Float)) {
|
||||||
|
mv.visitLdcInsn(1F);
|
||||||
|
mv.visitInsn(FSUB);
|
||||||
|
mv.visitInsn(DUP);
|
||||||
|
} else if (preDecrement.type().equals(TargetType.Double)) {
|
||||||
|
mv.visitLdcInsn(1D);
|
||||||
|
mv.visitInsn(DSUB);
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
|
} else if (preDecrement.type().equals(TargetType.Long)) {
|
||||||
|
mv.visitLdcInsn(1L);
|
||||||
|
mv.visitInsn(LSUB);
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
|
} else {
|
||||||
|
mv.visitLdcInsn(1);
|
||||||
|
mv.visitInsn(ISUB);
|
||||||
|
mv.visitInsn(DUP);
|
||||||
|
}
|
||||||
|
boxPrimitive(state, preDecrement.type());
|
||||||
|
afterIncDec(state, preDecrement);
|
||||||
|
break;
|
||||||
|
case TargetUnaryOp.PostIncrement postIncrement:
|
||||||
|
generate(state, postIncrement.expr());
|
||||||
|
if (postIncrement.type().equals(TargetType.Float)) {
|
||||||
|
mv.visitInsn(DUP);
|
||||||
|
mv.visitLdcInsn(1F);
|
||||||
|
mv.visitInsn(FADD);
|
||||||
|
} else if (postIncrement.type().equals(TargetType.Double)) {
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
|
mv.visitLdcInsn(1D);
|
||||||
|
mv.visitInsn(DADD);
|
||||||
|
} else if (postIncrement.type().equals(TargetType.Long)) {
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
|
mv.visitLdcInsn(1L);
|
||||||
|
mv.visitInsn(LADD);
|
||||||
|
} else {
|
||||||
|
mv.visitInsn(DUP);
|
||||||
|
mv.visitLdcInsn(1);
|
||||||
|
mv.visitInsn(IADD);
|
||||||
|
}
|
||||||
|
boxPrimitive(state, postIncrement.type());
|
||||||
|
afterIncDec(state, postIncrement);
|
||||||
|
break;
|
||||||
|
case TargetUnaryOp.PostDecrement postDecrement:
|
||||||
|
generate(state, postDecrement.expr());
|
||||||
|
if (postDecrement.type().equals(TargetType.Float)) {
|
||||||
|
mv.visitInsn(DUP);
|
||||||
|
mv.visitLdcInsn(1F);
|
||||||
|
mv.visitInsn(FSUB);
|
||||||
|
} else if (postDecrement.type().equals(TargetType.Double)) {
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
|
mv.visitLdcInsn(1D);
|
||||||
|
mv.visitInsn(DSUB);
|
||||||
|
} else if (postDecrement.type().equals(TargetType.Long)) {
|
||||||
|
mv.visitInsn(DUP2);
|
||||||
|
mv.visitLdcInsn(1L);
|
||||||
|
mv.visitInsn(LSUB);
|
||||||
|
} else {
|
||||||
|
mv.visitInsn(DUP);
|
||||||
|
mv.visitLdcInsn(1);
|
||||||
|
mv.visitInsn(ISUB);
|
||||||
|
}
|
||||||
|
boxPrimitive(state, postDecrement.type());
|
||||||
|
afterIncDec(state, postDecrement);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateLambdaExpression(State state, TargetLambdaExpression lambda) {
|
private void generateLambdaExpression(State state, TargetLambdaExpression lambda) {
|
||||||
var mv = state.mv;
|
var mv = state.mv;
|
||||||
var name = "lambda$" + state.lambdaCounter;
|
var name = "lambda$" + state.lambdaCounter;
|
||||||
var impl = new TargetMethod(
|
var impl = new TargetMethod(
|
||||||
ACC_PRIVATE, name, Set.of(),
|
0, name, Set.of(),
|
||||||
lambda.params(), lambda.returnType(), lambda.block()
|
lambda.params(), lambda.returnType(), lambda.block()
|
||||||
);
|
);
|
||||||
generateMethod(impl);
|
generateMethod(impl);
|
||||||
@ -665,6 +839,7 @@ public class Codegen {
|
|||||||
if (!dot.isStatic())
|
if (!dot.isStatic())
|
||||||
generate(state, dot.left());
|
generate(state, dot.left());
|
||||||
mv.visitFieldInsn(dot.isStatic() ? GETSTATIC : GETFIELD, dot.left().type().getName(), dot.right(), dot.type().toSignature());
|
mv.visitFieldInsn(dot.isStatic() ? GETSTATIC : GETFIELD, dot.left().type().getName(), dot.right(), dot.type().toSignature());
|
||||||
|
unboxPrimitive(state, dot.type());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TargetFor _for: {
|
case TargetFor _for: {
|
||||||
@ -738,8 +913,17 @@ public class Codegen {
|
|||||||
generate(state, e);
|
generate(state, e);
|
||||||
boxPrimitive(state, e.type());
|
boxPrimitive(state, e.type());
|
||||||
}
|
}
|
||||||
mv.visitMethodInsn(call.isInterface() ? INVOKEINTERFACE : call.isStatic() ? INVOKESTATIC: call.name() == "<init>" ? INVOKESPECIAL : INVOKEVIRTUAL,
|
var descriptor = call.getDescriptor();
|
||||||
call.owner().getName(), call.name(), call.getDescriptor(), call.isInterface());
|
if (call.owner() instanceof TargetFunNType) // Decay FunN
|
||||||
|
descriptor = TargetMethod.getDescriptor(
|
||||||
|
call.type() == null ? null : TargetType.Object,
|
||||||
|
call.parameterTypes().stream().map(x -> TargetType.Object).toArray(TargetType[]::new)
|
||||||
|
);
|
||||||
|
|
||||||
|
mv.visitMethodInsn(call.isInterface() ? INVOKEINTERFACE : call.isStatic() ? INVOKESTATIC: call.name().equals("<init>") ? INVOKESPECIAL : INVOKEVIRTUAL,
|
||||||
|
call.owner().getName(), call.name(), descriptor, call.isInterface());
|
||||||
|
if (call.owner() instanceof TargetFunNType)
|
||||||
|
mv.visitTypeInsn(CHECKCAST, call.type().getName());
|
||||||
if (call.type() != null)
|
if (call.type() != null)
|
||||||
unboxPrimitive(state, call.type());
|
unboxPrimitive(state, call.type());
|
||||||
break;
|
break;
|
||||||
@ -763,11 +947,11 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateField(TargetField field) {
|
private void generateField(TargetField field) {
|
||||||
cw.visitField(field.access(), field.name(), field.type().toSignature(), field.type().toGenericSignature(), null);
|
cw.visitField(field.access() | ACC_PUBLIC, field.name(), field.type().toSignature(), field.type().toGenericSignature(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateConstructor(TargetConstructor constructor) {
|
private void generateConstructor(TargetConstructor constructor) {
|
||||||
MethodVisitor mv = cw.visitMethod(constructor.access(), "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
|
MethodVisitor mv = cw.visitMethod(constructor.access() | ACC_PUBLIC, "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
var state = new State(mv, 1);
|
var state = new State(mv, 1);
|
||||||
for (var param: constructor.parameters())
|
for (var param: constructor.parameters())
|
||||||
@ -779,7 +963,8 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateMethod(TargetMethod method) {
|
private void generateMethod(TargetMethod method) {
|
||||||
MethodVisitor mv = cw.visitMethod(method.access(), method.name(), method.getDescriptor(), method.getSignature(), null);
|
// TODO The older codegen has set ACC_PUBLIC for all methods, good for testing but bad for everything else
|
||||||
|
MethodVisitor mv = cw.visitMethod(method.access() | ACC_PUBLIC, method.name(), method.getDescriptor(), method.getSignature(), null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
var state = new State(mv, method.isStatic() ? 0 : 1);
|
var state = new State(mv, method.isStatic() ? 0 : 1);
|
||||||
for (var param: method.parameters())
|
for (var param: method.parameters())
|
||||||
@ -803,7 +988,7 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public byte[] generate() {
|
public byte[] generate() {
|
||||||
cw.visit(V1_8, clazz.modifiers(), clazz.qualifiedName(),
|
cw.visit(V1_8, clazz.modifiers() | ACC_PUBLIC, clazz.qualifiedName(),
|
||||||
generateSignature(clazz), clazz.superType() != null ? clazz.superType().getName(): "java/lang/Object",
|
generateSignature(clazz), clazz.superType() != null ? clazz.superType().getName(): "java/lang/Object",
|
||||||
clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new)
|
clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new)
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.dhbwstuttgart.target.generate;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.funN.FunNGenerator;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||||
@ -25,6 +26,7 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
private class Sigma {
|
private class Sigma {
|
||||||
Map<Method, Set<ResultPair<?, ?>>> computedGenericsOfMethods = new HashMap<>();
|
Map<Method, Set<ResultPair<?, ?>>> computedGenericsOfMethods = new HashMap<>();
|
||||||
|
Map<Method, Set<TypePlaceholder>> usedTPHsOfMethods = new HashMap<>();
|
||||||
Map<ClassOrInterface, Set<ResultPair<?, ?>>> computedGenericsOfClasses = new HashMap<>();
|
Map<ClassOrInterface, Set<ResultPair<?, ?>>> computedGenericsOfClasses = new HashMap<>();
|
||||||
|
|
||||||
Set<PairTPHsmallerTPH> simplifiedConstraints = new HashSet<>();
|
Set<PairTPHsmallerTPH> simplifiedConstraints = new HashSet<>();
|
||||||
@ -142,14 +144,16 @@ public class ASTToTargetAST {
|
|||||||
if (expressionReceiver.expr instanceof This) {
|
if (expressionReceiver.expr instanceof This) {
|
||||||
// TODO This is going to fail spectacularly for overloaded methods
|
// TODO This is going to fail spectacularly for overloaded methods
|
||||||
var optMethod = owner.getMethods().stream().filter(m -> m.name.equals(methodCall.name)).findFirst();
|
var optMethod = owner.getMethods().stream().filter(m -> m.name.equals(methodCall.name)).findFirst();
|
||||||
assert optMethod.isPresent();
|
if (optMethod.isEmpty()) return;
|
||||||
var method = optMethod.get();
|
var method = optMethod.get();
|
||||||
var generics = generics(owner, method);
|
var generics = generics(owner, method);
|
||||||
Set<ResultPair<?, ?>> all = new HashSet<>(generics);
|
Set<ResultPair<?, ?>> all = new HashSet<>(generics);
|
||||||
|
|
||||||
// Reflexive and Transitive closure
|
// Reflexive and Transitive closure
|
||||||
HashSet<ResultPair<?, ?>> toAdd = new HashSet<>();
|
HashSet<ResultPair<?, ?>> toAdd = new HashSet<>();
|
||||||
|
int sizeBefore;
|
||||||
do {
|
do {
|
||||||
|
sizeBefore = all.size();
|
||||||
toAdd.clear();
|
toAdd.clear();
|
||||||
for (var g1 : all) {
|
for (var g1 : all) {
|
||||||
for (var g2 : all) {
|
for (var g2 : all) {
|
||||||
@ -160,7 +164,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
all.addAll(toAdd);
|
all.addAll(toAdd);
|
||||||
} while (toAdd.size() > 0);
|
} while (sizeBefore < all.size());
|
||||||
for (var generic : all) {
|
for (var generic : all) {
|
||||||
toAdd.add(new PairTPHsmallerTPH((TypePlaceholder) generic.getLeft(), (TypePlaceholder) generic.getLeft()));
|
toAdd.add(new PairTPHsmallerTPH((TypePlaceholder) generic.getLeft(), (TypePlaceholder) generic.getLeft()));
|
||||||
}
|
}
|
||||||
@ -231,6 +235,11 @@ public class ASTToTargetAST {
|
|||||||
eliminateCyclesAndInfima(result);
|
eliminateCyclesAndInfima(result);
|
||||||
System.out.println(method.name + ": " + result);
|
System.out.println(method.name + ": " + result);
|
||||||
|
|
||||||
|
Set<TypePlaceholder> allUsedTPHs = new HashSet<>();
|
||||||
|
allUsedTPHs.addAll(typeVariables);
|
||||||
|
allUsedTPHs.addAll(typeVariablesOfFields);
|
||||||
|
usedTPHsOfMethods.put(method, allUsedTPHs);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,8 +257,11 @@ public class ASTToTargetAST {
|
|||||||
var left = equality.getOrDefault(rsp.left, rsp.left);
|
var left = equality.getOrDefault(rsp.left, rsp.left);
|
||||||
var right = equality.getOrDefault(rsp.right, rsp.right);
|
var right = equality.getOrDefault(rsp.right, rsp.right);
|
||||||
if (left.equals(tph)) {
|
if (left.equals(tph)) {
|
||||||
generics.add(new PairTPHsmallerTPH(tph, right));
|
var pair = new PairTPHsmallerTPH(tph, right);
|
||||||
findAllBounds(right, generics);
|
if (!generics.contains(pair)) {
|
||||||
|
generics.add(pair);
|
||||||
|
findAllBounds(right, generics);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,6 +324,10 @@ public class ASTToTargetAST {
|
|||||||
for (var field : classOrInterface.getFieldDecl()) {
|
for (var field : classOrInterface.getFieldDecl()) {
|
||||||
findTphs(field.getType(), referenced);
|
findTphs(field.getType(), referenced);
|
||||||
}
|
}
|
||||||
|
for (var method : classOrInterface.getMethods()) {
|
||||||
|
generics(classOrInterface, method);
|
||||||
|
referenced.addAll(usedTPHsOfMethods.get(method));
|
||||||
|
}
|
||||||
|
|
||||||
var oldInput = new HashSet<>(input);
|
var oldInput = new HashSet<>(input);
|
||||||
for (var pair : oldInput) {
|
for (var pair : oldInput) {
|
||||||
@ -320,7 +336,10 @@ public class ASTToTargetAST {
|
|||||||
for (var pair2 : oldInput) {
|
for (var pair2 : oldInput) {
|
||||||
if (pair2.getRight().equals(pair.getLeft())) {
|
if (pair2.getRight().equals(pair.getLeft())) {
|
||||||
input.remove(pair2);
|
input.remove(pair2);
|
||||||
input.add(new PairTPHsmallerTPH((TypePlaceholder) pair2.getLeft(), (TypePlaceholder) pair.getRight()));
|
if (pair instanceof PairTPHsmallerTPH)
|
||||||
|
input.add(new PairTPHsmallerTPH((TypePlaceholder) pair2.getLeft(), (TypePlaceholder) pair.getRight()));
|
||||||
|
else
|
||||||
|
input.add(new PairTPHequalRefTypeOrWildcardType((TypePlaceholder) pair2.getLeft(), pair.getRight()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,7 +380,7 @@ public class ASTToTargetAST {
|
|||||||
input.removeAll(infima);
|
input.removeAll(infima);
|
||||||
for (var infimum : infima) {
|
for (var infimum : infima) {
|
||||||
equality.put(infimum.right, newTph);
|
equality.put(infimum.right, newTph);
|
||||||
new HashSet<>(input).stream().forEach(pair -> {
|
new HashSet<>(input).forEach(pair -> {
|
||||||
if (pair.getLeft().equals(infimum.right)) {
|
if (pair.getLeft().equals(infimum.right)) {
|
||||||
input.remove(pair);
|
input.remove(pair);
|
||||||
if (pair instanceof PairTPHsmallerTPH stph) {
|
if (pair instanceof PairTPHsmallerTPH stph) {
|
||||||
@ -417,6 +436,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tiernan simple cycles algorithm
|
// Tiernan simple cycles algorithm
|
||||||
|
// Adapted from https://github.com/jgrapht/jgrapht/blob/master/jgrapht-core/src/main/java/org/jgrapht/alg/cycle/TiernanSimpleCycles.java
|
||||||
static Set<List<TypePlaceholder>> findCycles(Set<ResultPair<?, ?>> input) {
|
static Set<List<TypePlaceholder>> findCycles(Set<ResultPair<?, ?>> input) {
|
||||||
Map<TypePlaceholder, Integer> indices = new HashMap<>();
|
Map<TypePlaceholder, Integer> indices = new HashMap<>();
|
||||||
List<TypePlaceholder> path = new ArrayList<>();
|
List<TypePlaceholder> path = new ArrayList<>();
|
||||||
@ -576,6 +596,12 @@ public class ASTToTargetAST {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<Integer> usedFunN = new HashSet<>();
|
||||||
|
|
||||||
|
public List<byte[]> generateUsedFunNTypes() {
|
||||||
|
return usedFunN.stream().map(n -> FunNGenerator.getInstance().generateSuperBytecode(n)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input) {
|
protected TargetType convert(RefTypeOrTPHOrWildcardOrGeneric input) {
|
||||||
return input.acceptTV(new TypeVisitor<>() {
|
return input.acceptTV(new TypeVisitor<>() {
|
||||||
@Override
|
@Override
|
||||||
@ -584,8 +610,10 @@ public class ASTToTargetAST {
|
|||||||
if (name.equals("void")) return null;
|
if (name.equals("void")) return null;
|
||||||
|
|
||||||
var params = refType.getParaList().stream().map(ASTToTargetAST.this::convert).toList();
|
var params = refType.getParaList().stream().map(ASTToTargetAST.this::convert).toList();
|
||||||
if (name.matches("Fun\\d\\$\\$")) // TODO This seems like a bad idea
|
if (name.matches("Fun\\d\\$\\$")) { // TODO This seems like a bad idea
|
||||||
return new TargetFunNType(params.size(), params);
|
usedFunN.add(params.size() - 1);
|
||||||
|
return new TargetFunNType(params.size() - 1, params);
|
||||||
|
}
|
||||||
return new TargetRefType(name, params);
|
return new TargetRefType(name, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import de.dhbwstuttgart.target.tree.MethodParameter;
|
|||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetFunNType;
|
import de.dhbwstuttgart.target.tree.type.TargetFunNType;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||||
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
@ -127,20 +128,24 @@ public class StatementToTargetExpression implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
|
var receiverType = converter.convert(methodCall.receiver.getType());
|
||||||
|
var isFunNType = receiverType instanceof TargetFunNType;
|
||||||
|
var returnType = converter.convert(methodCall.getType());
|
||||||
|
|
||||||
result = new TargetMethodCall(
|
result = new TargetMethodCall(
|
||||||
converter.convert(methodCall.getType()),
|
returnType,
|
||||||
methodCall.argTypes == null ? List.of() : methodCall.argTypes.stream().map(converter::convert).toList(),
|
methodCall.arglist.getArguments().stream().map(expr -> converter.convert(expr.getType())).toList(),
|
||||||
converter.convert(methodCall.receiver),
|
converter.convert(methodCall.receiver),
|
||||||
methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(),
|
methodCall.getArgumentList().getArguments().stream().map(converter::convert).toList(),
|
||||||
converter.convert(methodCall.receiver.getType()),
|
receiverType,
|
||||||
methodCall.name, false, false
|
methodCall.name, false, isFunNType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewClass newClass) {
|
public void visit(NewClass newClass) {
|
||||||
result = new TargetNew(
|
result = new TargetNew(
|
||||||
converter.convert(newClass.receiverType),
|
new TargetRefType(newClass.name),
|
||||||
newClass.getArgumentList().getArguments().stream().map(converter::convert).toList()
|
newClass.getArgumentList().getArguments().stream().map(converter::convert).toList()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@ public sealed interface TargetUnaryOp extends TargetExpression {
|
|||||||
record Add(TargetType type, TargetExpression expr) implements TargetUnaryOp {}
|
record Add(TargetType type, TargetExpression expr) implements TargetUnaryOp {}
|
||||||
record Not(TargetType type, TargetExpression expr) implements TargetUnaryOp {}
|
record Not(TargetType type, TargetExpression expr) implements TargetUnaryOp {}
|
||||||
|
|
||||||
record PreIncrement(TargetType type, TargetExpression expr) implements TargetStatementExpression {}
|
record PreIncrement(TargetType type, TargetExpression expr) implements TargetStatementExpression, TargetUnaryOp {}
|
||||||
record PostIncrement(TargetType type, TargetExpression expr) implements TargetStatementExpression {}
|
record PostIncrement(TargetType type, TargetExpression expr) implements TargetStatementExpression, TargetUnaryOp {}
|
||||||
record PreDecrement(TargetType type, TargetExpression expr) implements TargetStatementExpression {}
|
record PreDecrement(TargetType type, TargetExpression expr) implements TargetStatementExpression, TargetUnaryOp {}
|
||||||
record PostDecrement(TargetType type, TargetExpression expr) implements TargetStatementExpression {}
|
record PostDecrement(TargetType type, TargetExpression expr) implements TargetStatementExpression, TargetUnaryOp {}
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,12 @@ package de.dhbwstuttgart.target.tree.type;
|
|||||||
public record TargetExtendsWildcard(TargetType innerType) implements TargetType {
|
public record TargetExtendsWildcard(TargetType innerType) implements TargetType {
|
||||||
@Override
|
@Override
|
||||||
public String toSignature() {
|
public String toSignature() {
|
||||||
return null;
|
return innerType.toSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toGenericSignature() {
|
public String toGenericSignature() {
|
||||||
return null;
|
return innerType.toGenericSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -3,6 +3,7 @@ package de.dhbwstuttgart.target.tree.type;
|
|||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public record TargetRefType(String name, List<TargetType> params) implements TargetSpecializedType {
|
public record TargetRefType(String name, List<TargetType> params) implements TargetSpecializedType {
|
||||||
public TargetRefType(String name) {
|
public TargetRefType(String name) {
|
||||||
@ -17,4 +18,18 @@ public record TargetRefType(String name, List<TargetType> params) implements Tar
|
|||||||
public String toSignature() {
|
public String toSignature() {
|
||||||
return "L" + getName() + ";";
|
return "L" + getName() + ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Type erasure means we need to override hashCode and equals to only consider the name
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (other instanceof TargetRefType refType) {
|
||||||
|
return refType.name.equals(name);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,12 @@ package de.dhbwstuttgart.target.tree.type;
|
|||||||
public record TargetSuperWildcard(TargetType innerType) implements TargetType {
|
public record TargetSuperWildcard(TargetType innerType) implements TargetType {
|
||||||
@Override
|
@Override
|
||||||
public String toSignature() {
|
public String toSignature() {
|
||||||
return null;
|
return innerType.toSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toGenericSignature() {
|
public String toGenericSignature() {
|
||||||
return null;
|
return innerType.toGenericSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -38,8 +38,9 @@ public class ASTToTypedTargetAST {
|
|||||||
var converter = new ASTToTargetAST(resultSet);
|
var converter = new ASTToTargetAST(resultSet);
|
||||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||||
|
|
||||||
var overloading = TestCodegen.generateClass(converter.convert(classes.get(0)));
|
var classLoader = new ByteArrayClassLoader();
|
||||||
var overloading2 = TestCodegen.generateClass(converter.convert(classes.get(1)));
|
var overloading = TestCodegen.generateClass(converter.convert(classes.get(0)), classLoader);
|
||||||
|
var overloading2 = TestCodegen.generateClass(converter.convert(classes.get(1)), classLoader);
|
||||||
|
|
||||||
var test1 = overloading.getDeclaredMethod("test", overloading);
|
var test1 = overloading.getDeclaredMethod("test", overloading);
|
||||||
test1.setAccessible(true);
|
test1.setAccessible(true);
|
||||||
@ -59,7 +60,7 @@ public class ASTToTypedTargetAST {
|
|||||||
var converter = new ASTToTargetAST(resultSet);
|
var converter = new ASTToTargetAST(resultSet);
|
||||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||||
|
|
||||||
var tphAndGenerics = TestCodegen.generateClass(converter.convert(classes.get(0)));
|
var tphAndGenerics = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -70,7 +71,7 @@ public class ASTToTypedTargetAST {
|
|||||||
var converter = new ASTToTargetAST(resultSet);
|
var converter = new ASTToTargetAST(resultSet);
|
||||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||||
|
|
||||||
var cycle = TestCodegen.generateClass(converter.convert(classes.get(0)));
|
var cycle = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -81,6 +82,6 @@ public class ASTToTypedTargetAST {
|
|||||||
var converter = new ASTToTargetAST(resultSet);
|
var converter = new ASTToTargetAST(resultSet);
|
||||||
var classes = compiler.sourceFiles.get(file).getClasses();
|
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||||
|
|
||||||
var infimum = TestCodegen.generateClass(converter.convert(classes.get(0)));
|
var infimum = TestCodegen.generateClass(converter.convert(classes.get(0)), new ByteArrayClassLoader());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
134
src/test/java/targetast/GreaterEqualTest.java
Normal file
134
src/test/java/targetast/GreaterEqualTest.java
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class GreaterEqualTest {
|
||||||
|
static Class<?> classToTest;
|
||||||
|
static Object instance;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws Exception {
|
||||||
|
var classFiles = TestCodegen.generateClassFiles("GreaterEqual.jav", new ByteArrayClassLoader());
|
||||||
|
classToTest = classFiles.get("GreaterEqual");
|
||||||
|
instance = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntegers() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Integer.class, Integer.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 7, 5);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntegers2() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Integer.class, Integer.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 5, 7);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqIntegers() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Integer.class, Integer.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 5, 5);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLongs() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Long.class, Long.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 10L, 7L);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFloats() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Float.class, Float.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 5F, 7F);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubles() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Double.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 5.0, 7.0);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLongInt() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Long.class, Integer.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 15L, 7);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFloatInt() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Float.class, Integer.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 5F, 7);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleInt() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Integer.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 25.0, 17);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFloatLong() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Float.class, Long.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 75F, 70L);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleLong() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Long.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 5.0, 7L);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqDoubleFloat() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Float.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 7.0, 7F);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleFloat() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Float.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 15.0, 7F);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleFloat3() throws Exception {
|
||||||
|
Method gE = classToTest.getDeclaredMethod("gE", Double.class, Float.class);
|
||||||
|
gE.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gE.invoke(instance, 9.0, 17F);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
}
|
132
src/test/java/targetast/GreaterThanTest.java
Normal file
132
src/test/java/targetast/GreaterThanTest.java
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class GreaterThanTest {
|
||||||
|
static Class<?> classToTest;
|
||||||
|
static Object instance;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws Exception {
|
||||||
|
var classFiles = TestCodegen.generateClassFiles("GreaterThan.jav", new ByteArrayClassLoader());
|
||||||
|
classToTest = classFiles.get("GreaterThan");
|
||||||
|
instance = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntegers() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Integer.class, Integer.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 7, 5);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntegers2() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Integer.class, Integer.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 5, 7);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqIntegers() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Integer.class, Integer.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 5, 5);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLongs() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Long.class, Long.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 10L,7L);
|
||||||
|
assertTrue(result);
|
||||||
|
}@Test
|
||||||
|
|
||||||
|
public void testFloats() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Float.class, Float.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 5F,7F);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubles() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Double.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 5.0,7.0);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLongInt() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Long.class, Integer.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 15L,7);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFloatInt() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Float.class, Integer.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 5F,7);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleInt() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Integer.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 25.0,17);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFloatLong() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Float.class, Long.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 75F,70L);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleLong() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Long.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 5.0,7L);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqDoubleFloat() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Float.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 7.0,7F);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleFloat() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Float.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 15.0,7F);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleFloat3() throws Exception {
|
||||||
|
Method gT = classToTest.getDeclaredMethod("gT", Double.class, Float.class);
|
||||||
|
gT.setAccessible(true);
|
||||||
|
Boolean result = (Boolean) gT.invoke(instance, 9.0,17F);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
}
|
102
src/test/java/targetast/InheritTest.java
Normal file
102
src/test/java/targetast/InheritTest.java
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class InheritTest {
|
||||||
|
private static Class<?> classToTest, classToTestAA, classToTestBB, classToTestCC, classToTestDD;
|
||||||
|
private static Object instanceOfClass, instanceOfClassAA, instanceOfClassBB, instanceOfClassCC, instanceOfClassDD;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
var classLoader = new ByteArrayClassLoader();
|
||||||
|
classToTest = TestCodegen.generateClassFiles("Inherit.jav", classLoader).get("Inherit");
|
||||||
|
classToTestAA = TestCodegen.generateClassFiles("AA.jav", classLoader).get("AA");
|
||||||
|
classToTestBB = TestCodegen.generateClassFiles("BB.jav", classLoader).get("BB");
|
||||||
|
classToTestCC = TestCodegen.generateClassFiles("CC.jav", classLoader).get("CC");
|
||||||
|
classToTestDD = TestCodegen.generateClassFiles("DD.jav", classLoader).get("DD");
|
||||||
|
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
instanceOfClassAA = classToTestAA.getDeclaredConstructor().newInstance();
|
||||||
|
instanceOfClassBB = classToTestBB.getDeclaredConstructor().newInstance();
|
||||||
|
instanceOfClassCC = classToTestCC.getDeclaredConstructor().newInstance();
|
||||||
|
instanceOfClassDD = classToTestDD.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainAA() throws Exception {
|
||||||
|
Method m = classToTestAA.getDeclaredMethod("m", Integer.class);
|
||||||
|
assertEquals(m.invoke(instanceOfClassAA, 5), "AA");
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", classToTestAA, Integer.class);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, instanceOfClassAA, 5), "AA");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainBB() throws Exception {
|
||||||
|
Method m = classToTestAA.getDeclaredMethod("m", Integer.class);
|
||||||
|
assertEquals(m.invoke(instanceOfClassBB, 5), "AA");
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", classToTestAA, Integer.class);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, instanceOfClassBB, 5), "AA");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainCC() throws Exception {
|
||||||
|
Method m = classToTestCC.getDeclaredMethod("m", Integer.class);
|
||||||
|
assertEquals(m.invoke(instanceOfClassCC, 5), "CC");
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", classToTestCC, Integer.class);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, instanceOfClassCC, 5), "CC");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainDD() throws Exception {
|
||||||
|
Method m = classToTestCC.getDeclaredMethod("m", Integer.class);
|
||||||
|
assertEquals(m.invoke(instanceOfClassDD, 5), "CC");
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", classToTestCC, Integer.class);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, instanceOfClassDD, 5), "CC");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainVectorAA() throws Exception {
|
||||||
|
Method m = classToTestAA.getDeclaredMethod("m", Integer.class);
|
||||||
|
assertEquals(m.invoke(instanceOfClassAA, 5), "AA");
|
||||||
|
Vector v = new Vector<>();
|
||||||
|
v.add(instanceOfClassAA);
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", Vector.class, Integer.class);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, v, 5), "AA");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainVectorBB() throws Exception {
|
||||||
|
Method m = classToTestAA.getDeclaredMethod("m", Integer.class);
|
||||||
|
assertEquals(m.invoke(instanceOfClassBB, 5), "AA");
|
||||||
|
Vector v = new Vector<>();
|
||||||
|
v.add(instanceOfClassBB);
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", Vector.class, Integer.class);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, v, 5), "AA");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainVectorCC() throws Exception {
|
||||||
|
Method m = classToTestCC.getDeclaredMethod("m", Integer.class);
|
||||||
|
assertEquals(m.invoke(instanceOfClassCC, 5), "CC");
|
||||||
|
Vector v = new Vector<>();
|
||||||
|
v.add(instanceOfClassCC);
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", Vector.class, Integer.class);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, v, 5), "CC");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainVectorDD() throws Exception {
|
||||||
|
Method m = classToTestCC.getDeclaredMethod("m", Integer.class);
|
||||||
|
assertEquals(m.invoke(instanceOfClassDD, 5), "CC");
|
||||||
|
Vector v = new Vector<>();
|
||||||
|
v.add(instanceOfClassDD);
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", Vector.class, Integer.class);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, v, 5), "CC");
|
||||||
|
}
|
||||||
|
}
|
118
src/test/java/targetast/InheritTest2.java
Normal file
118
src/test/java/targetast/InheritTest2.java
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class InheritTest2 {
|
||||||
|
private static Class<?> classToTest, classToTestAA, classToTestBB, classToTestCC, classToTestDD;
|
||||||
|
private static Object instanceOfClass, instanceOfClassAA, instanceOfClassBB, instanceOfClassCC, instanceOfClassDD;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
var classLoader = new ByteArrayClassLoader();
|
||||||
|
classToTest = TestCodegen.generateClassFiles("Inherit.jav", classLoader).get("Inherit2");
|
||||||
|
classToTestAA = TestCodegen.generateClassFiles("AA.jav", classLoader).get("AA");
|
||||||
|
classToTestBB = TestCodegen.generateClassFiles("BB.jav", classLoader).get("BB");
|
||||||
|
classToTestCC = TestCodegen.generateClassFiles("CC.jav", classLoader).get("CC");
|
||||||
|
classToTestDD = TestCodegen.generateClassFiles("DD.jav", classLoader).get("DD");
|
||||||
|
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
instanceOfClassAA = classToTestAA.getDeclaredConstructor().newInstance();
|
||||||
|
instanceOfClassBB = classToTestBB.getDeclaredConstructor().newInstance();
|
||||||
|
instanceOfClassCC = classToTestCC.getDeclaredConstructor().newInstance();
|
||||||
|
instanceOfClassDD = classToTestDD.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainAA() throws Exception {
|
||||||
|
Method m2 = classToTestAA.getDeclaredMethod("m2", classToTestAA);
|
||||||
|
assertEquals(m2.invoke(instanceOfClassAA, instanceOfClassAA), "AA");
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", classToTestAA);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, instanceOfClassAA), "AA");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainBB() throws Exception {
|
||||||
|
Method m2 = classToTestAA.getDeclaredMethod("m2", classToTestAA);
|
||||||
|
assertEquals(m2.invoke(instanceOfClassAA, instanceOfClassAA), "AA");
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", classToTestAA);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, instanceOfClassBB), "AA");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainCC() throws Exception {
|
||||||
|
Method m2 = classToTestCC.getDeclaredMethod("m2", classToTestCC);
|
||||||
|
assertEquals(m2.invoke(instanceOfClassCC, instanceOfClassCC), "CC");
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", classToTestCC);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, instanceOfClassCC), "CC");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainDD() throws Exception {
|
||||||
|
Method m2 = classToTestCC.getDeclaredMethod("m2", classToTestCC);
|
||||||
|
assertEquals(m2.invoke(instanceOfClassCC, instanceOfClassCC), "CC");
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", classToTestCC);
|
||||||
|
assertEquals(main.invoke(instanceOfClass, instanceOfClassDD), "CC");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//PL 2020-05-12: Die folgenden Test funktionieren erst, wenn Generics im Bytecode implementiert sind
|
||||||
|
@Test
|
||||||
|
public void testmainVectorAA() throws Exception {
|
||||||
|
Method m2 = classToTestAA.getDeclaredMethod("m2", classToTestAA);
|
||||||
|
assertEquals(m2.invoke(instanceOfClassAA, instanceOfClassAA), "AA");
|
||||||
|
Vector v = new Vector<>();
|
||||||
|
v.add(instanceOfClassAA);
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", Vector.class);
|
||||||
|
try {
|
||||||
|
assertEquals(main.invoke(instanceOfClass, v), "AA");
|
||||||
|
}
|
||||||
|
catch (java.lang.reflect.InvocationTargetException e) {
|
||||||
|
testmainVectorCC();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainVectorBB() throws Exception {
|
||||||
|
Method m2 = classToTestAA.getDeclaredMethod("m2", classToTestAA);
|
||||||
|
assertEquals(m2.invoke(instanceOfClassAA, instanceOfClassAA), "AA");
|
||||||
|
Vector v = new Vector<>();
|
||||||
|
v.add(instanceOfClassBB);
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", Vector.class);
|
||||||
|
try {
|
||||||
|
assertEquals(main.invoke(instanceOfClass, v), "AA");
|
||||||
|
}
|
||||||
|
catch (java.lang.reflect.InvocationTargetException e) {
|
||||||
|
testmainVectorCC();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainVectorCC() throws Exception {
|
||||||
|
Method m2 = classToTestCC.getDeclaredMethod("m2", classToTestCC);
|
||||||
|
assertEquals(m2.invoke(instanceOfClassCC, instanceOfClassCC), "CC");
|
||||||
|
Vector v = new Vector<>();
|
||||||
|
v.add(instanceOfClassCC);
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", Vector.class);
|
||||||
|
String erg;
|
||||||
|
assertEquals(erg= (String) main.invoke(instanceOfClass, v),
|
||||||
|
erg.equals("CC")? "CC": "AA");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainVectorDD() throws Exception {
|
||||||
|
Method m2 = classToTestCC.getDeclaredMethod("m2", classToTestCC);
|
||||||
|
assertEquals(m2.invoke(instanceOfClassCC, instanceOfClassCC), "CC");
|
||||||
|
Vector v = new Vector<>();
|
||||||
|
v.add(instanceOfClassDD);
|
||||||
|
Method main = classToTest.getDeclaredMethod("main", Vector.class);
|
||||||
|
String erg;
|
||||||
|
assertEquals(erg= (String) main.invoke(instanceOfClass, v),
|
||||||
|
erg.equals("CC")? "CC": "AA");
|
||||||
|
}
|
||||||
|
}
|
111
src/test/java/targetast/LessEqualTest.java
Normal file
111
src/test/java/targetast/LessEqualTest.java
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class LessEqualTest {
|
||||||
|
static Class<?> classToTest;
|
||||||
|
static Object instance;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws Exception {
|
||||||
|
var classFiles = TestCodegen.generateClassFiles("LessEqual.jav", new ByteArrayClassLoader());
|
||||||
|
classToTest = classFiles.get("LessEqual");
|
||||||
|
instance = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntegers() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Integer.class, Integer.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 5,7);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqualIntegers() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Integer.class, Integer.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 5,5);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLongs() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Long.class, Long.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 5L,7L);
|
||||||
|
assertTrue(result);
|
||||||
|
}@Test
|
||||||
|
|
||||||
|
public void testFloats() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Float.class, Float.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 5F,7F);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubles() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Double.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 5.0,7.0);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLongInt() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Long.class, Integer.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 5L,7);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFloatInt() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Float.class, Integer.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 5F,7);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleInt() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Integer.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 5.0,7);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFloatLong() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Float.class, Long.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 5F,7L);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleLong() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Long.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 5.0,7L);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEqDoubleFloat() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Float.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 7.0,7F);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleFloat() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Float.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 5.0,7F);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDoubleFloat3() throws Exception {
|
||||||
|
Method lessEqual = classToTest.getDeclaredMethod("lessEqual", Double.class, Float.class);
|
||||||
|
Boolean result = (Boolean) lessEqual.invoke(instance, 9.0,7F);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
}
|
119
src/test/java/targetast/LessThanTest.java
Normal file
119
src/test/java/targetast/LessThanTest.java
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class LessThanTest {
|
||||||
|
static Class<?> classToTest;
|
||||||
|
static Object instance;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws Exception {
|
||||||
|
var classFiles = TestCodegen.generateClassFiles("LessThan.jav", new ByteArrayClassLoader());
|
||||||
|
classToTest = classFiles.get("LessThan");
|
||||||
|
instance = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanInt() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Integer.class,Integer.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 5, 7);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanInt2() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Integer.class, Integer.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 7, 5);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanInt3() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Integer.class, Integer.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 5, 5);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanLong() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Long.class,Long.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 5L, 7L);
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanLong2() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Long.class, Long.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 7L, 5L);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanLong3() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Long.class, Long.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 5L, 5L);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanFloat() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Float.class, Float.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 7F, 5F);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanDouble() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Double.class, Double.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 7.0, 5.0);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanLongInt() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Long.class, Integer.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 7L, 5);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanFloatInt() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Float.class, Integer.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 7F, 5);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanDoubleInt() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Double.class, Integer.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 7.0, 5);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanFloatLong() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Float.class, Long.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 7F, 5L);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanDoubleLong() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Double.class, Long.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 7.0, 5L);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLessThanDoubleFloat() throws Exception {
|
||||||
|
Method lessThan = classToTest.getDeclaredMethod("lessThan", Double.class, Float.class);
|
||||||
|
Boolean result = (Boolean) lessThan.invoke(instance, 7.0, 5F);
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
}
|
71
src/test/java/targetast/OLTest.java
Normal file
71
src/test/java/targetast/OLTest.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class OLTest {
|
||||||
|
private static Class<?> classToTest;
|
||||||
|
private static Class<?> classToTest1;
|
||||||
|
private static Object instanceOfClass;
|
||||||
|
private static Object instanceOfClass1;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
var classFiles = TestCodegen.generateClassFiles("OL.jav", new ByteArrayClassLoader());
|
||||||
|
classToTest = classFiles.get("OL");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
classToTest1 = classFiles.get("OLMain");
|
||||||
|
instanceOfClass1 = classToTest1.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmInt() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m", Integer.class);
|
||||||
|
Integer result = (Integer) m.invoke(instanceOfClass, 5);
|
||||||
|
assertEquals(new Integer(10), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmDouble() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m", Double.class);
|
||||||
|
Double result = (Double) m.invoke(instanceOfClass, 5.0);
|
||||||
|
assertEquals(new Double(10.0), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmString() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m", String.class);
|
||||||
|
String result = (String) m.invoke(instanceOfClass, "xxx");
|
||||||
|
assertEquals("xxxxxx", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOLMainClassName() {
|
||||||
|
assertEquals("OLMain", classToTest1.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainInt() throws Exception {
|
||||||
|
Method main = classToTest1.getDeclaredMethod("main", Integer.class);
|
||||||
|
Integer result = (Integer) main.invoke(instanceOfClass1, 5);
|
||||||
|
assertEquals(Integer.valueOf(10), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainDouble() throws Exception {
|
||||||
|
Method main = classToTest1.getDeclaredMethod("main", Double.class);
|
||||||
|
Double result = (Double) main.invoke(instanceOfClass1, 5.0);
|
||||||
|
assertEquals(Double.valueOf(10.0), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testmainString() throws Exception {
|
||||||
|
Method main = classToTest1.getDeclaredMethod("main", String.class);
|
||||||
|
String result = (String) main.invoke(instanceOfClass1, "xxx");
|
||||||
|
assertEquals("xxxxxx", result);
|
||||||
|
}
|
||||||
|
}
|
49
src/test/java/targetast/PostIncTest.java
Normal file
49
src/test/java/targetast/PostIncTest.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class PostIncTest {
|
||||||
|
private static Class<?> classToTest;
|
||||||
|
private static Object instanceOfClass;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
var classFiles = TestCodegen.generateClassFiles("PostIncDec.jav", new ByteArrayClassLoader());
|
||||||
|
classToTest = classFiles.get("PostIncDec");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testM1() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(Integer.valueOf(1), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testM2() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m2");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(Integer.valueOf(0), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testD1() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("d");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(Integer.valueOf(-1), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testD2() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("d2");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(Integer.valueOf(0), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
49
src/test/java/targetast/PreIncTest.java
Normal file
49
src/test/java/targetast/PreIncTest.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class PreIncTest {
|
||||||
|
private static Class<?> classToTest;
|
||||||
|
private static Object instanceOfClass;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
var classFiles = TestCodegen.generateClassFiles("PreInc.jav", new ByteArrayClassLoader());
|
||||||
|
classToTest = classFiles.get("PreInc");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testM() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(Integer.valueOf(1), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testM2() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m2");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(Integer.valueOf(1), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testD() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("d");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(Integer.valueOf(-1), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testD2() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("d2");
|
||||||
|
Integer res = (Integer) m.invoke(instanceOfClass);
|
||||||
|
assertEquals(Integer.valueOf(-1), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
58
src/test/java/targetast/PutTest.java
Normal file
58
src/test/java/targetast/PutTest.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Stack;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class PutTest {
|
||||||
|
private static Class<?> classToTest;
|
||||||
|
private static Object instanceOfClass;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
var classFiles = TestCodegen.generateClassFiles("Put.jav", new ByteArrayClassLoader());
|
||||||
|
classToTest = classFiles.get("Put");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPutElementVector() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("putElement", Object.class, Vector.class);
|
||||||
|
Vector<Integer> v_invoke = new Vector<>();
|
||||||
|
m.invoke(instanceOfClass, 5, v_invoke);
|
||||||
|
Vector<Integer> v = new Vector<>();
|
||||||
|
v.add(5);
|
||||||
|
assertEquals(v, v_invoke);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPutElementStack() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("putElement", Object.class, Stack.class);
|
||||||
|
Stack<Integer> s_invoke = new Stack<>();
|
||||||
|
m.invoke(instanceOfClass, 5, s_invoke);
|
||||||
|
assertEquals(new Integer(5), s_invoke.pop());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMainVector() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("main", Object.class, Vector.class);
|
||||||
|
Vector<Integer> v_invoke = new Vector<>();
|
||||||
|
m.invoke(instanceOfClass, 6, v_invoke);
|
||||||
|
Vector<Integer> v = new Vector<>();
|
||||||
|
v.add(6);
|
||||||
|
assertEquals(v, v_invoke);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMainStack() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("main", Object.class, Stack.class);
|
||||||
|
Stack<Integer> s_invoke = new Stack<>();
|
||||||
|
m.invoke(instanceOfClass, 6, s_invoke);
|
||||||
|
assertEquals(new Integer(6), s_invoke.pop());
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,12 @@
|
|||||||
package targetast;
|
package targetast;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.target.bytecode.Codegen;
|
import de.dhbwstuttgart.target.bytecode.Codegen;
|
||||||
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
import de.dhbwstuttgart.target.tree.MethodParameter;
|
import de.dhbwstuttgart.target.tree.MethodParameter;
|
||||||
import de.dhbwstuttgart.target.tree.TargetClass;
|
import de.dhbwstuttgart.target.tree.TargetClass;
|
||||||
import de.dhbwstuttgart.target.tree.expression.*;
|
import de.dhbwstuttgart.target.tree.expression.*;
|
||||||
|
import de.dhbwstuttgart.target.tree.type.TargetFunNType;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
import de.dhbwstuttgart.target.tree.type.TargetRefType;
|
||||||
import de.dhbwstuttgart.target.tree.type.TargetType;
|
import de.dhbwstuttgart.target.tree.type.TargetType;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -15,26 +18,47 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.StandardOpenOption;
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
public class TestCodegen {
|
public class TestCodegen {
|
||||||
|
|
||||||
private static ByteArrayClassLoader loader = new ByteArrayClassLoader();
|
public static Class<?> generateClass(TargetClass clazz, ByteArrayClassLoader classLoader) throws IOException {
|
||||||
|
|
||||||
public static Class generateClass(TargetClass clazz) throws IOException {
|
|
||||||
var codegen = new Codegen(clazz);
|
var codegen = new Codegen(clazz);
|
||||||
var bytes = codegen.generate();
|
var bytes = codegen.generate();
|
||||||
var path = Path.of(System.getProperty("user.dir"), "src/test/resources/target/");
|
var path = Path.of(System.getProperty("user.dir"), "src/test/resources/target/");
|
||||||
Files.createDirectories(path);
|
Files.createDirectories(path);
|
||||||
Files.write(path.resolve(clazz.qualifiedName() + ".class"), bytes, StandardOpenOption.CREATE);
|
Files.write(path.resolve(clazz.qualifiedName() + ".class"), bytes, StandardOpenOption.CREATE);
|
||||||
return loader.loadClass(bytes);
|
return classLoader.loadClass(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, Class<?>> generateClassFiles(String filename, ByteArrayClassLoader classLoader) throws IOException, ClassNotFoundException {
|
||||||
|
var file = Path.of(System.getProperty("user.dir"), "/src/test/resources/bytecode/javFiles/", filename).toFile();
|
||||||
|
var compiler = new JavaTXCompiler(file);
|
||||||
|
var resultSet = compiler.typeInference();
|
||||||
|
var converter = new ASTToTargetAST(resultSet);
|
||||||
|
var classes = compiler.sourceFiles.get(file).getClasses();
|
||||||
|
|
||||||
|
for (var bytes : converter.generateUsedFunNTypes()) {
|
||||||
|
classLoader.loadClass(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes.stream().map(cli -> {
|
||||||
|
try {
|
||||||
|
return generateClass(converter.convert(cli), classLoader);
|
||||||
|
} catch (IOException exception) {
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toMap(Class::getName, Function.identity()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyClass() throws Exception {
|
public void testEmptyClass() throws Exception {
|
||||||
var clazz = new TargetClass(Opcodes.ACC_PUBLIC, "Empty");
|
var clazz = new TargetClass(Opcodes.ACC_PUBLIC, "Empty");
|
||||||
clazz.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", List.of(), null, new TargetBlock(List.of()));
|
clazz.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "main", List.of(), null, new TargetBlock(List.of()));
|
||||||
generateClass(clazz).getDeclaredMethod("main").invoke(null);
|
generateClass(clazz, new ByteArrayClassLoader()).getDeclaredMethod("main").invoke(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -78,7 +102,7 @@ public class TestCodegen {
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
var clazz = generateClass(targetClass);
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
assertEquals(clazz.getDeclaredMethod("add", Integer.class, Integer.class).invoke(null, 10, 10), 20);
|
assertEquals(clazz.getDeclaredMethod("add", Integer.class, Integer.class).invoke(null, 10, 10), 20);
|
||||||
assertEquals(clazz.getDeclaredMethod("sub", Integer.class, Integer.class).invoke(null, 20, 10), 10);
|
assertEquals(clazz.getDeclaredMethod("sub", Integer.class, Integer.class).invoke(null, 20, 10), 10);
|
||||||
assertEquals(clazz.getDeclaredMethod("div", Integer.class, Integer.class).invoke(null, 20, 10), 2);
|
assertEquals(clazz.getDeclaredMethod("div", Integer.class, Integer.class).invoke(null, 20, 10), 2);
|
||||||
@ -86,6 +110,39 @@ public class TestCodegen {
|
|||||||
assertEquals(clazz.getDeclaredMethod("rem", Integer.class, Integer.class).invoke(null, 10, 3), 1);
|
assertEquals(clazz.getDeclaredMethod("rem", Integer.class, Integer.class).invoke(null, 10, 3), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnary() throws Exception {
|
||||||
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "Unary");
|
||||||
|
|
||||||
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "not",
|
||||||
|
List.of(new MethodParameter(TargetType.Integer, "a")),
|
||||||
|
TargetType.Integer,
|
||||||
|
new TargetBlock(List.of(new TargetReturn(
|
||||||
|
new TargetUnaryOp.Not(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a")))
|
||||||
|
))
|
||||||
|
);
|
||||||
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "neg",
|
||||||
|
List.of(new MethodParameter(TargetType.Integer, "a")),
|
||||||
|
TargetType.Integer,
|
||||||
|
new TargetBlock(List.of(new TargetReturn(
|
||||||
|
new TargetUnaryOp.Negate(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a")))
|
||||||
|
))
|
||||||
|
);
|
||||||
|
targetClass.addMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "add",
|
||||||
|
List.of(new MethodParameter(TargetType.Integer, "a")),
|
||||||
|
TargetType.Integer,
|
||||||
|
new TargetBlock(List.of(new TargetReturn(
|
||||||
|
new TargetUnaryOp.Add(TargetType.Integer, new TargetLocalVar(TargetType.Integer, "a")))
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
|
assertEquals(clazz.getDeclaredMethod("not", Integer.class).invoke(null, 10), -11);
|
||||||
|
assertEquals(clazz.getDeclaredMethod("neg", Integer.class).invoke(null, 10), -10);
|
||||||
|
assertEquals(clazz.getDeclaredMethod("add", Integer.class).invoke(null, 10), 10);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConditional() throws Exception {
|
public void testConditional() throws Exception {
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "Conditional");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "Conditional");
|
||||||
@ -105,7 +162,7 @@ public class TestCodegen {
|
|||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
var clazz = generateClass(targetClass);
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
var and = clazz.getDeclaredMethod("and", Boolean.class, Boolean.class);
|
var and = clazz.getDeclaredMethod("and", Boolean.class, Boolean.class);
|
||||||
var or = clazz.getDeclaredMethod("or", Boolean.class, Boolean.class);
|
var or = clazz.getDeclaredMethod("or", Boolean.class, Boolean.class);
|
||||||
assertEquals(and.invoke(null, true, false), false);
|
assertEquals(and.invoke(null, true, false), false);
|
||||||
@ -123,7 +180,7 @@ public class TestCodegen {
|
|||||||
new TargetBinaryOp.Add(TargetType.Long, new TargetLiteral.CharLiteral((char)10), new TargetLiteral.LongLiteral((long)20))
|
new TargetBinaryOp.Add(TargetType.Long, new TargetLiteral.CharLiteral((char)10), new TargetLiteral.LongLiteral((long)20))
|
||||||
)))
|
)))
|
||||||
);
|
);
|
||||||
var clazz = generateClass(targetClass);
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
assertEquals(clazz.getDeclaredMethod("add").invoke(null), (long)30);
|
assertEquals(clazz.getDeclaredMethod("add").invoke(null), (long)30);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +203,7 @@ public class TestCodegen {
|
|||||||
)))
|
)))
|
||||||
);
|
);
|
||||||
|
|
||||||
var clazz = generateClass(targetClass);
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
clazz.getDeclaredMethod("helloWorld").invoke(null);
|
clazz.getDeclaredMethod("helloWorld").invoke(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +223,7 @@ public class TestCodegen {
|
|||||||
)
|
)
|
||||||
)))
|
)))
|
||||||
);
|
);
|
||||||
var clazz = generateClass(targetClass);
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
var ifStmt = clazz.getDeclaredMethod("ifStmt", Integer.class);
|
var ifStmt = clazz.getDeclaredMethod("ifStmt", Integer.class);
|
||||||
assertEquals(ifStmt.invoke(null, 10), 1);
|
assertEquals(ifStmt.invoke(null, 10), 1);
|
||||||
assertEquals(ifStmt.invoke(null, 3), 2);
|
assertEquals(ifStmt.invoke(null, 3), 2);
|
||||||
@ -195,7 +252,7 @@ public class TestCodegen {
|
|||||||
new TargetReturn(new TargetLocalVar(TargetType.Integer, "sum"))
|
new TargetReturn(new TargetLocalVar(TargetType.Integer, "sum"))
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
var clazz = generateClass(targetClass);
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
assertEquals(clazz.getDeclaredMethod("forLoop").invoke(null), 45);
|
assertEquals(clazz.getDeclaredMethod("forLoop").invoke(null), 45);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +274,7 @@ public class TestCodegen {
|
|||||||
new TargetReturn(new TargetLocalVar(TargetType.Integer, "i"))
|
new TargetReturn(new TargetLocalVar(TargetType.Integer, "i"))
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
var clazz = generateClass(targetClass);
|
var clazz = generateClass(targetClass, new ByteArrayClassLoader());
|
||||||
assertEquals(clazz.getDeclaredMethod("whileLoop").invoke(null), 10);
|
assertEquals(clazz.getDeclaredMethod("whileLoop").invoke(null), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,6 +287,7 @@ public class TestCodegen {
|
|||||||
pointTarget.addConstructor(Opcodes.ACC_PUBLIC,
|
pointTarget.addConstructor(Opcodes.ACC_PUBLIC,
|
||||||
List.of(new MethodParameter(TargetType.Integer, "x"), new MethodParameter(TargetType.Integer, "y")),
|
List.of(new MethodParameter(TargetType.Integer, "x"), new MethodParameter(TargetType.Integer, "y")),
|
||||||
new TargetBlock(List.of(
|
new TargetBlock(List.of(
|
||||||
|
new TargetMethodCall(null, new TargetSuper(TargetType.Object), List.of(), TargetType.Object, "<init>", false, false),
|
||||||
new TargetAssign(TargetType.Integer,
|
new TargetAssign(TargetType.Integer,
|
||||||
new TargetFieldVar(TargetType.Integer, pointType, false, new TargetThis(pointType), "x"),
|
new TargetFieldVar(TargetType.Integer, pointType, false, new TargetThis(pointType), "x"),
|
||||||
new TargetLocalVar(TargetType.Integer, "x")
|
new TargetLocalVar(TargetType.Integer, "x")
|
||||||
@ -252,8 +310,9 @@ public class TestCodegen {
|
|||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
var pointClass = generateClass(pointTarget);
|
var classLoader = new ByteArrayClassLoader();
|
||||||
var mainClass = generateClass(mainTarget);
|
var pointClass = generateClass(pointTarget, classLoader);
|
||||||
|
var mainClass = generateClass(mainTarget, classLoader);
|
||||||
|
|
||||||
var point = mainClass.getDeclaredMethod("makePoint", Integer.class, Integer.class).invoke(null, 10, 20);
|
var point = mainClass.getDeclaredMethod("makePoint", Integer.class, Integer.class).invoke(null, 10, 20);
|
||||||
assertEquals(point.getClass().getDeclaredField("x").get(point), 10);
|
assertEquals(point.getClass().getDeclaredField("x").get(point), 10);
|
||||||
@ -262,11 +321,14 @@ public class TestCodegen {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLambda() throws Exception {
|
public void testLambda() throws Exception {
|
||||||
var fun = loader.loadClass(Path.of(System.getProperty("user.dir"), "src/test/java/targetast/Fun1$$.class"));
|
var classLoader = new ByteArrayClassLoader();
|
||||||
var interfaceType = new TargetRefType("Fun1$$");
|
var fun = classLoader.loadClass(Path.of(System.getProperty("user.dir"), "src/test/java/targetast/Fun1$$.class"));
|
||||||
|
var interfaceType = new TargetFunNType(1, List.of());
|
||||||
|
|
||||||
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "Lambda");
|
var targetClass = new TargetClass(Opcodes.ACC_PUBLIC, "CGLambda");
|
||||||
targetClass.addConstructor(Opcodes.ACC_PUBLIC, List.of(), new TargetBlock(List.of()));
|
targetClass.addConstructor(Opcodes.ACC_PUBLIC, List.of(), new TargetBlock(List.of(
|
||||||
|
new TargetMethodCall(null, new TargetSuper(TargetType.Object), List.of(), TargetType.Object, "<init>", false, false)
|
||||||
|
)));
|
||||||
targetClass.addMethod(Opcodes.ACC_PUBLIC, "lambda", List.of(), TargetType.Integer,
|
targetClass.addMethod(Opcodes.ACC_PUBLIC, "lambda", List.of(), TargetType.Integer,
|
||||||
new TargetBlock(List.of(
|
new TargetBlock(List.of(
|
||||||
new TargetVarDecl(interfaceType, "by2",
|
new TargetVarDecl(interfaceType, "by2",
|
||||||
@ -284,7 +346,7 @@ public class TestCodegen {
|
|||||||
), interfaceType, "apply", false, true)))
|
), interfaceType, "apply", false, true)))
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
var clazz = generateClass(targetClass);
|
var clazz = generateClass(targetClass, classLoader);
|
||||||
var instance = clazz.getConstructor().newInstance();
|
var instance = clazz.getConstructor().newInstance();
|
||||||
assertEquals(clazz.getDeclaredMethod("lambda").invoke(instance), 20);
|
assertEquals(clazz.getDeclaredMethod("lambda").invoke(instance), 20);
|
||||||
}
|
}
|
||||||
|
385
src/test/java/targetast/TestComplete.java
Normal file
385
src/test/java/targetast/TestComplete.java
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import static targetast.TestCodegen.generateClassFiles;
|
||||||
|
|
||||||
|
public class TestComplete {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void applyLambdaTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("applyLambda.jav", new ByteArrayClassLoader());
|
||||||
|
var applyLambda = classFiles.get("applyLambda");
|
||||||
|
var instance = applyLambda.getDeclaredConstructor().newInstance();
|
||||||
|
var m = applyLambda.getDeclaredMethod("m");
|
||||||
|
var result = m.invoke(instance);
|
||||||
|
|
||||||
|
assertEquals(result.getClass(), classFiles.get("Apply"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void binaryTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("BinaryInMeth.jav", new ByteArrayClassLoader());
|
||||||
|
var binaryInMeth = classFiles.get("BinaryInMeth");
|
||||||
|
var instance = binaryInMeth.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
var m2 = binaryInMeth.getDeclaredMethod("m2", Integer.class, Integer.class);
|
||||||
|
var m3 = binaryInMeth.getDeclaredMethod("m3", Integer.class);
|
||||||
|
|
||||||
|
assertEquals(6, m2.invoke(instance, 2, 3));
|
||||||
|
assertEquals(4, m3.invoke(instance, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void classGenLamTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("ClassGenLam.jav", new ByteArrayClassLoader());
|
||||||
|
classFiles.get("ClassGenLam").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void facTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Fac.jav", new ByteArrayClassLoader());
|
||||||
|
var fac = classFiles.get("Fac");
|
||||||
|
var instance = fac.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
var getFac = fac.getDeclaredMethod("getFac", Integer.class);
|
||||||
|
assertEquals(6, getFac.invoke(instance, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void facultyTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Faculty.jav", new ByteArrayClassLoader());
|
||||||
|
|
||||||
|
var fac = classFiles.get("Faculty");
|
||||||
|
var constructor = fac.getDeclaredConstructor();
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
var instance = constructor.newInstance();
|
||||||
|
|
||||||
|
var getFact = fac.getDeclaredMethod("getFact", Integer.class);
|
||||||
|
assertEquals(6, getFact.invoke(instance, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fieldTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Field.jav", new ByteArrayClassLoader());
|
||||||
|
var field = classFiles.get("Field");
|
||||||
|
var instance = field.getDeclaredConstructor().newInstance();
|
||||||
|
assertEquals(1, field.getFields().length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fieldTph2Test() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("FieldTph2.jav", new ByteArrayClassLoader());
|
||||||
|
var fieldtph2 = classFiles.get("FieldTph2");
|
||||||
|
var instance = fieldtph2.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
var a = fieldtph2.getDeclaredField("a");
|
||||||
|
var m2 = fieldtph2.getDeclaredMethod("m2", Object.class);
|
||||||
|
m2.invoke(instance, 1);
|
||||||
|
|
||||||
|
var m = fieldtph2.getDeclaredMethod("m", Object.class);
|
||||||
|
assertEquals(1, m.invoke(instance, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fieldTphConsMethTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("FieldTphConsMeth.jav", new ByteArrayClassLoader());
|
||||||
|
var fieldTphConsMeth = classFiles.get("FieldTphConsMeth");
|
||||||
|
|
||||||
|
var ctor = fieldTphConsMeth.getDeclaredConstructor(Object.class);
|
||||||
|
var instance = ctor.newInstance("C");
|
||||||
|
var a = fieldTphConsMeth.getDeclaredField("a");
|
||||||
|
var id = fieldTphConsMeth.getDeclaredMethod("id", Object.class);
|
||||||
|
|
||||||
|
assertEquals(42, id.invoke(instance, 42));
|
||||||
|
assertEquals("C", a.get(instance));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fieldTphMMethTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("FieldTphMMeth.jav", new ByteArrayClassLoader());
|
||||||
|
var fieldTphMMeth = classFiles.get("FieldTphMMeth");
|
||||||
|
var ctor = fieldTphMMeth.getDeclaredConstructor(Object.class, Object.class, Boolean.class);
|
||||||
|
|
||||||
|
var instance1 = ctor.newInstance("C", 42, true);
|
||||||
|
var instance2 = ctor.newInstance("C", 42, false);
|
||||||
|
|
||||||
|
var m = fieldTphMMeth.getDeclaredMethod("m", Object.class, Object.class, Boolean.class);
|
||||||
|
assertEquals(42, m.invoke(instance1, "C", 42, false));
|
||||||
|
|
||||||
|
var a = fieldTphMMeth.getDeclaredField("a");
|
||||||
|
assertEquals("C", a.get(instance1));
|
||||||
|
assertEquals(42, a.get(instance2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void genTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Gen.jav", new ByteArrayClassLoader());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void idTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Id.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("Id").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void infTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Inf.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("Inf").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void kompTphTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("KompTph.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("KompTph").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lambdaCaptureTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("LambdaCapture.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("LambdaCapture").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lambdaTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Lambda.jav", new ByteArrayClassLoader());
|
||||||
|
var classToTest = classFiles.get("Lambda");
|
||||||
|
var instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
var m = classToTest.getDeclaredMethod("m");
|
||||||
|
var lambda = m.invoke(instanceOfClass).getClass();
|
||||||
|
var apply = lambda.getMethod("apply", Object.class);
|
||||||
|
apply.setAccessible(true);
|
||||||
|
|
||||||
|
var i = Integer.valueOf(77);
|
||||||
|
assertEquals(i, apply.invoke(m.invoke(instanceOfClass), i));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mathStrucInteger() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("mathStrucInteger.jav", new ByteArrayClassLoader());
|
||||||
|
var mathStrucInteger = classFiles.get("mathStrucInteger");
|
||||||
|
mathStrucInteger.getDeclaredConstructor(Integer.class).newInstance(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mathStruc() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("mathStruc.jav", new ByteArrayClassLoader());
|
||||||
|
var mathStruc = classFiles.get("mathStruc");
|
||||||
|
mathStruc.getDeclaredConstructor(Object.class).newInstance("A");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void matrixOpTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("MatrixOP.jav", new ByteArrayClassLoader());
|
||||||
|
var matrixOP = classFiles.get("MatrixOP");
|
||||||
|
|
||||||
|
Vector<Vector<Integer>> vv = new Vector<>();
|
||||||
|
Vector<Integer> v1 = new Vector<>();
|
||||||
|
v1.addElement(2);
|
||||||
|
v1.addElement(2);
|
||||||
|
Vector<Integer> v2 = new Vector<>();
|
||||||
|
v2.addElement(3);
|
||||||
|
v2.addElement(3);
|
||||||
|
vv.addElement(v1);
|
||||||
|
vv.addElement(v2);
|
||||||
|
|
||||||
|
var instanceOfClass_m1 = matrixOP.getDeclaredConstructor(Vector.class).newInstance(vv);
|
||||||
|
|
||||||
|
Vector<Vector<Integer>> vv1 = new Vector<>();
|
||||||
|
Vector<Integer> v3 = new Vector<>();
|
||||||
|
v3.addElement(2);
|
||||||
|
v3.addElement(2);
|
||||||
|
Vector<Integer> v4 = new Vector<>();
|
||||||
|
v4.addElement(3);
|
||||||
|
v4.addElement(3);
|
||||||
|
vv1.addElement(v3);
|
||||||
|
vv1.addElement(v4);
|
||||||
|
|
||||||
|
var instanceOfClass_m2 = matrixOP.getDeclaredConstructor(Vector.class).newInstance(vv1);//Matrix m2 = new Matrix(vv1);
|
||||||
|
|
||||||
|
var mul = matrixOP.getField("mul");
|
||||||
|
mul.setAccessible(true);
|
||||||
|
|
||||||
|
var lambda = mul.get(instanceOfClass_m1).getClass();
|
||||||
|
var apply = lambda.getMethod("apply", Object.class, Object.class);
|
||||||
|
apply.setAccessible(true);
|
||||||
|
|
||||||
|
var result = apply.invoke(mul.get(instanceOfClass_m1), instanceOfClass_m1, instanceOfClass_m2);
|
||||||
|
System.out.println(instanceOfClass_m1.toString() + " * " + instanceOfClass_m2.toString() + " = " + result.toString());
|
||||||
|
|
||||||
|
Vector<Vector<Integer>> res = new Vector<>();
|
||||||
|
Vector<Integer> v5 = new Vector<>();
|
||||||
|
v5.addElement(10);
|
||||||
|
v5.addElement(10);
|
||||||
|
Vector<Integer> v6 = new Vector<>();
|
||||||
|
v6.addElement(15);
|
||||||
|
v6.addElement(15);
|
||||||
|
res.addElement(v5);
|
||||||
|
res.addElement(v6);
|
||||||
|
|
||||||
|
var instanceOfClass_m3 = matrixOP.getDeclaredConstructor(Vector.class).newInstance(res);
|
||||||
|
assertEquals(result, instanceOfClass_m3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore("Thread blocking for some reason")
|
||||||
|
@Test
|
||||||
|
public void matrixTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Matrix.jav", new ByteArrayClassLoader());
|
||||||
|
var matrix = classFiles.get("Matrix");
|
||||||
|
|
||||||
|
Vector<Vector<Integer>> vv = new Vector<>();
|
||||||
|
Vector<Integer> v1 = new Vector<> ();
|
||||||
|
v1.addElement(2);
|
||||||
|
v1.addElement(2);
|
||||||
|
Vector<Integer> v2 = new Vector<> ();
|
||||||
|
v2.addElement(3);
|
||||||
|
v2.addElement(3);
|
||||||
|
vv.addElement(v1);
|
||||||
|
vv.addElement(v2);
|
||||||
|
|
||||||
|
var instanceOfClass_m1 = matrix.getDeclaredConstructor(Vector.class).newInstance(vv);
|
||||||
|
|
||||||
|
Vector<Vector<Integer>> vv1 = new Vector<>();
|
||||||
|
Vector<Integer> v3 = new Vector<> ();
|
||||||
|
v3.addElement(2);
|
||||||
|
v3.addElement(2);
|
||||||
|
Vector<Integer> v4 = new Vector<> ();
|
||||||
|
v4.addElement(3);
|
||||||
|
v4.addElement(3);
|
||||||
|
vv1.addElement(v3);
|
||||||
|
vv1.addElement(v4);
|
||||||
|
|
||||||
|
var instanceOfClass_m2 = matrix.getDeclaredConstructor(Vector.class).newInstance(vv1);
|
||||||
|
|
||||||
|
var mul = matrix.getDeclaredMethod("mul", Vector.class);
|
||||||
|
var result = mul.invoke(instanceOfClass_m1, instanceOfClass_m2);
|
||||||
|
System.out.println(instanceOfClass_m1.toString() + " * " + instanceOfClass_m2.toString() + " = " + result.toString());
|
||||||
|
|
||||||
|
Vector<Vector<Integer>> res = new Vector<>();
|
||||||
|
Vector<Integer> v5 = new Vector<> ();
|
||||||
|
v5.addElement(10);
|
||||||
|
v5.addElement(10);
|
||||||
|
Vector<Integer> v6 = new Vector<> ();
|
||||||
|
v6.addElement(15);
|
||||||
|
v6.addElement(15);
|
||||||
|
res.addElement(v5);
|
||||||
|
res.addElement(v6);
|
||||||
|
|
||||||
|
var instanceOfClass_m3 = matrix.getDeclaredConstructor(Vector.class).newInstance(res);
|
||||||
|
assertEquals(result, instanceOfClass_m3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mergeTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Merge.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("Merge").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void overloadingSortingTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Sorting.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("Sorting").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void overloadingTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Overloading.jav", new ByteArrayClassLoader());
|
||||||
|
var overloading = classFiles.get("Overloading");
|
||||||
|
var overloading2 = classFiles.get("Overloading2");
|
||||||
|
var instance1 = overloading.getDeclaredConstructor().newInstance();
|
||||||
|
var instance2 = overloading2.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
var m1 = overloading.getDeclaredMethod("test", overloading);
|
||||||
|
assertEquals("Overloading", m1.invoke(instance1, instance1));
|
||||||
|
var m2 = overloading.getDeclaredMethod("test", overloading2);
|
||||||
|
assertEquals("Overloading2", m2.invoke(instance1, instance2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void plusTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Plus.jav", new ByteArrayClassLoader());
|
||||||
|
var plus = classFiles.get("Plus");
|
||||||
|
var instance = plus.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
var addInt = plus.getDeclaredMethod("m", Integer.class, Integer.class);
|
||||||
|
assertEquals(10, addInt.invoke(instance, 7, 3));
|
||||||
|
|
||||||
|
var addString = plus.getDeclaredMethod("m", String.class, String.class);
|
||||||
|
assertEquals("ByteCode", addString.invoke(instance, "Byte", "Code"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void relOpsTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("RelOps.jav", new ByteArrayClassLoader());
|
||||||
|
var relOps = classFiles.get("RelOps");
|
||||||
|
var instance = relOps.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
var m = relOps.getDeclaredMethod("m", Integer.class,Integer.class);
|
||||||
|
assertFalse((Boolean) m.invoke(instance, 7, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simpleCyclesTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("SimpleCycle.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("SimpleCycle").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void subMatTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("SubMatrix.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("SubMatrix").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void tph3Test() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Tph3.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("Tph3").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void tph5Test() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Tph5.jav", new ByteArrayClassLoader());
|
||||||
|
var tph5 = classFiles.get("Tph5");
|
||||||
|
var instance = tph5.getDeclaredConstructor().newInstance();
|
||||||
|
var m = tph5.getDeclaredMethod("m", Object.class, Object.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void tph6Test() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Tph6.jav", new ByteArrayClassLoader());
|
||||||
|
var tph5 = classFiles.get("Tph6");
|
||||||
|
var instance = tph5.getDeclaredConstructor().newInstance();
|
||||||
|
var m = tph5.getDeclaredMethod("m", Object.class, Object.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void typedIdTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("TypedID.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("TypedID").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void vectorAddTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("VectorAdd.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("VectorAdd").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void vectorSuperTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("VectorSuper.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("VectorSuper").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void yTest() throws Exception {
|
||||||
|
var classFiles = generateClassFiles("Y.jav", new ByteArrayClassLoader());
|
||||||
|
var instance = classFiles.get("Y").getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
}
|
58
src/test/java/targetast/TphTest.java
Normal file
58
src/test/java/targetast/TphTest.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class TphTest {
|
||||||
|
|
||||||
|
private static Class<?> classToTest;
|
||||||
|
private static Object instanceOfClass;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
var classFiles = TestCodegen.generateClassFiles("Tph.jav", new ByteArrayClassLoader());
|
||||||
|
classToTest = classFiles.get("Tph");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class);
|
||||||
|
Object result = m.invoke(instanceOfClass, 1,2);
|
||||||
|
|
||||||
|
assertEquals(1,result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class);
|
||||||
|
Object result = m.invoke(instanceOfClass, 1, "sss");
|
||||||
|
|
||||||
|
assertEquals(1,result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test3() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m2", Object.class);
|
||||||
|
Object result = m.invoke(instanceOfClass, 2);
|
||||||
|
|
||||||
|
assertEquals(2,result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test4() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m2", Object.class);
|
||||||
|
Object result = m.invoke(instanceOfClass,"xxx");
|
||||||
|
|
||||||
|
assertEquals("xxx",result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
47
src/test/java/targetast/WhileTest.java
Normal file
47
src/test/java/targetast/WhileTest.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package targetast;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class WhileTest {
|
||||||
|
private static Class<?> classToTest;
|
||||||
|
private static Object instanceOfClass;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
var classFiles = TestCodegen.generateClassFiles("While.jav", new ByteArrayClassLoader());
|
||||||
|
classToTest = classFiles.get("While");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m", Integer.class);
|
||||||
|
Integer result = (Integer) m.invoke(instanceOfClass, 0);
|
||||||
|
assertEquals(Integer.valueOf(2), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDouble() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m", Double.class);
|
||||||
|
Double result = (Double) m.invoke(instanceOfClass, 0.0);
|
||||||
|
assertEquals(Double.valueOf(2.0), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLong() throws Exception {
|
||||||
|
Method m = classToTest.getDeclaredMethod("m", Long.class);
|
||||||
|
Long result = (Long) m.invoke(instanceOfClass, 0l);
|
||||||
|
assertEquals(Long.valueOf(2l), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user