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

View File

@ -32,6 +32,7 @@ import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
@ -98,23 +99,62 @@ public class MethodCallHelper {
public String getDesc(String className) throws NotInCurrentPackageException, NotFoundException {
String name = methCall.name;
ClassOrInterface clazz = getClassFromCurrPkg(className);
String retType = getResolvedType(methCall.getType());
ArrayList<String> params = getTypes(methCall.arglist.getArguments());
Map<String, String> genAndBoundsClass = getGenericsAndBounds(clazz.getGenerics());
modifyGenAndBounds(genAndBoundsClass);
for (Method m : clazz.getMethods()) {
if (name.equals(m.getName())) {
Map<String, String> genAndBoundsMethod = getGenericsAndBoundsMethod(m.getGenerics());
modifyGenAndBounds(genAndBoundsMethod);
boolean hasGen = hasGen(m, genAndBoundsClass);
NormalMethod nm = new NormalMethod(m, (HashMap<String, String>) genAndBoundsClass,
(HashMap<String, String>) genAndBoundsMethod, hasGen);
return nm.accept(new DescriptorToString(resultSet));
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());
modifyGenAndBounds(genAndBoundsMethod);
boolean hasGen = hasGen(m, genAndBoundsClass);
NormalMethod nm = new NormalMethod(m, (HashMap<String, String>) genAndBoundsClass,
(HashMap<String, String>) genAndBoundsMethod, hasGen);
return nm.accept(new DescriptorToString(resultSet));
}
}
}
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) {
String retType = resultSet.resolveType(m.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
/*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/

View File

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

View File

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