From b4c604e2b172e10c3323b10a8d35abefac5f3676 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 27 Jun 2018 14:49:22 +0200 Subject: [PATCH] =?UTF-8?q?Bug=20in=20der=20Methode=20simplifyPairs=20gefi?= =?UTF-8?q?xt.=20Bug=2082=20gefixt.=20TPHs=20in=20paramtrisierten=20Typen?= =?UTF-8?q?=20als=20TypeVariablen=20in=20Signature=20hinzugef=C3=BCgt.=20L?= =?UTF-8?q?ambda.jav=20funktioniert.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/de/dhbwstuttgart/.DS_Store | Bin 6148 -> 6148 bytes .../dhbwstuttgart/bytecode/BytecodeGen.java | 40 ++++- .../bytecode/BytecodeGenMethod.java | 13 ++ .../descriptor/DescriptorToString.java | 33 +++- .../bytecode/signature/Signature.java | 143 +++++++++++++++++- .../bytecode/signature/TypeToSignature.java | 7 +- test/bytecode/javFiles/Lambda.jav | 5 +- test/bytecode/javFiles/Matrix.jav | 12 +- 8 files changed, 230 insertions(+), 23 deletions(-) diff --git a/src/de/dhbwstuttgart/.DS_Store b/src/de/dhbwstuttgart/.DS_Store index f20299e87666851977a6b404d3ad84ba10b1fb67..aa8a1074b6c8b435c3b9b58fbf5afc60d45b908c 100644 GIT binary patch delta 358 zcmZoMXfc=|#>B)qu~2NHo}wr-0|Nsi1A_nqLo!1?LkdG`Qh9N~#*NDv>p?Oc3`q=? z3?&Sy$g)W}`AI;z6G;U*nZ+dr2G<#xm|0la*f}`3IJkJZVuLgC%Y#c2OG=BK5{sfi zynw`#j3g*KBtJg~&Q44U%St+BQ3j~ZnZ-N0ol!j3=C-x}FV)(QyxF|0tKQA4qigDw{Yb=}DIruq%;kI$(cjn3b ZBDx|V?I0r?AT-$Y%^@Nim?t){008kdTL1t6 delta 94 zcmZoMXfc=|#>CJzu~2NHo}wrt0|NsP3otMwGvqU*Fr=mwC+AEoRG%!sEIOHknP;;J t^JSLJ4$K`)o7p+|Ie;2B8!~@qp3E simplifyPairs(String methodName, ArrayList allPairs) { + allPairs.forEach(p->System.out.print(p.TA1 + " < "+ p.TA2+ " ; ")); + + if(allPairs.size() < 2) + return allPairs; + ArrayList simplifiedPairs = new ArrayList<>(); MethodAndTPH method; @@ -320,22 +325,41 @@ public class BytecodeGen implements ASTVisitor { numOfVisitedPairs++; } - // TODO: teste noch den Fall X < Y und Y nicht in TPHS der Methode - // Dann hat man nach der While-Schleife X < Y - // Y muss durch Object ersetzt. - // Subtype TypePlaceholder subTphRes = tphsInRel.get(0); // Die größte Supertype TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1); + + while(subAndSuperTph.containsValue(subTphRes)) { + for(TypePlaceholder tph : subAndSuperTph.keySet()) { + if(methodTphs.contains(tph) && subAndSuperTph.get(tph).equals(subTphRes)) { + subTphRes = tph; + break; + } + } + if(subTphRes.equals(tphsInRel.get(0))) { + break; + } + tphsInRel.put(0, subTphRes); + numOfVisitedPairs++; + } + + subTphRes = tphsInRel.get(0); + int i = 2; while(!methodTphs.contains(superTphRes) && (tphsInRel.size()-i) >0) { superTphRes = tphsInRel.get(tphsInRel.size()-i); i++; } + // teste noch den Fall X < Y und Y nicht in TPHS der Methode + // Dann hat man nach der While-Schleife X < Y + // Y muss durch Object ersetzt. - GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes); - simplifiedPairs.add(sPair); + // Zweite Operand für die Fälle wie in Lambda.jav (Paramtrisierte Typen) + if(methodTphs.contains(superTphRes) || !tphExtractor.allTPHS.containsKey(superTphRes)) { + GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes); + simplifiedPairs.add(sPair); + } } return simplifiedPairs; } @@ -599,7 +623,6 @@ public class BytecodeGen implements ASTVisitor { methodAndTph.getTphs().add(resolvedTPH); allTPHS.put(resolvedTPH,inMethod); - ResolvedType rst = resultSet.resolveType(tph); resultSet.resolveType(tph).additionalGenerics.forEach(ag ->{ if(ag.contains(resolvedTPH)&&ag.TA1.equals(resolvedTPH)&&!contains(allPairs,ag)) { if(inMethod) @@ -625,6 +648,7 @@ public class BytecodeGen implements ASTVisitor { inMethod = false; ListOfMethodsAndTph.add(methodAndTph); } + } } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index 9d03979f..b5486df7 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -639,6 +639,19 @@ public class BytecodeGenMethod implements StatementVisitor { public void visit(MethodCall methodCall) { //ClassLoader.getSystemClassLoader().loadClass(className).getMethod(name, parameterTypes) + String receiverName = getResolvedType(methodCall.receiver.getType()); + System.out.println("Methods of " + receiverName + " "); + ClassLoader cl = ClassLoader.getSystemClassLoader(); + try { + java.lang.reflect.Method[] methods = cl.loadClass("java.util.Vector").getMethods(); + System.out.println("Methods of " + receiverName + " "); + for(java.lang.reflect.Method m : methods) { + System.out.println(m.getName() + " " + m.toGenericString()+ " ==> "); + } + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor())); methodCall.receiver.accept(this); diff --git a/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java b/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java index b22109c1..2b9bb931 100644 --- a/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java +++ b/src/de/dhbwstuttgart/bytecode/descriptor/DescriptorToString.java @@ -123,9 +123,21 @@ public class DescriptorToString implements DescriptorVisitor{ Iterator itr = lambdaExpression.getParams().iterator(); while(itr.hasNext()) { FormalParameter fp = itr.next(); - desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";"; + String d = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()); + if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) { + desc += "L"+Type.getInternalName(Object.class)+ ";"; + }else { + desc = desc + "L"+ d + ";"; + } + } + + String retType = resultSet.resolveType(lambdaExpression.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()); + + if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){ + desc += ")L"+Type.getInternalName(Object.class)+ ";"; + }else { + desc = desc + ")"+"L"+retType+";"; } - desc = addReturnType(desc, lambdaExpression.getReturnType(), resultSet); return desc; } @@ -135,9 +147,22 @@ public class DescriptorToString implements DescriptorVisitor{ Iterator itr = samMethod.getArgumentList().iterator(); while(itr.hasNext()) { RefTypeOrTPHOrWildcardOrGeneric rt = itr.next(); - desc = desc + "L"+resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor())+";"; + String d = resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor()); + + if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) { + desc += "L"+Type.getInternalName(Object.class)+ ";"; + }else { + desc += "L"+ d + ";"; + + } + } + String retType = resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()); + + if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){ + desc += ")L"+Type.getInternalName(Object.class)+ ";"; + }else { + desc = desc + ")"+"L"+retType+";"; } - desc = desc + ")"+"L"+resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+";"; return desc; } diff --git a/src/de/dhbwstuttgart/bytecode/signature/Signature.java b/src/de/dhbwstuttgart/bytecode/signature/Signature.java index 7b222770..09a2788f 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/Signature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/Signature.java @@ -9,6 +9,7 @@ import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureWriter; import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; +import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.Constructor; @@ -16,9 +17,11 @@ import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.result.GenericInsertPair; +import de.dhbwstuttgart.typeinference.result.ResolvedType; import de.dhbwstuttgart.typeinference.result.ResultSet; public class Signature { @@ -106,7 +109,7 @@ public class Signature { // 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)+"$"; + String g = ret.substring(4,ret.length())+"$"; if(genericsAndBounds.containsKey(g)) { genericsAndBoundsMethod.put(g, genericsAndBounds.get(g)); }else { @@ -117,13 +120,21 @@ public class Signature { } } + if(ret.contains("<")) { + RefType ref = (RefType) resultSet.resolveType(method.getReturnType()).resolvedType; + if(hasTPHs(ref)) { + createSignatureForParameterizedType(ref); + } + + } + // Parameters 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 ")) { - String gP = pT.substring(4)+"$"; + String gP = pT.substring(4,pT.length())+"$"; if(!genericsAndBounds.containsKey(gP) && !genericsAndBoundsMethod.containsKey(gP)) { sw.visitFormalTypeParameter(gP); String bound = Type.getInternalName(Object.class); @@ -147,6 +158,12 @@ public class Signature { } } + if(pT.contains("<")) { + RefType ref = (RefType) methodParamsAndTypes.get(paramName); + if(hasTPHs(ref)) + createSignatureForParameterizedType(ref); + } + for(GenericInsertPair p:methodPairs) { String name = p.TA1.getName()+"$"; if(!genericsAndBoundsMethod.containsKey(name)) { @@ -191,6 +208,128 @@ public class Signature { } // sw.visitEnd(); } + + private void createSignatureForParameterizedType(RefType ref) { + ArrayList allPairs = getAllPairs(ref); + allPairs.addAll(methodPairs); + ArrayList simplifiedPairs = simplifyPairs(allPairs); + + HashMap names = new HashMap<>(); + + for(GenericInsertPair pair : simplifiedPairs) { + String sub = pair.TA1.getName()+"$"; + String superT = pair.TA2.getName()+"$"; + names.put(sub, superT); + } + + for(String sub : names.keySet()) { + if(!genericsAndBoundsMethod.containsKey(sub) && !genericsAndBounds.containsKey(sub)) { + sw.visitFormalTypeParameter(sub); + String bound = names.get(sub); + sw.visitClassBound().visitTypeVariable(bound); + genericsAndBoundsMethod.put(sub, bound); + } + } + + for(String superT : names.values()) { + if(!names.containsKey(superT)) { + if(!genericsAndBoundsMethod.containsKey(superT) && !genericsAndBounds.containsKey(superT)) { + sw.visitFormalTypeParameter(superT); + sw.visitClassBound().visitClassType(Type.getInternalName(Object.class)); + sw.visitClassBound().visitEnd(); + genericsAndBoundsMethod.put(superT, Type.getInternalName(Object.class)); + } + } + } + } + + private ArrayList getAllPairs(RefType ref) { + final ArrayList res = new ArrayList<>(); + for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) { + RefTypeOrTPHOrWildcardOrGeneric resolved = resultSet.resolveType(p).resolvedType; + if(resolved instanceof TypePlaceholder) { + resultSet.resolveType(p).additionalGenerics.forEach(ag ->{ + if(!contains(res,ag)) { + res.add(ag); + } + }); + } + + } + return res; + } + + private boolean contains(ArrayList pairs, GenericInsertPair genPair) { + for(int i=0; i simplifyPairs(ArrayList allPairs) { + ArrayList simplifiedPairs = new ArrayList<>(); + + HashMap subAndSuperTph = new HashMap<>(); + for(GenericInsertPair p : allPairs) { + subAndSuperTph.put(p.TA1, p.TA2); + } + + subAndSuperTph.forEach((k,v)->System.out.println(k.getName() + " || " + v.getName())); + + int numOfVisitedPairs = 0; + for(TypePlaceholder subTph: subAndSuperTph.keySet()) { + + if(numOfVisitedPairs>=subAndSuperTph.size()) + break; + + HashMap tphsInRel= new HashMap<>(); + + tphsInRel.put(tphsInRel.size(), subTph); + TypePlaceholder superTph = subAndSuperTph.get(subTph); + tphsInRel.put(tphsInRel.size(), superTph); + + numOfVisitedPairs++; + + while(subAndSuperTph.containsKey(superTph)) { + superTph = subAndSuperTph.get(superTph); + tphsInRel.put(tphsInRel.size(), superTph); + numOfVisitedPairs++; + } + + // Subtype + TypePlaceholder subTphRes = tphsInRel.get(0); + // Die größte Supertype + TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1); + + + while(subAndSuperTph.containsValue(subTphRes)) { + for(TypePlaceholder tph : subAndSuperTph.keySet()) { + if(subAndSuperTph.get(tph).equals(subTphRes)) { + subTphRes = tph; + break; + } + } + tphsInRel.put(0, subTphRes); + numOfVisitedPairs++; + } + + subTphRes = tphsInRel.get(0); + GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes); + simplifiedPairs.add(sPair); + } + return simplifiedPairs; + } + + private boolean hasTPHs(RefType ref) { + for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) { + if(resultSet.resolveType(p).resolvedType instanceof TypePlaceholder) + return true; + } + return false; + } + /** * Visits parameter type or return type with {@link SignatureVisitor} to create * the method signature diff --git a/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java b/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java index a1357d4c..62227c8e 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java @@ -22,7 +22,12 @@ public class TypeToSignature implements TypeVisitor { Iterator it = refType.getParaList().iterator(); while(it.hasNext()){ RefTypeOrTPHOrWildcardOrGeneric param = it.next(); - params += "L"+param.toString().replace(".", "/"); + if(param instanceof TypePlaceholder) { + params += "T" + ((TypePlaceholder) param).getName() + "$"; + } else { + params += "L"+param.toString().replace(".", "/"); + } + if(it.hasNext())params += ";"; } params += ";>"; diff --git a/test/bytecode/javFiles/Lambda.jav b/test/bytecode/javFiles/Lambda.jav index b9a2c3f9..5ee83868 100644 --- a/test/bytecode/javFiles/Lambda.jav +++ b/test/bytecode/javFiles/Lambda.jav @@ -1,4 +1,4 @@ -class Apply { } +//class Apply { } public class Lambda { @@ -6,7 +6,8 @@ public class Lambda { var lam1 = (x) -> { return x; }; - return lam1.apply(new Apply()); +// return lam1.apply(new Apply()); + return lam1; } } diff --git a/test/bytecode/javFiles/Matrix.jav b/test/bytecode/javFiles/Matrix.jav index f0ea0356..eff095c7 100644 --- a/test/bytecode/javFiles/Matrix.jav +++ b/test/bytecode/javFiles/Matrix.jav @@ -8,9 +8,9 @@ public class Matrix extends Vector> { var i = 0; while(i < size()) { var v1 = this.elementAt(i); - var v2 = new Vector(); - var j = 0; - while(j < v1.size()) { +// var v2 = new Vector(); +// var j = 0; +// while(j < v1.size()) { // var erg = 0; // var k = 0; // while(k < v1.size()) { @@ -18,9 +18,9 @@ public class Matrix extends Vector> { // * m.elementAt(k).elementAt(j); // k++; } // v2.addElement(new Integer(erg)); - j++; } - ret.addElement(v2); - i++; +// j++; } +// ret.addElement(v2); +// i++; } return ret; }