From 0194e302064b1a81bf0c341b60fa4ff59749d6c5 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 26 Jun 2019 12:16:47 +0200 Subject: [PATCH] Fixed Bug 150. --- .../bytecode/ArgumentVisitor.java | 24 ++++---- .../dhbwstuttgart/bytecode/BytecodeGen.java | 4 +- .../bytecode/BytecodeGenMethod.java | 58 ++++++++++--------- .../dhbwstuttgart/bytecode/TPHExtractor.java | 11 +++- .../bytecode/utilities/MethodAndTPH.java | 8 +-- .../bytecode/utilities/MethodUtility.java | 34 +++++++++++ .../bytecode/utilities/Resolver.java | 28 +++++++++ .../bytecode/utilities/Simplify.java | 8 ++- src/test/resources/bytecode/javFiles/OL.jav | 4 +- 9 files changed, 129 insertions(+), 50 deletions(-) create mode 100644 src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodUtility.java create mode 100644 src/main/java/de/dhbwstuttgart/bytecode/utilities/Resolver.java diff --git a/src/main/java/de/dhbwstuttgart/bytecode/ArgumentVisitor.java b/src/main/java/de/dhbwstuttgart/bytecode/ArgumentVisitor.java index 87c730adb..268e53b59 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/ArgumentVisitor.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/ArgumentVisitor.java @@ -61,7 +61,7 @@ public class ArgumentVisitor implements StatementVisitor { assign.accept(bytecodeGenMethod); if(argListMethCall.get(0)) - bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(assign.getType())); + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(assign.getType())); argListMethCall.remove(0); } @@ -70,9 +70,9 @@ public class ArgumentVisitor implements StatementVisitor { binary.accept(bytecodeGenMethod); if(argListMethCall.get(0)) { - bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(binary.getType())); + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(binary.getType())); } else { - bytecodeGenMethod.doBoxing(bytecodeGenMethod.getResolvedType(binary.getType())); + bytecodeGenMethod.doBoxing(bytecodeGenMethod.getResolver().getResolvedType(binary.getType())); } argListMethCall.remove(0); } @@ -88,7 +88,7 @@ public class ArgumentVisitor implements StatementVisitor { castExpr.accept(bytecodeGenMethod); if(argListMethCall.get(0)) - bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(castExpr.getType())); + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(castExpr.getType())); argListMethCall.remove(0); } @@ -103,7 +103,7 @@ public class ArgumentVisitor implements StatementVisitor { fieldVar.accept(bytecodeGenMethod); if(argListMethCall.get(0)) - bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(fieldVar.getType())); + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(fieldVar.getType())); argListMethCall.remove(0); } @@ -124,7 +124,7 @@ public class ArgumentVisitor implements StatementVisitor { instanceOf.accept(bytecodeGenMethod); if(argListMethCall.get(0)) - bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(instanceOf.getType())); + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(instanceOf.getType())); argListMethCall.remove(0); } @@ -133,7 +133,7 @@ public class ArgumentVisitor implements StatementVisitor { localVar.accept(bytecodeGenMethod); if(!bytecodeGenMethod.isBinaryExp) { if(argListMethCall.get(0)) - bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(localVar.getType())); + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(localVar.getType())); } argListMethCall.remove(0); } @@ -149,7 +149,7 @@ public class ArgumentVisitor implements StatementVisitor { methodCall.accept(bytecodeGenMethod); if(argListMethCall.get(0)) - bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(methodCall.getType())); + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(methodCall.getType())); argListMethCall.remove(0); } @@ -158,7 +158,7 @@ public class ArgumentVisitor implements StatementVisitor { methodCall.accept(bytecodeGenMethod); if(argListMethCall.get(0)) - bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(methodCall.getType())); + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(methodCall.getType())); argListMethCall.remove(0); } @@ -197,7 +197,7 @@ public class ArgumentVisitor implements StatementVisitor { aThis.accept(bytecodeGenMethod); if(argListMethCall.get(0)) - bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(aThis.getType())); + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(aThis.getType())); argListMethCall.remove(0); } @@ -242,7 +242,7 @@ public class ArgumentVisitor implements StatementVisitor { unaryExpr.accept(bytecodeGenMethod); if(argListMethCall.get(0)) - bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(unaryExpr.getType())); + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(unaryExpr.getType())); argListMethCall.remove(0); } @@ -251,7 +251,7 @@ public class ArgumentVisitor implements StatementVisitor { literal.accept(bytecodeGenMethod); if(argListMethCall.get(0)) - bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(literal.getType())); + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(literal.getType())); argListMethCall.remove(0); } diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java index f89f7bbc7..767bfcc58 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -353,7 +353,7 @@ public class BytecodeGen implements ASTVisitor { } String sig = null; if (hasGen) { - HashMap> constraints = Simplify.simplifyConstraints(field.name, tphExtractor, + HashMap> constraints = Simplify.simplifyConstraints(field, tphExtractor, tphsClass); Signature signature = new Signature(field, genericsAndBounds, methodParamsAndTypes, resultSet, constraints); sig = signature.toString(); @@ -446,7 +446,7 @@ public class BytecodeGen implements ASTVisitor { System.out.println("ALL CONST: " + tphExtractor.allCons.size()); tphExtractor.allCons.forEach(c -> System.out.println(c.toString())); System.out.println("----------------"); - HashMap> constraints = Simplify.simplifyConstraints(method.name, + HashMap> constraints = Simplify.simplifyConstraints(method, tphExtractor, tphsClass); // ArrayList pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons); Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds, diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index a91e201a6..b2699cd4a 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -42,6 +42,7 @@ import de.dhbwstuttgart.bytecode.utilities.KindOfLambda; import de.dhbwstuttgart.bytecode.utilities.Lambda; import de.dhbwstuttgart.bytecode.utilities.MethodCallHelper; import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall; +import de.dhbwstuttgart.bytecode.utilities.Resolver; import de.dhbwstuttgart.bytecode.utilities.SamMethod; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; @@ -58,6 +59,7 @@ import javassist.NotFoundException; public class BytecodeGenMethod implements StatementVisitor { + private Resolver resolver; private Method m; private MethodVisitor mv; private HashMap paramsAndLocals = new HashMap<>(); @@ -101,6 +103,7 @@ public class BytecodeGenMethod implements StatementVisitor { this.className = className; this.superClass = superClass; this.resultSet = resultSet; + this.resolver = new Resolver(resultSet); this.m = m; this.mv = mv; this.paramsAndLocals = paramsAndLocals; @@ -126,6 +129,7 @@ public class BytecodeGenMethod implements StatementVisitor { this.className = className; this.superClass = superClass; this.resultSet = resultSet; + this.resolver = new Resolver(resultSet); this.m = m; this.mv = mv; this.paramsAndLocals = paramsAndLocals; @@ -147,6 +151,7 @@ public class BytecodeGenMethod implements StatementVisitor { HashMap genericsAndBounds) { this.resultSet = resultSet; + this.resolver = new Resolver(resultSet); this.mv = mv; this.isInterface = isInterface; this.classFiles = classFiles; @@ -172,20 +177,21 @@ public class BytecodeGenMethod implements StatementVisitor { lambdaExpression.methodBody.accept(this); } + public Resolver getResolver() { + return resolver; + } + public void isBinary(boolean isBinary) { this.isBinaryExp =isBinary; } - public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) { - return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor()); - } @Override public void visit(Block block) { for (Statement stmt : block.getStatements()) { stmt.accept(this); if(stmt instanceof MethodCall) { - String ret = getResolvedType(((MethodCall) stmt).getType()); + String ret = resolver.getResolvedType(((MethodCall) stmt).getType()); if(!ret.equals("void")) mv.visitInsn(Opcodes.POP); } @@ -220,7 +226,7 @@ public class BytecodeGenMethod implements StatementVisitor { mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name)); if (isBinaryExp) { - doUnboxing(getResolvedType(localVar.getType())); + doUnboxing(resolver.getResolvedType(localVar.getType())); } } @@ -254,13 +260,13 @@ public class BytecodeGenMethod implements StatementVisitor { if (isBinaryExp) { BinaryExpr binary = (BinaryExpr) assign.rightSide; - String binaryType = getResolvedType(binary.getType()); + String binaryType = resolver.getResolvedType(binary.getType()); doBoxing(binaryType); isBinaryExp = false; } - System.out.println("ASSIGN TYPE R: " + getResolvedType(assign.rightSide.getType())); - String typeOfRightSide = getResolvedType(assign.rightSide.getType()); + System.out.println("ASSIGN TYPE R: " + resolver.getResolvedType(assign.rightSide.getType())); + String typeOfRightSide = resolver.getResolvedType(assign.rightSide.getType()); if(typeOfRightSide.contains("<")) { mv.visitTypeInsn(Opcodes.CHECKCAST, typeOfRightSide.substring(0, typeOfRightSide.indexOf('<'))); } @@ -272,11 +278,11 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(BinaryExpr binary) { isParentBinary = true; - String lexpType = getResolvedType(binary.lexpr.getType()); - String rexpType = getResolvedType(binary.rexpr.getType()); + String lexpType = resolver.getResolvedType(binary.lexpr.getType()); + String rexpType = resolver.getResolvedType(binary.rexpr.getType()); String largerType = getLargerType(lexpType, rexpType); - String typeOfBinary = getResolvedType(binary.getType()); + String typeOfBinary = resolver.getResolvedType(binary.getType()); if (typeOfBinary.equals(Type.getInternalName(String.class))) { mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class)); @@ -649,7 +655,7 @@ public class BytecodeGenMethod implements StatementVisitor { } for(int i=pos;i " + parentBinary); if(methodRefl == null && (parentBinary || !isReturnStmt)) { if(isBinaryExp) - doUnboxing(getResolvedType(methodCall.getType())); + doUnboxing(resolver.getResolvedType(methodCall.getType())); } } @@ -958,7 +964,7 @@ public class BytecodeGenMethod implements StatementVisitor { private String[] getTypes(List arguments) { String[] types = new String[arguments.size()]; for(int i = 0; i "+ typeOfLiteral); // Der Wert des Literals wird auf den Stack geladen und // geboxt, wenn es nötig ist. @@ -1467,7 +1473,7 @@ public class BytecodeGenMethod implements StatementVisitor { //TODO: teste, ob man das für unary braucht if (isBinaryExp) { BinaryExpr binary = (BinaryExpr) al; - String binaryType = getResolvedType(binary.getType()); + String binaryType = resolver.getResolvedType(binary.getType()); doBoxing(binaryType); } statement = null; @@ -1493,8 +1499,8 @@ public class BytecodeGenMethod implements StatementVisitor { fDesc +=";"; - System.out.println("Receiver = " + getResolvedType(assignLeftSide.field.receiver.getType())); - mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()), + System.out.println("Receiver = " + resolver.getResolvedType(assignLeftSide.field.receiver.getType())); + mv.visitFieldInsn(Opcodes.PUTFIELD, resolver.getResolvedType(assignLeftSide.field.receiver.getType()), assignLeftSide.field.fieldVarName, fDesc); } diff --git a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java index 66723205c..2ef7d9572 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java @@ -15,6 +15,8 @@ import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; +import de.dhbwstuttgart.bytecode.utilities.MethodUtility; +import de.dhbwstuttgart.bytecode.utilities.Resolver; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.Field; @@ -48,6 +50,7 @@ public class TPHExtractor extends AbstractASTWalker { final ArrayList> allPairs = new ArrayList<>(); public final ArrayList allCons = new ArrayList<>(); private ResultSet resultSet; + private Resolver resolver; public TPHExtractor() { @@ -55,6 +58,11 @@ public class TPHExtractor extends AbstractASTWalker { public void setResultSet(ResultSet resultSet) { this.resultSet = resultSet; + this.resolver = new Resolver(resultSet); + } + + public Resolver getResolver() { + return resolver; } @Override @@ -153,7 +161,8 @@ public class TPHExtractor extends AbstractASTWalker { @Override public void visit(Method method) { inMethod = true; - methodAndTph = new MethodAndTPH(method.name); + String id = MethodUtility.createID(resolver,method); + methodAndTph = new MethodAndTPH(id); super.visit(method); inMethod = false; ListOfMethodsAndTph.add(methodAndTph); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java index c2c0210e5..d8eed39cb 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java @@ -9,7 +9,7 @@ import de.dhbwstuttgart.typeinference.result.ResultPair; public class MethodAndTPH { - private String name; + private String id; private final ArrayList tphs = new ArrayList<>(); //private final ArrayList pairs = new ArrayList<>(); private final ArrayList> pairs = new ArrayList<>(); @@ -17,7 +17,7 @@ public class MethodAndTPH { private final ArrayList localTphs = new ArrayList<>(); public MethodAndTPH(String name) { - this.name = name; + this.id = name; } public ArrayList getTphs() { @@ -31,8 +31,8 @@ public class MethodAndTPH { return pairs; } - public String getName() { - return name; + public String getId() { + return id; } public ArrayList getLocalTphs() { diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodUtility.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodUtility.java new file mode 100644 index 000000000..6a84e97c1 --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodUtility.java @@ -0,0 +1,34 @@ +/** + * + */ +package de.dhbwstuttgart.bytecode.utilities; + +import java.util.Iterator; + +import de.dhbwstuttgart.syntaxtree.FormalParameter; +import de.dhbwstuttgart.syntaxtree.Method; + +/** + * @author fayez + * + */ +public class MethodUtility { + /** + * Creates an ID for a method + * + * @param resolver type Resolver + * @param method for which the ID will be generated + * @return ID for the given method. + * ID = ReturntypeMethodname(Parametertypes) + */ + public static String createID(Resolver resolver, Method method) { + String id = resolver.getResolvedType(method.getReturnType()) + method.name + "("; + Iterator itr = method.getParameterList().iterator(); + while (itr.hasNext()) { + FormalParameter fp = itr.next(); + id += resolver.getResolvedType(fp.getType()); + } + id += ")"; + return id; + } +} diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Resolver.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Resolver.java new file mode 100644 index 000000000..f581b3745 --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Resolver.java @@ -0,0 +1,28 @@ +/** + * + */ +package de.dhbwstuttgart.bytecode.utilities; + +import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.typeinference.result.ResultSet; + +/** + * @author fayez + * + */ +public class Resolver { + + private ResultSet resultSet; + + /** + * @param resultSet + */ + public Resolver(ResultSet resultSet) { + this.resultSet = resultSet; + } + + public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) { + return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor()); + } +} diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java index 2a4a3bd29..a88e07409 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java @@ -14,11 +14,12 @@ import de.dhbwstuttgart.bytecode.constraint.EqualConstraint; import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; +import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; public class Simplify { - public static HashMap> simplifyConstraints(String name, TPHExtractor tphExtractor, + public static HashMap> simplifyConstraints(Method method, TPHExtractor tphExtractor, ArrayList tphsClass) { // 1. check if there are any simple cycles like L set L=R and: @@ -44,12 +45,13 @@ public class Simplify { } } ArrayList consToRemove = new ArrayList<>(); - + + String id = MethodUtility.createID(tphExtractor.getResolver(), method); // get all tph of the method ArrayList methodTphs = new ArrayList<>(); ArrayList localTphs = new ArrayList<>(); for (MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) { - if (m.getName().equals(name)) { + if (m.getId().equals(id)) { methodTphs = m.getTphs(); localTphs = m.getLocalTphs(); break; diff --git a/src/test/resources/bytecode/javFiles/OL.jav b/src/test/resources/bytecode/javFiles/OL.jav index da049d244..ec5f9ab5a 100644 --- a/src/test/resources/bytecode/javFiles/OL.jav +++ b/src/test/resources/bytecode/javFiles/OL.jav @@ -13,12 +13,12 @@ public class OL { // 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) { + m(x) { //x.add(1); x.addAll(x); return x; } -*/ + } public class OLMain {