From 3c36c6107797c3c14e23619b96b6b3aa18259bd7 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Thu, 13 Jun 2019 14:01:32 +0200 Subject: [PATCH] Fixed Bugs 159, 162 and 163 --- .../bytecode/BytecodeGenMethod.java | 43 +++++++++----- .../bytecode/utilities/MethodCallHelper.java | 56 ++++++++++++++++--- src/test/resources/bytecode/javFiles/Id.jav | 10 +++- src/test/resources/bytecode/javFiles/OL.jav | 15 ++--- 4 files changed, 93 insertions(+), 31 deletions(-) diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index 02169d6ae..a91e201a6 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -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; diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodCallHelper.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodCallHelper.java index be57376b8..ceb72fa0c 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodCallHelper.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodCallHelper.java @@ -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 params = getTypes(methCall.arglist.getArguments()); + Map genAndBoundsClass = getGenericsAndBounds(clazz.getGenerics()); modifyGenAndBounds(genAndBoundsClass); for (Method m : clazz.getMethods()) { - if (name.equals(m.getName())) { - Map genAndBoundsMethod = getGenericsAndBoundsMethod(m.getGenerics()); - modifyGenAndBounds(genAndBoundsMethod); - boolean hasGen = hasGen(m, genAndBoundsClass); - NormalMethod nm = new NormalMethod(m, (HashMap) genAndBoundsClass, - (HashMap) genAndBoundsMethod, hasGen); - return nm.accept(new DescriptorToString(resultSet)); + if (name.equals(m.getName()) && retType.equals(getResolvedType(m.getReturnType()))) { + ArrayList paramsOfM = getTypes(m.getParameterList()); + if(areEquals(params,paramsOfM)) { + Map genAndBoundsMethod = getGenericsAndBoundsMethod(m.getGenerics()); + modifyGenAndBounds(genAndBoundsMethod); + boolean hasGen = hasGen(m, genAndBoundsClass); + NormalMethod nm = new NormalMethod(m, (HashMap) genAndBoundsClass, + (HashMap) genAndBoundsMethod, hasGen); + return nm.accept(new DescriptorToString(resultSet)); + } } } throw new NotFoundException("Method " + name + " is not found"); } + private boolean areEquals(ArrayList params, ArrayList 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 getTypes(ParameterList parameterList) { + Iterator itr = parameterList.iterator(); + ArrayList typeList = new ArrayList<>(); + while (itr.hasNext()) { + FormalParameter fp = itr.next(); + String t = getResolvedType(fp.getType()); + typeList.add(t); + } + + return typeList; + } + + private ArrayList getTypes(List arguments) { + ArrayList types = new ArrayList<>(); + for(int i = 0; i genericsAndBounds) { String retType = resultSet.resolveType(m.getReturnType()).resolvedType.acceptTV(new TypeToSignature()); /*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/ diff --git a/src/test/resources/bytecode/javFiles/Id.jav b/src/test/resources/bytecode/javFiles/Id.jav index 5f84acc58..081832aa0 100644 --- a/src/test/resources/bytecode/javFiles/Id.jav +++ b/src/test/resources/bytecode/javFiles/Id.jav @@ -1,7 +1,11 @@ public class Id { - id(b){ - return b; - } +// id(b){ +// return b; +// } + id2 = x -> x; + + id3 (x) { + return id2.apply(x) } diff --git a/src/test/resources/bytecode/javFiles/OL.jav b/src/test/resources/bytecode/javFiles/OL.jav index 0861b4df1..da049d244 100644 --- a/src/test/resources/bytecode/javFiles/OL.jav +++ b/src/test/resources/bytecode/javFiles/OL.jav @@ -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 {