From 7a1ed7ce6f7f1ef1ccb8f07a2f72919a080ddb20 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Thu, 25 Oct 2018 12:26:56 +0200 Subject: [PATCH] Neuer Transivitaet-Algorithmus Step 1 und Step 2 --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 155 +++++++++++++++++- .../bytecode/constraint/EqualConstraint.java | 9 + .../constraint/ExtendsConstraint.java | 9 + .../bytecode/constraint/TPHConstraint.java | 55 +++++++ test/bytecode/javFiles/Field.jav | 5 + 5 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 src/de/dhbwstuttgart/bytecode/constraint/EqualConstraint.java create mode 100644 src/de/dhbwstuttgart/bytecode/constraint/ExtendsConstraint.java create mode 100644 src/de/dhbwstuttgart/bytecode/constraint/TPHConstraint.java diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 8c9be088..62fb86ce 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -2,6 +2,7 @@ package de.dhbwstuttgart.bytecode; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -13,6 +14,9 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; +import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint; +import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; +import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString; import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; import de.dhbwstuttgart.bytecode.signature.Signature; @@ -175,6 +179,11 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(Constructor field) { + System.out.println("ResultSet: "); + resultSet.results.forEach(a->{ + System.out.println(a.getLeft().toString() + " = " + a.getRight().toString()); + }); + System.out.println("---------------"); field.getParameterList().accept(this); String methParamTypes = field.name+"%%"; @@ -205,7 +214,7 @@ public class BytecodeGen implements ASTVisitor { } String sig = null; if(hasGen) { - ArrayList pairs = simplifyPairs(field.name,tphExtractor.allPairs); + ArrayList pairs = simplifyPairs(field.name,tphExtractor.allPairs, tphExtractor.allCons); Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,pairs); sig = signature.toString(); } @@ -274,7 +283,11 @@ public class BytecodeGen implements ASTVisitor { /* if method has generics or return type is TPH, create signature */ // zwite operand muss weggelassen werden if(hasGen||resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString()).equals("TPH")) { - ArrayList pairs = simplifyPairs(method.name,tphExtractor.allPairs); + System.out.println("ALL CONST: " + tphExtractor.allCons.size()); + tphExtractor.allCons.forEach(c->System.out.println(c.toString())); + System.out.println("----------------"); + HashMap> constraints = simplifyPairs(method.name,tphExtractor.allCons); + ArrayList pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons); System.out.println(method.name + " => Simplified Pairs: "); pairs.forEach(p->System.out.println(p.TA1.getName() + " -> "+p.TA2.getName())); Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet, pairs); @@ -295,9 +308,122 @@ public class BytecodeGen implements ASTVisitor { mv.visitEnd(); } - private ArrayList simplifyPairs(String methodName, ArrayList allPairs) { + private HashMap> simplifyPairs(String name, ArrayList allCons) { + // 1. check if there are any cycles like L set L=R and: + // * remove both constraints + // * substitute L with R in all constraint + // b)no => go to next step + // 2. check the result of step 1 if there are any equal-constraints like L=R, M=R .. + // a) yes + // b) no + ArrayList consToRemove = new ArrayList<>(); + // step 1: + for(TPHConstraint c : allCons) { + + String left = c.getLeft(); + String right = c.getRight(); + if(c.getRel() == Relation.EXTENDS) { + TPHConstraint revCon = getReverseConstraint(allCons,left,right); + if(revCon != null) { + revCon.setRel(Relation.EQUAL); + consToRemove.add(revCon); + c.setRel(Relation.EQUAL); + substituteTPH(allCons,left, right); + } + } + } + System.out.println(); + System.out.println("NEW ALL CONST: " + allCons.size()); + allCons.forEach(c->System.out.println(c.toString())); + System.out.println("----------------"); + allCons.removeAll(consToRemove); + System.out.println("AFTER DELETE ALL CONST: " + allCons.size()); + allCons.forEach(c->System.out.println(c.toString())); + System.out.println("----------------"); + HashMap> result = new HashMap<>(); + for(TPHConstraint c : allCons) { + if(c.getRel()==Relation.EQUAL) { + HashSet equalTPHs = getEqualsTPHs(result, c); + TPHConstraint constraint = getKeyConstraint(result,c); + equalTPHs.add(c.getLeft()); + equalTPHs.add(c.getRight()); + result.put(constraint, equalTPHs); + } + } + System.out.println("Step 2 Result: "); + result.forEach((c,hs)->{ + System.out.print(c.toString() + " -> "); + hs.forEach(s->{ + System.out.print(s + ", "); + }); + System.out.println(); + }); + System.out.println("----------------"); + return result; + } + + private TPHConstraint getKeyConstraint(HashMap> result, TPHConstraint toFind) { + for(TPHConstraint c : result.keySet()) { + if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight())) + return c; + } + return new ExtendsConstraint(toFind.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS); + } + + private HashSet getEqualsTPHs(HashMap> result, TPHConstraint toFind) { + for(TPHConstraint c : result.keySet()) { + if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight())) + return result.get(c); + } + return new HashSet<>(); + } + + private String getBound(ArrayList allCons, String right) { + String bound = Type.getInternalName(Object.class); + for(TPHConstraint c: allCons) { + if(c.getRel() == Relation.EXTENDS && c.getLeft().equals(right)) { + return c.getRight(); + } + } + return bound; + } + + private ArrayList simplifyPairs(String methodName, ArrayList allPairs, ArrayList allCons) { allPairs.forEach(p->System.out.print(p.TA1 + " < "+ p.TA2+ " ; ")); + // 1. check if there are any cycles like L set L=R and: + // * remove both constraints + // * substitute L with R in all constraint + // b)no => go to next step + // 2. check the result of step 1 if there are any equal-constraints like L=R, M=R .. + // a) yes + // b) no + ArrayList consToRemove = new ArrayList<>(); + // step 1: + for(TPHConstraint c : allCons) { + + String left = c.getLeft(); + String right = c.getRight(); + if(c.getRel() == Relation.EXTENDS) { + TPHConstraint revCon = getReverseConstraint(allCons,left,right); + if(revCon != null) { + revCon.setRel(Relation.EQUAL); + consToRemove.add(revCon); + c.setRel(Relation.EQUAL); + substituteTPH(allCons,left, right); + } + } + } + System.out.println(); + System.out.println("NEW ALL CONST: " + allCons.size()); + allCons.forEach(c->System.out.println(c.toString())); + System.out.println("----------------"); + allCons.removeAll(consToRemove); + System.out.println("AFTER DELETE ALL CONST: " + allCons.size()); + allCons.forEach(c->System.out.println(c.toString())); + System.out.println("----------------"); if(allPairs.size() < 2) return allPairs; @@ -425,6 +551,26 @@ public class BytecodeGen implements ASTVisitor { return simplifiedPairs; } + private void substituteTPH(ArrayList allCons,String left ,String right) { + allCons.forEach(c->{ + if(c.getRel() == Relation.EXTENDS) { + if(c.getLeft().equals(left)) + c.setLeft(right); + if(c.getRight().equals(left)) + c.setRight(right); + } + }); + } + + private TPHConstraint getReverseConstraint(ArrayList allCons, String left, String right) { + for(TPHConstraint c : allCons) { + if(c.getLeft().equals(right) && c.getRight().equals(left)){ + return c; + } + } + return null; + } + private void removePair(ArrayList simplifiedPairs, TypePlaceholder typePlaceholder, TypePlaceholder typePlaceholder2) { for(GenericInsertPair p : simplifiedPairs) { if(p.TA1.equals(typePlaceholder) && p.TA2.equals(typePlaceholder2)) { @@ -685,6 +831,7 @@ public class BytecodeGen implements ASTVisitor { Boolean inMethod = false; final ArrayList ListOfMethodsAndTph = new ArrayList<>(); final ArrayList allPairs = new ArrayList<>(); + final ArrayList allCons = new ArrayList<>(); @Override public void visit(TypePlaceholder tph) { @@ -699,6 +846,8 @@ public class BytecodeGen implements ASTVisitor { if(inMethod) methodAndTph.getPairs().add(ag); allPairs.add(ag); + TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); + allCons.add(con); } }); } diff --git a/src/de/dhbwstuttgart/bytecode/constraint/EqualConstraint.java b/src/de/dhbwstuttgart/bytecode/constraint/EqualConstraint.java new file mode 100644 index 00000000..fb6cae20 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/constraint/EqualConstraint.java @@ -0,0 +1,9 @@ +package de.dhbwstuttgart.bytecode.constraint; + +public class EqualConstraint extends TPHConstraint { + + public EqualConstraint(String left, String right, Relation rel) { + super(left, right, rel); + } + +} diff --git a/src/de/dhbwstuttgart/bytecode/constraint/ExtendsConstraint.java b/src/de/dhbwstuttgart/bytecode/constraint/ExtendsConstraint.java new file mode 100644 index 00000000..6f28e24f --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/constraint/ExtendsConstraint.java @@ -0,0 +1,9 @@ +package de.dhbwstuttgart.bytecode.constraint; + +public class ExtendsConstraint extends TPHConstraint { + + public ExtendsConstraint(String left, String right, Relation rel) { + super(left, right, rel); + } + +} diff --git a/src/de/dhbwstuttgart/bytecode/constraint/TPHConstraint.java b/src/de/dhbwstuttgart/bytecode/constraint/TPHConstraint.java new file mode 100644 index 00000000..e0f3b4c0 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/constraint/TPHConstraint.java @@ -0,0 +1,55 @@ +package de.dhbwstuttgart.bytecode.constraint; + +public class TPHConstraint { + protected String left; + protected String right; + protected Relation rel; + public enum Relation{ + EXTENDS, EQUAL + } + + public TPHConstraint(String left, String right, Relation rel) { + this.left = left; + this.right = right; + this.rel = rel; + } + + public String getLeft() { + return left; + } + + + public String getRight() { + return right; + } + + + public Relation getRel() { + return rel; + } + + public void setLeft(String left) { + this.left = left; + } + + public void setRight(String right) { + this.right = right; + } + + public void setRel(Relation rel) { + this.rel = rel; + } + + public boolean containTPH(String tph) { + return left.equals(tph)||right.equals(tph); + } + + @Override + public String toString() { + if(rel == Relation.EXTENDS) { + return left + " < " + right; + }else { + return left + " = " + right; + } + } +} diff --git a/test/bytecode/javFiles/Field.jav b/test/bytecode/javFiles/Field.jav index ed08efce..970cbe2f 100644 --- a/test/bytecode/javFiles/Field.jav +++ b/test/bytecode/javFiles/Field.jav @@ -1,4 +1,9 @@ +import java.lang.Integer; public class Field { x = 5; + + m(){ + return x; + } } \ No newline at end of file