forked from JavaTX/JavaCompilerCore
Bugs gefixt. Tests für relationalen Operatoren(GreaterEqualTest, ...) laufen.
Für Typplaceholder werden Generics verwendet. Neue Tests angefügt.
This commit is contained in:
parent
dcc36f082f
commit
0f29bc038a
@ -191,13 +191,13 @@ public class BytecodeGen implements ASTVisitor {
|
||||
System.out.println(acc);
|
||||
|
||||
/*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/
|
||||
boolean hasGenInParameterList = genericsAndBounds.containsKey(resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()));
|
||||
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.subSequence(0, 4).equals("TPH ");
|
||||
/*Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature, wenn nicht,
|
||||
* prüfe, ob einer der Parameter Typ-Variable als Typ hat*/
|
||||
if(!hasGenInParameterList) {
|
||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
|
||||
if(genericsAndBounds.containsKey(typeOfParam)) {
|
||||
if(genericsAndBounds.containsKey(typeOfParam)||typeOfParam.substring(0, 4).equals("TPH ")) {
|
||||
hasGenInParameterList = true;
|
||||
break;
|
||||
}
|
||||
@ -213,6 +213,7 @@ public class BytecodeGen implements ASTVisitor {
|
||||
boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList;
|
||||
|
||||
/* if method has generics or return type is TPH, create signature */
|
||||
// zwite operand muss weggelassen werden
|
||||
if(hasGen||method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) {
|
||||
// resultset hier zum testen
|
||||
Signature signature = new Signature(method, genericsAndBoundsMethod, methodParamsAndTypes,resultSet);
|
||||
|
@ -29,8 +29,6 @@ import org.objectweb.asm.signature.SignatureWriter;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||
import de.dhbwstuttgart.bytecode.signature.TypeToString;
|
||||
import de.dhbwstuttgart.bytecode.utilities.KindOfLambda;
|
||||
import de.dhbwstuttgart.bytecode.utilities.Lambda;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
|
||||
@ -56,7 +54,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
private HashMap<String, String> genericsAndBounds;
|
||||
private boolean isBinaryExp = false;
|
||||
|
||||
private IStatement statement;
|
||||
private IStatement statement = null;
|
||||
|
||||
// for tests **
|
||||
private String fieldName;
|
||||
@ -67,9 +65,6 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
private KindOfLambda kindOfLambda;
|
||||
private HashMap<String, byte[]> classFiles;
|
||||
|
||||
private boolean isAssignStmt = false;
|
||||
private Statement loopBlock;
|
||||
|
||||
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
|
||||
|
||||
public BytecodeGenMethod(String className, ResultSet resultSet, Method m, MethodVisitor mv,
|
||||
@ -138,7 +133,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
|
||||
|
||||
if (isBinaryExp) {
|
||||
getVlaueIns(getResolvedType(localVar.getType()));
|
||||
doUnboxing(getResolvedType(localVar.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,8 +146,6 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
@Override
|
||||
public void visit(Assign assign) {
|
||||
statement = new AssignStmt(assign.rightSide);
|
||||
isAssignStmt = true;
|
||||
|
||||
// if the right side is a lambda => the left side must be a functional interface
|
||||
if (assign.rightSide instanceof LambdaExpression) {
|
||||
isRightSideALambda = true;
|
||||
@ -162,7 +155,6 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
|
||||
isBinaryExp = statement.isExprBinary();
|
||||
|
||||
|
||||
if (assign.lefSide instanceof AssignToField) {
|
||||
// load_0, ldc or .. then putfield
|
||||
this.rightSideTemp = assign.rightSide;
|
||||
@ -171,24 +163,22 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
}
|
||||
if (isBinaryExp) {
|
||||
BinaryExpr binary = (BinaryExpr) assign.rightSide;
|
||||
String lexpType = getResolvedType(binary.lexpr.getType());
|
||||
String rexpType = getResolvedType(binary.rexpr.getType());
|
||||
getValueOfIns(getLargerType(lexpType, rexpType));
|
||||
String binaryType = getResolvedType(binary.getType());
|
||||
doBoxing(binaryType);
|
||||
isBinaryExp = false;
|
||||
}
|
||||
assign.lefSide.accept(this);
|
||||
|
||||
isAssignStmt =false;
|
||||
statement = null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(BinaryExpr binary) {
|
||||
|
||||
String lexpType = getResolvedType(binary.lexpr.getType());
|
||||
String rexpType = getResolvedType(binary.rexpr.getType());
|
||||
|
||||
String largerType = getLargerType(lexpType,rexpType);
|
||||
String largerType = getLargerType(lexpType, rexpType);
|
||||
String typeOfBinary = getResolvedType(binary.getType());
|
||||
|
||||
if (typeOfBinary.equals(Type.getInternalName(String.class))) {
|
||||
@ -200,19 +190,17 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
|
||||
Label endLabel = new Label();
|
||||
// this case for while loops
|
||||
if(statement instanceof LoopStmt)
|
||||
if (statement instanceof LoopStmt)
|
||||
mv.visitLabel(endLabel);
|
||||
|
||||
binary.lexpr.accept(this);
|
||||
|
||||
if(!lexpType.equals(rexpType) &&
|
||||
!lexpType.equals(largerType))
|
||||
if (!lexpType.equals(rexpType) && !lexpType.equals(largerType))
|
||||
doCast(lexpType, largerType);
|
||||
|
||||
binary.rexpr.accept(this);
|
||||
|
||||
if(!lexpType.equals(rexpType) &&
|
||||
!rexpType.equals(largerType))
|
||||
if (!lexpType.equals(rexpType) && !rexpType.equals(largerType))
|
||||
doCast(rexpType, largerType);
|
||||
|
||||
Operator op = binary.operation;
|
||||
@ -243,7 +231,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
case BIGGERTHAN:
|
||||
case BIGGEREQUAL:
|
||||
Label branchLabel = new Label();
|
||||
doVisitRelOpInsn(op,largerType, branchLabel, endLabel);
|
||||
doVisitRelOpInsn(op, largerType, branchLabel, endLabel);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -252,19 +240,22 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Diese Methode wird nicht mehr gebraucht, da es jetzt nicht möglich ist, dass
|
||||
* solche Fälle: Integer -> Integer (OP) Short ,... usw, nicht vorkommen!
|
||||
*/
|
||||
private String getLargerType(String lexpType, String rexpType) {
|
||||
if(lexpType.equals(Type.getInternalName(String.class)) ||
|
||||
rexpType.equals(Type.getInternalName(String.class))) {
|
||||
if (lexpType.equals(Type.getInternalName(String.class))
|
||||
|| rexpType.equals(Type.getInternalName(String.class))) {
|
||||
return Type.getInternalName(String.class);
|
||||
} else
|
||||
if(lexpType.equals(Type.getInternalName(Double.class)) ||
|
||||
rexpType.equals(Type.getInternalName(Double.class))) {
|
||||
} else if (lexpType.equals(Type.getInternalName(Double.class))
|
||||
|| rexpType.equals(Type.getInternalName(Double.class))) {
|
||||
return Type.getInternalName(Double.class);
|
||||
} else if(lexpType.equals(Type.getInternalName(Float.class)) ||
|
||||
rexpType.equals(Type.getInternalName(Float.class))) {
|
||||
} else if (lexpType.equals(Type.getInternalName(Float.class))
|
||||
|| rexpType.equals(Type.getInternalName(Float.class))) {
|
||||
return Type.getInternalName(Float.class);
|
||||
} else if(lexpType.equals(Type.getInternalName(Long.class)) ||
|
||||
rexpType.equals(Type.getInternalName(Long.class))) {
|
||||
} else if (lexpType.equals(Type.getInternalName(Long.class))
|
||||
|| rexpType.equals(Type.getInternalName(Long.class))) {
|
||||
return Type.getInternalName(Long.class);
|
||||
} else {
|
||||
return Type.getInternalName(Integer.class);
|
||||
@ -278,9 +269,9 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
break;
|
||||
|
||||
case "java/lang/Double":
|
||||
if(sourceType.equals(Type.getInternalName(Long.class))) {
|
||||
if (sourceType.equals(Type.getInternalName(Long.class))) {
|
||||
mv.visitInsn(Opcodes.L2D);
|
||||
} else if(sourceType.equals(Type.getInternalName(Float.class))) {
|
||||
} else if (sourceType.equals(Type.getInternalName(Float.class))) {
|
||||
mv.visitInsn(Opcodes.F2D);
|
||||
} else {
|
||||
mv.visitInsn(Opcodes.I2D);
|
||||
@ -288,7 +279,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
break;
|
||||
|
||||
case "java/lang/Float":
|
||||
if(sourceType.equals(Type.getInternalName(Long.class))) {
|
||||
if (sourceType.equals(Type.getInternalName(Long.class))) {
|
||||
mv.visitInsn(Opcodes.L2F);
|
||||
} else {
|
||||
mv.visitInsn(Opcodes.I2F);
|
||||
@ -296,14 +287,18 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
break;
|
||||
// braucht man eigentlic nicht, muss getestet werden
|
||||
case "java/lang/String":
|
||||
if(sourceType.equals(Type.getInternalName(Double.class))) {
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf", "(D)Ljava/lang/String;", false);
|
||||
} else if(sourceType.equals(Type.getInternalName(Long.class))) {
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf", "(J)Ljava/lang/String;", false);
|
||||
} else if(sourceType.equals(Type.getInternalName(Float.class))) {
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf", "(F)Ljava/lang/String;", false);
|
||||
if (sourceType.equals(Type.getInternalName(Double.class))) {
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
|
||||
"(D)Ljava/lang/String;", false);
|
||||
} else if (sourceType.equals(Type.getInternalName(Long.class))) {
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
|
||||
"(J)Ljava/lang/String;", false);
|
||||
} else if (sourceType.equals(Type.getInternalName(Float.class))) {
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
|
||||
"(F)Ljava/lang/String;", false);
|
||||
} else {
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf", "(I)Ljava/lang/String;", false);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
|
||||
"(I)Ljava/lang/String;", false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -344,7 +339,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
break;
|
||||
}
|
||||
|
||||
statement.genBCForRelOp(mv, branchLabel, endLabel,this);
|
||||
statement.genBCForRelOp(mv, branchLabel, endLabel, this);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -368,8 +363,8 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
statement.genBCForRelOp(mv, branchLabel, endLabel, this);
|
||||
|
||||
statement.genBCForRelOp(mv, branchLabel, endLabel, this);
|
||||
}
|
||||
|
||||
private void doVisitModOpInsn(String typeOfBinary) {
|
||||
@ -532,7 +527,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
|
||||
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
|
||||
|
||||
generateBCForFunN(lambdaExpression,typeErasure);
|
||||
generateBCForFunN(lambdaExpression, typeErasure);
|
||||
}
|
||||
|
||||
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
|
||||
@ -687,17 +682,17 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
switch (op) {
|
||||
case POSTDECREMENT:
|
||||
case POSTINCREMENT:
|
||||
if(isAssignStmt)
|
||||
if (statement instanceof AssignStmt)
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
genBCForIncAndDec(op, typeOfUnary);
|
||||
getValueOfIns(typeOfUnary);
|
||||
doBoxing(typeOfUnary);
|
||||
isIncOrDec = true;
|
||||
break;
|
||||
case PREDECREMENT:
|
||||
case PREINCREMENT:
|
||||
genBCForIncAndDec(op, typeOfUnary);
|
||||
getValueOfIns(typeOfUnary);
|
||||
if(isAssignStmt)
|
||||
doBoxing(typeOfUnary);
|
||||
if (statement instanceof AssignStmt)
|
||||
mv.visitInsn(Opcodes.DUP);
|
||||
isIncOrDec = true;
|
||||
break;
|
||||
@ -712,7 +707,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
// Für Byte und Short muss noch einen Cast geben i2b, i2s
|
||||
// das wird später gemacht, da bytecode für cast noch nicht erzeugt wird
|
||||
|
||||
if(isIncOrDec && (unaryExpr.expr instanceof LocalVar)) {
|
||||
if (isIncOrDec && (unaryExpr.expr instanceof LocalVar)) {
|
||||
LocalVar local = (LocalVar) unaryExpr.expr;
|
||||
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(local.name));
|
||||
}
|
||||
@ -738,8 +733,8 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
|
||||
private void genBCForIncAndDec(Operation op, String typeOfUnary) {
|
||||
|
||||
getVlaueIns(typeOfUnary);
|
||||
doAssign(typeOfUnary, 1.0, true);
|
||||
doUnboxing(typeOfUnary);
|
||||
loadValue(typeOfUnary, 1.0, true);
|
||||
|
||||
switch (op) {
|
||||
case POSTDECREMENT:
|
||||
@ -759,22 +754,19 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(Return aReturn) {
|
||||
|
||||
statement = new ReturnStmt(aReturn.retexpr);
|
||||
|
||||
isBinaryExp = statement.isExprBinary();
|
||||
|
||||
aReturn.retexpr.accept(this);
|
||||
|
||||
if (isBinaryExp) {
|
||||
BinaryExpr binary = (BinaryExpr) aReturn.retexpr;
|
||||
String lexpType = getResolvedType(binary.lexpr.getType());
|
||||
String rexpType = getResolvedType(binary.rexpr.getType());
|
||||
getValueOfIns(getLargerType(lexpType, rexpType));
|
||||
doBoxing(getResolvedType(binary.getType()));
|
||||
isBinaryExp = false;
|
||||
}
|
||||
|
||||
mv.visitInsn(Opcodes.ARETURN);
|
||||
statement = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -787,7 +779,8 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
// mv.visitMethodInsn(Opcodes.INVOKESTATIC,
|
||||
// staticClassName.getType().toString().replace(".", "/"),
|
||||
// staticClassName.toString(), staticClassName.getType().toString(), false);
|
||||
//mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()), fieldName, fieldDesc);
|
||||
// mv.visitFieldInsn(Opcodes.GETSTATIC,
|
||||
// getResolvedType(staticClassName.getType()), fieldName, fieldDesc);
|
||||
throw new NotImplementedException("Static noch nicht implementiert!");
|
||||
}
|
||||
|
||||
@ -803,16 +796,11 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
|
||||
@Override
|
||||
public void visit(WhileStmt whileStmt) {
|
||||
|
||||
statement = new LoopStmt(whileStmt.expr, whileStmt.loopBlock);
|
||||
this.loopBlock = whileStmt.loopBlock;
|
||||
|
||||
|
||||
isBinaryExp = statement.isExprBinary();
|
||||
|
||||
whileStmt.expr.accept(this);
|
||||
|
||||
isBinaryExp = false;
|
||||
statement = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -825,12 +813,13 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
public void visit(Literal literal) {
|
||||
Object value = literal.value;
|
||||
String typeOfLiteral = getResolvedType(literal.getType());
|
||||
// Name der Methode muss geändert werden
|
||||
doAssign(typeOfLiteral, value, false);
|
||||
|
||||
// Der Wert des Literals wird auf den Stack geladen und
|
||||
// geboxt, wenn es nötig ist.
|
||||
loadValue(typeOfLiteral, value, false);
|
||||
}
|
||||
|
||||
private void getVlaueIns(String type) {
|
||||
// Unboxing: RefType -> prim
|
||||
private void doUnboxing(String type) {
|
||||
switch (type) {
|
||||
case "java/lang/String":
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
|
||||
@ -860,11 +849,13 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
case "java/lang/Character":
|
||||
break;
|
||||
default:
|
||||
// mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue",
|
||||
// "()I", false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void doAssign(String type, Object value, boolean isOperator) {
|
||||
private void loadValue(String type, Object value, boolean isOperator) {
|
||||
switch (type) {
|
||||
case "java/lang/String":
|
||||
mv.visitLdcInsn(String.valueOf(value));
|
||||
@ -895,17 +886,21 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
visitCharLiteral((Character) value);
|
||||
break;
|
||||
default:
|
||||
// wenn die Typ des Literals = Number ist, wird integer-value
|
||||
// verwendet
|
||||
// visitIntegerLiteral(((Double) value).intValue(), false);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!type.equals("java/lang/String")&&!type.equals("java/lang/Boolean")) {
|
||||
// Boxing
|
||||
if (!type.equals("java/lang/String") && !type.equals("java/lang/Boolean")) {
|
||||
if (!this.isBinaryExp && !isOperator)
|
||||
getValueOfIns(type);
|
||||
doBoxing(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void getValueOfIns(String type) {
|
||||
// Boxing: prim -> RefType
|
||||
private void doBoxing(String type) {
|
||||
switch (type) {
|
||||
case "java/lang/String":
|
||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
|
||||
@ -1019,6 +1014,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
for (Expression al : argumentList.getArguments()) {
|
||||
statement = new ArgumentExpr(al);
|
||||
al.accept(this);
|
||||
statement = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1042,9 +1038,9 @@ public class BytecodeGenMethod implements StatementVisitor {
|
||||
varsFunInterface.add(assignLeftSide.localVar.getType());
|
||||
int index = paramsAndLocals.size();
|
||||
String var = assignLeftSide.localVar.name;
|
||||
if(!paramsAndLocals.containsKey(var)) {
|
||||
if (!paramsAndLocals.containsKey(var)) {
|
||||
paramsAndLocals.put(var, index + 1);
|
||||
}else {
|
||||
} else {
|
||||
paramsAndLocals.put(var, index);
|
||||
}
|
||||
|
||||
|
@ -46,12 +46,18 @@ public class DescriptorToString implements DescriptorVisitor{
|
||||
}else if(method.getGenericsAndBounds().containsKey(fpDesc)){
|
||||
desc += "L"+method.getGenericsAndBounds().get(fpDesc)+ ";";
|
||||
}else {
|
||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
if(resType.subSequence(0, 4).equals("TPH ")) {
|
||||
desc += "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";";
|
||||
} else {
|
||||
desc += "L"+resType+ ";";
|
||||
}
|
||||
}
|
||||
}
|
||||
//TODO: generate a class java%% ... %%
|
||||
else if(resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()).contains("<")){
|
||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "%").replace("<", "%%").replace(">", "%%")+ ";";
|
||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "$$").replace("<", "$$$").replace(">", "$$$")+ ";";
|
||||
}
|
||||
else {
|
||||
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
@ -68,7 +74,12 @@ public class DescriptorToString implements DescriptorVisitor{
|
||||
}else if(method.getGenericsAndBounds().containsKey(ret)){
|
||||
desc += ")L"+method.getGenericsAndBounds().get(ret)+ ";";
|
||||
}else {
|
||||
desc += ")" + "L"+resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
String resType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||
if(resType.subSequence(0, 4).equals("TPH ")) {
|
||||
desc += ")" + "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";";
|
||||
} else {
|
||||
desc += ")" + "L"+resType+ ";";
|
||||
}
|
||||
}
|
||||
}else {
|
||||
desc += ")" + "L"+resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||
|
@ -13,6 +13,8 @@ public class TypeToDescriptor implements TypeVisitor<String>{
|
||||
@Override
|
||||
public String visit(RefType refType) {
|
||||
return refType.getName().toString().replace(".", "/");
|
||||
// String t = refType.getName().toString().replace(".", "/");
|
||||
// return t.equals("Fun1")?(t+"$$"):t;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -27,7 +29,8 @@ public class TypeToDescriptor implements TypeVisitor<String>{
|
||||
|
||||
@Override
|
||||
public String visit(ExtendsWildcardType extendsWildcardType) {
|
||||
throw new NotImplementedException();
|
||||
return extendsWildcardType.getInnerType().toString();
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -59,7 +59,7 @@ public class Signature {
|
||||
|
||||
private void createSignatureForFunN(LambdaExpression lambdaExpression, int numberOfParams) {
|
||||
|
||||
sw.visitClassBound().visitEnd();
|
||||
// sw.visitClassBound().visitEnd();
|
||||
for(int i = 0;i<numberOfParams;i++) {
|
||||
int j = i+1;
|
||||
sw.visitFormalTypeParameter("T"+ j);
|
||||
@ -92,7 +92,31 @@ public class Signature {
|
||||
GenericTypeVar g = itr.next();
|
||||
getBoundsOfTypeVar(g,genericsAndBoundsMethod);
|
||||
}
|
||||
// visits each method-parameter to create the signature
|
||||
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt
|
||||
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
|
||||
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||
if(ret.substring(0,4).equals("TPH ")) {
|
||||
String g = ret.substring(4)+"$";
|
||||
sw.visitFormalTypeParameter(g);
|
||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
||||
genericsAndBoundsMethod.put(g, Type.getInternalName(Object.class));
|
||||
sw.visitClassBound().visitEnd();
|
||||
}
|
||||
|
||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
|
||||
String pT = t.acceptTV(new TypeToSignature());
|
||||
// S.o
|
||||
if(pT.substring(0,4).equals("TPH ") && !genericsAndBoundsMethod.containsKey(pT)) {
|
||||
String gP = pT.substring(4)+"$";
|
||||
sw.visitFormalTypeParameter(gP);
|
||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
||||
genericsAndBoundsMethod.put(gP, Type.getInternalName(Object.class));
|
||||
sw.visitClassBound().visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// visit each method-parameter to create the signature
|
||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
|
||||
// parameter type deswegen ist true
|
||||
@ -101,6 +125,15 @@ public class Signature {
|
||||
if(isConstructor) {
|
||||
sw.visitReturnType().visitBaseType('V');
|
||||
}else {
|
||||
// String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||
// if(ret.substring(0,4).equals("TPH ")) {
|
||||
// String g = ret.substring(4);
|
||||
// if(!genericsAndBoundsMethod.containsKey(g)) {
|
||||
// genericsAndBoundsMethod.put(g, Type.getInternalName(Object.class));
|
||||
// } else {
|
||||
// genericsAndBoundsMethod.put(g+"_", Type.getInternalName(Object.class));
|
||||
// }
|
||||
// }
|
||||
RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType();
|
||||
// return type deswegen ist false
|
||||
doVisitParamsOrReturn(returnType, false);
|
||||
@ -132,10 +165,16 @@ public class Signature {
|
||||
break;
|
||||
case "TPH":
|
||||
RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
|
||||
if(!r.acceptTV(new TypeToSignature()).substring(0, 4).equals("TPH "))
|
||||
sv.visitInterface().visitClassType(r.acceptTV(new TypeToSignature()));
|
||||
// sv.visitClassType(r.acceptTV(new TypeToSignature()));
|
||||
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
|
||||
// der Fall wenn die Type eine Interface ist, muss betrachtet werden
|
||||
// Deswegen muss in ResutSet noch enthalten werden, ob die Type eine
|
||||
// Interface oder eine Klasse ist.
|
||||
if(!r.acceptTV(new TypeToSignature()).substring(0, 4).equals("TPH ")) {
|
||||
// sv.visitInterface().visitClassType(r.acceptTV(new TypeToSignature()));
|
||||
sv.visitClassType(r.acceptTV(new TypeToSignature()));
|
||||
} else {
|
||||
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
|
||||
sv.visitTypeVariable(r.acceptTV(new TypeToSignature()).substring(4)+"$");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(!isParameterType)
|
||||
|
@ -27,6 +27,8 @@ public class TypeToSignature implements TypeVisitor<String> {
|
||||
}
|
||||
params += ";>";
|
||||
}
|
||||
// String t = refType.getName().toString().replace(".", "/");
|
||||
// return t.equals("Fun1")?t+"$$"+params+";":t+params+";";
|
||||
return refType.getName().toString().replace(".", "/") + params+";";
|
||||
}
|
||||
|
||||
|
40
test/bytecode/BinaryTest.java
Normal file
40
test/bytecode/BinaryTest.java
Normal file
@ -0,0 +1,40 @@
|
||||
package bytecode;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
|
||||
public class BinaryTest {
|
||||
private static String path;
|
||||
private static File fileToTest;
|
||||
private static JavaTXCompiler compiler;
|
||||
private static ClassLoader loader;
|
||||
private static Class<?> classToTest;
|
||||
private static String pathToClassFile;
|
||||
private static Object instanceOfClass;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/BinaryInMeth.jav";
|
||||
fileToTest = new File(path);
|
||||
compiler = new JavaTXCompiler(fileToTest);
|
||||
compiler.generateBytecode();
|
||||
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||
classToTest = loader.loadClass("BinaryInMeth");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
fail("Not yet implemented");
|
||||
}
|
||||
|
||||
}
|
44
test/bytecode/FacTest.java
Normal file
44
test/bytecode/FacTest.java
Normal file
@ -0,0 +1,44 @@
|
||||
package bytecode;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
|
||||
public class FacTest {
|
||||
private static String path;
|
||||
private static File fileToTest;
|
||||
private static JavaTXCompiler compiler;
|
||||
private static ClassLoader loader;
|
||||
private static Class<?> classToTest;
|
||||
private static String pathToClassFile;
|
||||
private static Object instanceOfClass;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Fac.jav";
|
||||
fileToTest = new File(path);
|
||||
compiler = new JavaTXCompiler(fileToTest);
|
||||
compiler.generateBytecode();
|
||||
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||
classToTest = loader.loadClass("Fac");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||
Method getFac = classToTest.getDeclaredMethod("getFac", Integer.class,Integer.class);
|
||||
Integer result = (Integer) getFac.invoke(instanceOfClass,3);
|
||||
assertEquals(result, 6);
|
||||
}
|
||||
|
||||
}
|
@ -29,7 +29,7 @@ public class PlusTest {
|
||||
compiler = new JavaTXCompiler(fileToTest);
|
||||
compiler.generateBytecode();
|
||||
|
||||
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/examples/";
|
||||
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||
classToTest = loader.loadClass("Plus");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
|
44
test/bytecode/RelOpsTest.java
Normal file
44
test/bytecode/RelOpsTest.java
Normal file
@ -0,0 +1,44 @@
|
||||
package bytecode;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
|
||||
public class RelOpsTest {
|
||||
private static String path;
|
||||
private static File fileToTest;
|
||||
private static JavaTXCompiler compiler;
|
||||
private static ClassLoader loader;
|
||||
private static Class<?> classToTest;
|
||||
private static String pathToClassFile;
|
||||
private static Object instanceOfClass;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/RelOps.jav";
|
||||
fileToTest = new File(path);
|
||||
compiler = new JavaTXCompiler(fileToTest);
|
||||
compiler.generateBytecode();
|
||||
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||
classToTest = loader.loadClass("RelOps");
|
||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||
Method m = classToTest.getDeclaredMethod("m", Integer.class,Integer.class);
|
||||
Boolean result = (Boolean) m.invoke(instanceOfClass, 7,3);
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
}
|
11
test/bytecode/javFiles/BinaryInMeth.jav
Normal file
11
test/bytecode/javFiles/BinaryInMeth.jav
Normal file
@ -0,0 +1,11 @@
|
||||
import java.lang.Integer;
|
||||
public class BinaryInMeth {
|
||||
|
||||
m(a){
|
||||
return ++a;
|
||||
}
|
||||
|
||||
m2(a,b){
|
||||
return m(a+b);
|
||||
}
|
||||
}
|
16
test/bytecode/javFiles/Fac.jav
Normal file
16
test/bytecode/javFiles/Fac.jav
Normal file
@ -0,0 +1,16 @@
|
||||
import java.lang.Integer;
|
||||
import java.lang.Long;
|
||||
import java.lang.Double;
|
||||
|
||||
public class Fac {
|
||||
|
||||
getFac(n){
|
||||
var res = 1;
|
||||
var i = 1;
|
||||
while(i<=n) {
|
||||
res = res * i;
|
||||
i++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ import java.lang.Integer;
|
||||
import java.util.Vector;
|
||||
|
||||
public class Gen{
|
||||
Vector<? extends Integer> m(Vector<Integer> v){
|
||||
Vector<Integer> m(Vector<Integer> v){
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
@ -7,19 +7,19 @@ class Matrix extends Vector<Vector<Integer>> {
|
||||
var ret = new Matrix();
|
||||
var i = 0;
|
||||
while(i < size()) {
|
||||
var v1 = this.elementAt(i);
|
||||
var v2 = new Vector<Integer>();
|
||||
var j = 0;
|
||||
while(j < v1.size()) {
|
||||
var erg = 0;
|
||||
var k = 0;
|
||||
while(k < v1.size()) {
|
||||
erg = erg + v1.elementAt(k)
|
||||
* m.elementAt(k).elementAt(j);
|
||||
k++; }
|
||||
v2.addElement(new Integer(erg));
|
||||
j++; }
|
||||
ret.addElement(v2);
|
||||
// var v1 = this.elementAt(i);
|
||||
// var v2 = new Vector<Integer>();
|
||||
// var j = 0;
|
||||
// while(j < v1.size()) {
|
||||
// var erg = 0;
|
||||
// var k = 0;
|
||||
// while(k < v1.size()) {
|
||||
// erg = erg + v1.elementAt(k)
|
||||
// * m.elementAt(k).elementAt(j);
|
||||
// k++; }
|
||||
// v2.addElement(new Integer(erg));
|
||||
// j++; }
|
||||
// ret.addElement(v2);
|
||||
i++;
|
||||
}
|
||||
return ret;
|
||||
|
@ -9,7 +9,7 @@ import java.lang.Byte;
|
||||
|
||||
public class Op {
|
||||
|
||||
Integer m(Integer a, Integer b) {
|
||||
m(a, b) {
|
||||
//var c = a+b;
|
||||
return a+b;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import java.lang.Integer;
|
||||
//import java.lang.Integer;
|
||||
|
||||
public class Plus {
|
||||
|
||||
|
7
test/bytecode/javFiles/RelOps.jav
Normal file
7
test/bytecode/javFiles/RelOps.jav
Normal file
@ -0,0 +1,7 @@
|
||||
import java.lang.Integer;
|
||||
|
||||
public class RelOps {
|
||||
m(a,b){
|
||||
return a<b;
|
||||
}
|
||||
}
|
@ -1,4 +1,8 @@
|
||||
import java.lang.Integer;
|
||||
// wenn nur ein Import da steht,wird die Type von
|
||||
// dem Literal 2 Number berechnet => Deswegen kann
|
||||
// nicht auf den Stack geladen.
|
||||
//import java.lang.Long;
|
||||
|
||||
public class While {
|
||||
m(x) {
|
||||
|
107
test/logFiles/log
Normal file
107
test/logFiles/log
Normal file
@ -0,0 +1,107 @@
|
||||
FC:\{java.lang.Number=Elem: Node(java.lang.Number)
|
||||
Prec: [java.lang.Object, java.io.Serializable]
|
||||
Desc: [java.lang.Integer]
|
||||
|
||||
, java.lang.Comparable=Elem: Node(java.lang.Comparable)
|
||||
Prec: []
|
||||
Desc: [java.lang.Integer]
|
||||
|
||||
, java.lang.Comparable<BWE>=Elem: Node(java.lang.Comparable<BWE>)
|
||||
Prec: [java.lang.Object]
|
||||
Desc: []
|
||||
|
||||
, java.lang.Integer=Elem: Node(java.lang.Integer)
|
||||
Prec: [java.lang.Number, java.lang.Object, java.lang.Comparable, java.io.Serializable]
|
||||
Desc: []
|
||||
|
||||
, java.lang.Iterable<CWZ>=Elem: Node(java.lang.Iterable<CWZ>)
|
||||
Prec: [java.lang.Object]
|
||||
Desc: []
|
||||
|
||||
, java.lang.Iterable<CFZ>=Elem: Node(java.lang.Iterable<CFZ>)
|
||||
Prec: [java.lang.Object]
|
||||
Desc: []
|
||||
|
||||
, java.util.Collection=Elem: Node(java.util.Collection)
|
||||
Prec: []
|
||||
Desc: [java.util.AbstractList<BXU>, java.util.Vector<BXU>, java.util.List<BXU>, java.util.AbstractCollection<BXU>]
|
||||
|
||||
, java.util.AbstractCollection<BXU>=Elem: Node(java.util.AbstractCollection<BXU>)
|
||||
Prec: [java.lang.Object, java.util.Collection]
|
||||
Desc: [java.util.AbstractList<BXU>, java.util.Vector<BXU>]
|
||||
|
||||
, java.util.AbstractList<BXU>=Elem: Node(java.util.AbstractList<BXU>)
|
||||
Prec: [java.lang.Object, java.util.Collection, java.util.AbstractCollection<BXU>, java.util.List]
|
||||
Desc: [java.util.Vector<BXU>]
|
||||
|
||||
, java.lang.Cloneable=Elem: Node(java.lang.Cloneable)
|
||||
Prec: [java.lang.Object]
|
||||
Desc: [java.util.Vector<BXU>]
|
||||
|
||||
, java.lang.Comparable<BPP>=Elem: Node(java.lang.Comparable<BPP>)
|
||||
Prec: [java.lang.Object]
|
||||
Desc: []
|
||||
|
||||
, java.lang.Object=Elem: Node(java.lang.Object)
|
||||
Prec: [java.lang.Object]
|
||||
Desc: [java.lang.Number, java.lang.Comparable<BWE>, java.lang.Integer, java.lang.Iterable<CWZ>, java.lang.Iterable<CFZ>, java.util.AbstractCollection<BXU>, java.util.AbstractList<BXU>, java.lang.Cloneable, java.lang.Comparable<BPP>, Gen, java.lang.Object, java.util.Vector<BXU>, java.util.Collection<CMJ>, java.util.RandomAccess, java.util.Collection<CDW>, java.util.List<BXU>, java.io.Serializable, java.lang.Iterable<COM>, java.util.Collection<CUW>]
|
||||
|
||||
, java.util.Vector<BXU>=Elem: Node(java.util.Vector<BXU>)
|
||||
Prec: [java.util.AbstractList<BXU>, java.lang.Cloneable, java.lang.Object, java.util.Collection, java.util.RandomAccess, java.io.Serializable, java.util.AbstractCollection<BXU>, java.util.List]
|
||||
Desc: []
|
||||
|
||||
, Gen=Elem: Node(Gen)
|
||||
Prec: [java.lang.Object]
|
||||
Desc: []
|
||||
|
||||
, java.util.Collection<CMJ>=Elem: Node(java.util.Collection<CMJ>)
|
||||
Prec: [java.lang.Object, java.lang.Iterable]
|
||||
Desc: []
|
||||
|
||||
, java.util.RandomAccess=Elem: Node(java.util.RandomAccess)
|
||||
Prec: [java.lang.Object]
|
||||
Desc: [java.util.Vector<BXU>]
|
||||
|
||||
, java.util.List<BXU>=Elem: Node(java.util.List<BXU>)
|
||||
Prec: [java.lang.Object, java.util.Collection]
|
||||
Desc: []
|
||||
|
||||
, java.util.Collection<CDW>=Elem: Node(java.util.Collection<CDW>)
|
||||
Prec: [java.lang.Object, java.lang.Iterable]
|
||||
Desc: []
|
||||
|
||||
, java.io.Serializable=Elem: Node(java.io.Serializable)
|
||||
Prec: [java.lang.Object]
|
||||
Desc: [java.lang.Number, java.util.Vector<BXU>, java.lang.Integer]
|
||||
|
||||
, java.lang.Iterable<COM>=Elem: Node(java.lang.Iterable<COM>)
|
||||
Prec: [java.lang.Object]
|
||||
Desc: []
|
||||
|
||||
, java.lang.Iterable=Elem: Node(java.lang.Iterable)
|
||||
Prec: []
|
||||
Desc: [java.util.Collection<CMJ>, java.util.Collection<CDW>, java.util.Collection<CUW>]
|
||||
|
||||
, java.util.Collection<CUW>=Elem: Node(java.util.Collection<CUW>)
|
||||
Prec: [java.lang.Object, java.lang.Iterable]
|
||||
Desc: []
|
||||
|
||||
, java.util.List=Elem: Node(java.util.List)
|
||||
Prec: []
|
||||
Desc: [java.util.AbstractList<BXU>, java.util.Vector<BXU>]
|
||||
|
||||
}
|
||||
class Gen {
|
||||
|
||||
java.util.Vector<java.lang.Integer> m(java.util.Vector<java.lang.Integer> v)({
|
||||
return (v)::java.util.Vector<java.lang.Integer>;
|
||||
})::TPH K
|
||||
|
||||
Gen()({
|
||||
super(());
|
||||
})::TPH N
|
||||
|
||||
}Unifikation: [(java.util.Vector<java.lang.Integer> <. java.util.Vector<java.lang.Integer>, )]
|
||||
Unifikation: []
|
||||
[]
|
||||
RES: []
|
Loading…
Reference in New Issue
Block a user