Fixed Bugs 159, 162 and 163

This commit is contained in:
Fayez Abu Alia 2019-06-13 14:01:32 +02:00
parent 857d63322e
commit 3c36c61077
4 changed files with 93 additions and 31 deletions

View File

@ -248,6 +248,10 @@ public class BytecodeGenMethod implements StatementVisitor {
} else { } else {
assign.rightSide.accept(this); assign.rightSide.accept(this);
} }
statement = new AssignStmt(assign.rightSide);
isBinaryExp = statement.isExprBinary();
if (isBinaryExp) { if (isBinaryExp) {
BinaryExpr binary = (BinaryExpr) assign.rightSide; BinaryExpr binary = (BinaryExpr) assign.rightSide;
String binaryType = getResolvedType(binary.getType()); String binaryType = getResolvedType(binary.getType());
@ -291,6 +295,11 @@ public class BytecodeGenMethod implements StatementVisitor {
binary.lexpr.accept(this); binary.lexpr.accept(this);
if(lexpType.equals(Type.getInternalName(String.class))) {
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
}
if (!lexpType.equals(rexpType) && !lexpType.equals(largerType)) if (!lexpType.equals(rexpType) && !lexpType.equals(largerType))
doCast(lexpType, largerType); doCast(lexpType, largerType);
@ -298,7 +307,10 @@ public class BytecodeGenMethod implements StatementVisitor {
needDUP = true; needDUP = true;
binary.rexpr.accept(this); binary.rexpr.accept(this);
if(rexpType.equals(Type.getInternalName(String.class))) {
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
}
isParentBinary = false; isParentBinary = false;
if (!lexpType.equals(rexpType) && !rexpType.equals(largerType)) if (!lexpType.equals(rexpType) && !rexpType.equals(largerType))
@ -383,7 +395,7 @@ public class BytecodeGenMethod implements StatementVisitor {
mv.visitInsn(Opcodes.I2F); mv.visitInsn(Opcodes.I2F);
} }
break; break;
// braucht man eigentlic nicht, muss getestet werden // braucht man eigentlich nicht, muss getestet werden
case "java/lang/String": case "java/lang/String":
if (sourceType.equals(Type.getInternalName(Double.class))) { if (sourceType.equals(Type.getInternalName(Double.class))) {
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf", mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
@ -566,6 +578,10 @@ public class BytecodeGenMethod implements StatementVisitor {
case "java/lang/Float": case "java/lang/Float":
mv.visitInsn(Opcodes.FADD); mv.visitInsn(Opcodes.FADD);
break; break;
case "java/lang/String":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
false);
break;
default: default:
break; break;
} }
@ -905,14 +921,15 @@ public class BytecodeGenMethod implements StatementVisitor {
mDesc, isInterface); mDesc, isInterface);
} }
// TODO: if called method is apply (from FI) then generate BC-instruction "CHECKCAST"
if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) { if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) {
if(methodRefl.getReturnType().equals(Object.class)) { if(methodRefl.getReturnType().equals(Object.class)) {
helper.createCheckCast(methodCall,mv); helper.createCheckCast(methodCall,mv);
} }
if(isBinaryExp) if(isBinaryExp) {
doUnboxing(getResolvedType(methodCall.getType())); doUnboxing(getResolvedType(methodCall.getType()));
}
} else if(receiverName.contains("$$") && !methCallType.equals(Type.getInternalName(Object.class))) { } else if(receiverName.contains("$$") && !methCallType.equals(Type.getInternalName(Object.class))) {
helper.createCheckCast(methodCall,mv); helper.createCheckCast(methodCall,mv);
} }
@ -1229,11 +1246,11 @@ public class BytecodeGenMethod implements StatementVisitor {
// Unboxing: RefType -> prim // Unboxing: RefType -> prim
public void doUnboxing(String type) { public void doUnboxing(String type) {
switch (type) { switch (type) {
case "java/lang/String": // case "java/lang/String":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append", // mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); // "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
//
break; // break;
case "java/lang/Boolean": case "java/lang/Boolean":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
break; break;
@ -1330,10 +1347,10 @@ public class BytecodeGenMethod implements StatementVisitor {
// Boxing: prim -> RefType // Boxing: prim -> RefType
public void doBoxing(String type) { public void doBoxing(String type) {
switch (type) { switch (type) {
case "java/lang/String": // case "java/lang/String":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", // mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
false); // false);
break; // break;
case "java/lang/Boolean": case "java/lang/Boolean":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
break; break;

View File

@ -32,6 +32,7 @@ import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.statement.Expression; import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
@ -98,11 +99,15 @@ public class MethodCallHelper {
public String getDesc(String className) throws NotInCurrentPackageException, NotFoundException { public String getDesc(String className) throws NotInCurrentPackageException, NotFoundException {
String name = methCall.name; String name = methCall.name;
ClassOrInterface clazz = getClassFromCurrPkg(className); ClassOrInterface clazz = getClassFromCurrPkg(className);
String retType = getResolvedType(methCall.getType());
ArrayList<String> params = getTypes(methCall.arglist.getArguments());
Map<String, String> genAndBoundsClass = getGenericsAndBounds(clazz.getGenerics()); Map<String, String> genAndBoundsClass = getGenericsAndBounds(clazz.getGenerics());
modifyGenAndBounds(genAndBoundsClass); modifyGenAndBounds(genAndBoundsClass);
for (Method m : clazz.getMethods()) { for (Method m : clazz.getMethods()) {
if (name.equals(m.getName())) { if (name.equals(m.getName()) && retType.equals(getResolvedType(m.getReturnType()))) {
ArrayList<String> paramsOfM = getTypes(m.getParameterList());
if(areEquals(params,paramsOfM)) {
Map<String, String> genAndBoundsMethod = getGenericsAndBoundsMethod(m.getGenerics()); Map<String, String> genAndBoundsMethod = getGenericsAndBoundsMethod(m.getGenerics());
modifyGenAndBounds(genAndBoundsMethod); modifyGenAndBounds(genAndBoundsMethod);
boolean hasGen = hasGen(m, genAndBoundsClass); boolean hasGen = hasGen(m, genAndBoundsClass);
@ -111,10 +116,45 @@ public class MethodCallHelper {
return nm.accept(new DescriptorToString(resultSet)); return nm.accept(new DescriptorToString(resultSet));
} }
} }
}
throw new NotFoundException("Method " + name + " is not found"); throw new NotFoundException("Method " + name + " is not found");
} }
private boolean areEquals(ArrayList<String> params, ArrayList<String> paramsOfM) {
if(params.size() != paramsOfM.size())
return false;
for(String t : params) {
for(String t2 : paramsOfM) {
if(!t.equals(t2))
return false;
}
}
return true;
}
private ArrayList<String> getTypes(ParameterList parameterList) {
Iterator<FormalParameter> itr = parameterList.iterator();
ArrayList<String> typeList = new ArrayList<>();
while (itr.hasNext()) {
FormalParameter fp = itr.next();
String t = getResolvedType(fp.getType());
typeList.add(t);
}
return typeList;
}
private ArrayList<String> getTypes(List<Expression> arguments) {
ArrayList<String> types = new ArrayList<>();
for(int i = 0; i<arguments.size(); ++i) {
String t = getResolvedType(arguments.get(i).getType());
types.add(t);
}
return types;
}
private boolean hasGen(Method m, Map<String, String> genericsAndBounds) { private boolean hasGen(Method m, Map<String, String> genericsAndBounds) {
String retType = resultSet.resolveType(m.getReturnType()).resolvedType.acceptTV(new TypeToSignature()); String retType = resultSet.resolveType(m.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
/*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/ /*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/

View File

@ -1,7 +1,11 @@
public class Id { public class Id {
id(b){ // id(b){
return b; // return b;
} // }
id2 = x -> x;
id3 (x) {
return id2.apply(x)
} }

View File

@ -2,22 +2,23 @@ import java.lang.String;
import java.lang.Integer; import java.lang.Integer;
import java.lang.Double; import java.lang.Double;
import java.lang.Boolean; import java.lang.Boolean;
import java.util.Vector;
public class OL { public class OL {
m(x) { return x + x; } m(x) { return x + x; }
/*
m(Boolean x) { return x; } m(Boolean x) { return x; }
// if the class contains just this method, then correct BC will be generated.
m(x) { // But if another methods are contained then the generated BC is not correct
x.add(1); /* m(x) {
//x.add(1);
x.addAll(x); x.addAll(x);
return x; return x;
} }
*/ */
} }
public class OLMain { public class OLMain {