From 3e186334a2077e37de084c36e4142b2b60bed43b Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Thu, 21 Feb 2019 13:34:36 +0100 Subject: [PATCH] Simpify Algo korrigiert so dass die lokalen Variablen der Methode beruecksichtigt werden --- .../dhbwstuttgart/bytecode/TPHExtractor.java | 68 +- .../bytecode/utilities/ConstraintsFinder.java | 11 +- .../bytecode/utilities/MethodAndTPH.java | 7 + .../bytecode/utilities/NameReplacer.java | 7 +- .../bytecode/utilities/Simplify.java | 1074 +++++++++-------- src/test/java/bytecode/KompTphTest.java | 37 + .../resources/bytecode/javFiles/KompTph.jav | 13 + 7 files changed, 700 insertions(+), 517 deletions(-) create mode 100644 src/test/java/bytecode/KompTphTest.java create mode 100644 src/test/resources/bytecode/javFiles/KompTph.jav diff --git a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java index 0135631ed..c100eb4a9 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java @@ -5,6 +5,7 @@ package de.dhbwstuttgart.bytecode; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; @@ -12,7 +13,11 @@ import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.Constructor; +import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.statement.LocalVar; +import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.result.GenericInsertPair; import de.dhbwstuttgart.typeinference.result.ResultSet; @@ -21,36 +26,42 @@ import de.dhbwstuttgart.typeinference.result.ResultSet; * @author Fayez Abu Alia * */ -public class TPHExtractor extends AbstractASTWalker{ +public class TPHExtractor extends AbstractASTWalker { // Alle TPHs der Felder werden iKopf der Klasse definiert // alle TPHs der Klasse: (TPH, is in Method?) - final HashMap allTPHS = new HashMap<>(); + final HashMap allTPHS = new HashMap<>(); MethodAndTPH methodAndTph; + Boolean inMethod = false; + boolean inLocalOrParam = false; + public final ArrayList ListOfMethodsAndTph = new ArrayList<>(); final ArrayList allPairs = new ArrayList<>(); public final ArrayList allCons = new ArrayList<>(); private ResultSet resultSet; - + public TPHExtractor() { - + } - + public void setResultSet(ResultSet resultSet) { this.resultSet = resultSet; } - + @Override public void visit(TypePlaceholder tph) { - if(resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) { + if (resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) { TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType; - if(inMethod) + if (inMethod) { methodAndTph.getTphs().add(resolvedTPH.getName()); - - allTPHS.put(resolvedTPH,inMethod); - resultSet.resolveType(tph).additionalGenerics.forEach(ag ->{ - if(ag.contains(resolvedTPH)&&ag.TA1.equals(resolvedTPH)&&!contains(allPairs,ag)) { - if(inMethod) + if (inLocalOrParam) + methodAndTph.getLocalTphs().add(resolvedTPH.getName()); + } + + allTPHS.put(resolvedTPH, inMethod); + resultSet.resolveType(tph).additionalGenerics.forEach(ag -> { + if (ag.contains(resolvedTPH) && ag.TA1.equals(resolvedTPH) && !contains(allPairs, ag)) { + if (inMethod) methodAndTph.getPairs().add(ag); allPairs.add(ag); TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); @@ -59,14 +70,16 @@ public class TPHExtractor extends AbstractASTWalker{ }); } } + private boolean contains(ArrayList pairs, GenericInsertPair genPair) { - for(int i=0; i allConstaints; @@ -18,10 +19,12 @@ public class ConstraintsFinder { List visitedCons = new ArrayList<>(); for(TPHConstraint c : allConstaints) { - // get constraints with the same left side - List cons = getConstraints(c,visitedCons); - if(cons.size()>1) - result.add(cons); + if(c.getRel() == Relation.EXTENDS) { + // get constraints with the same left side + List cons = getConstraints(c,visitedCons); + if(cons.size()>1) + result.add(cons); + } } return result; diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java index 7175f1088..e21f974cc 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java @@ -10,6 +10,8 @@ public class MethodAndTPH { private String name; private final ArrayList tphs = new ArrayList<>(); private final ArrayList pairs = new ArrayList<>(); + // tphs of local variables and parameters + private final ArrayList localTphs = new ArrayList<>(); public MethodAndTPH(String name) { this.name = name; @@ -26,4 +28,9 @@ public class MethodAndTPH { public String getName() { return name; } + + public ArrayList getLocalTphs() { + return localTphs; + } + } diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java index 8b906eee6..bc3c1b98c 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java @@ -12,12 +12,14 @@ public class NameReplacer { private List constraints; private List allConstraints; private List tphs; + private List localTphs; - public NameReplacer(List constraints, List allConstraints,List tphs) { + public NameReplacer(List constraints, List allConstraints,List tphs, ArrayList localTphs) { super(); this.constraints = constraints; this.allConstraints = allConstraints; this.tphs = tphs; + this.localTphs = localTphs; } public Map> replaceNames() { @@ -34,8 +36,11 @@ public class NameReplacer { if(names.contains(cons.getRight())) cons.setRight(newName); } + tphs.removeAll(names); tphs.add(newName); + localTphs.removeAll(names); + localTphs.add(newName); HashMap> res = new HashMap<>(); res.put(newName, names); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java index e15282542..89b55efbe 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java @@ -17,125 +17,145 @@ import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; public class Simplify { - - public static HashMap> simplifyConstraints(String name, TPHExtractor tphExtractor, ArrayList tphsClass) { + + public static HashMap> simplifyConstraints(String name, TPHExtractor tphExtractor, + ArrayList tphsClass) { // 1. check if there are any simple 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 => put all such TPhs in a map and define "key-Cons" - // -- key-Cons = TPH < Object -- - // put this Constraint and the - // b) no + // a) yes => 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 => put all such TPhs in a map and define "key-Cons" + // -- key-Cons = TPH < Object -- + // put this Constraint and the + // b) no // 3. is - + // all constraints that will be simplified - ArrayList allCons = tphExtractor.allCons; +// ArrayList allCons = tphExtractor.allCons; + ArrayList allCons = new ArrayList<>(); + + for(TPHConstraint c : tphExtractor.allCons) { + TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel()); + allCons.add(nc); + } ArrayList consToRemove = new ArrayList<>(); - + + // get all tph of the method + ArrayList methodTphs = new ArrayList<>(); + ArrayList localTphs = new ArrayList<>(); + for (MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) { + if (m.getName().equals(name)) { + methodTphs = m.getTphs(); + localTphs = m.getLocalTphs(); + break; + } + } + // step 1: - for(TPHConstraint c : allCons) { - + 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) { + if (c.getRel() == Relation.EXTENDS) { + TPHConstraint revCon = getReverseConstraint(allCons, left, right); + if (revCon != null) { revCon.setRel(Relation.EQUAL); - // the reverse constraint is removed because - // otherwise there is the same constraint twice - // (e.g. A A=B and B=A) + // the reverse constraint is removed because + // otherwise there is the same constraint twice + // (e.g. A A=B and B=A) consToRemove.add(revCon); c.setRel(Relation.EQUAL); - substituteTPH(allCons,left, right); + substituteTPH(allCons, left, right); } } } - + System.out.println(); System.out.println("NEW ALL CONST: " + allCons.size()); - allCons.forEach(c->System.out.println(c.toString())); + allCons.forEach(c -> System.out.println(c.toString())); System.out.println("----------------"); allCons.removeAll(consToRemove); consToRemove = new ArrayList<>(); - + int size = allCons.size(); - + System.out.println("AFTER DELETE ALL CONST: " + allCons.size()); - allCons.forEach(c->System.out.println(c.toString())); + allCons.forEach(c -> System.out.println(c.toString())); System.out.println("----------------"); HashMap> result = new HashMap<>(); - + // check if there is any long cycle (e.g. A allTypes = new LinkedList<>(); // we will put all constraints which are in the cycle, in this ArrayList. // Later these contraints will be converted to equal-constraints ArrayList constraints = new ArrayList<>(size); int visited = 0; - + // contains all constraints - HashMap ss1 = new HashMap<>(); - - for(TPHConstraint constr : allCons) { + HashMap ss1 = new HashMap<>(); + + for (TPHConstraint constr : allCons) { ss1.put(constr.getLeft(), constr.getRight()); } - - for(TPHConstraint c : allCons) { - - if(visited >= size) + + for (TPHConstraint c : allCons) { + + if (visited >= size) break; // Only extends-constraints will be checked - if(c.getRel() == Relation.EXTENDS) { + if (c.getRel() == Relation.EXTENDS) { ++visited; - + String left = c.getLeft(); String right = c.getRight(); // put the types in linked list allTypes.add(left); allTypes.add(right); - + constraints.add(c); - + boolean isCycle = false; - + // iterate through the map to check if there is a cycle - while(ss1.containsKey(right)) { + while (ss1.containsKey(right)) { ++visited; String oldRight = right; right = ss1.get(right); - + TPHConstraint toAdd = getConstraint(oldRight, right, allCons); - - if(toAdd != null) + + if (toAdd != null) constraints.add(toAdd); - - if(left.equals(right)) { + + if (left.equals(right)) { isCycle = true; break; } - + allTypes.add(right); } - - if(isCycle) { + + if (isCycle) { // convert all constraints to equal constraints setAllEqual(constraints); // these constraints will be removed from allCons consToRemove.addAll(constraints); // all equal types will be substitute with one type - substituteAllTPH(allCons,constraints,left); - + substituteAllTPH(allCons, constraints, left); + HashSet eq = new HashSet<>(); // put all equal types in a set - for(String t:allTypes) { + for (String t : allTypes) { eq.add(t); } // generate a new constraint (left < Object) - TPHConstraint constraint = new ExtendsConstraint(left, Type.getInternalName(Object.class), Relation.EXTENDS); + TPHConstraint constraint = new ExtendsConstraint(left, Type.getInternalName(Object.class), + Relation.EXTENDS); // put the generated constraint and its equal set into result set result.put(constraint, eq); constraints.clear(); @@ -143,93 +163,100 @@ public class Simplify { allTypes.clear(); } } - // build an equal set that contains all types - // which are equal and for each equal constraint put left side and right side - // in this set Then generate a constraint type < Object and put it - // with the equal set into the result. - for(TPHConstraint c : allCons) { - if(c.getRel()==Relation.EQUAL) { - if(!isTPHInResEqual(result, c.getLeft())) { - HashSet equalTPHs = getEqualsTPHs(result, c); - TPHConstraint constraint = getKeyConstraint(result,c); - equalTPHs.add(c.getLeft()); - equalTPHs.add(c.getRight()); - result.put(constraint, equalTPHs); + + for (TPHConstraint ec : allCons) { + + if(ec.getRel() == Relation.EQUAL) { + if(!localTphs.contains(ec.getRight())) { + localTphs.add(ec.getRight()); } - consToRemove.add(c); - size--; + if(!methodTphs.contains(ec.getRight())) { + methodTphs.add(ec.getRight()); + } + } } - + // build an equal set that contains all types + // which are equal and for each equal constraint put left side and right side + // in this set Then generate a constraint type < Object and put it + // with the equal set into the result. +// for(TPHConstraint c : allCons) { +// if(c.getRel()==Relation.EQUAL) { +// if(!isTPHInResEqual(result, c.getLeft())) { +// HashSet equalTPHs = getEqualsTPHs(result, c); +// TPHConstraint constraint = getKeyConstraint(result,c); +// equalTPHs.add(c.getLeft()); +// equalTPHs.add(c.getRight()); +// result.put(constraint, equalTPHs); +// } +// consToRemove.add(c); +// size--; +// } +// } + System.out.println("Step 2 Result: "); - result.forEach((c,hs)->{ + result.forEach((c, hs) -> { System.out.print(c.toString() + " -> "); - hs.forEach(s->{ + hs.forEach(s -> { System.out.print(s + ", "); }); System.out.println(); }); System.out.println("----------------"); - // remove all equal-constraints - allCons.removeAll(consToRemove); - // add all generated constraints to allCons - allCons.addAll(result.keySet()); - - if(!allCons.isEmpty() && allCons.size()<2) { + + if (!allCons.isEmpty() && allCons.size() < 2) { TPHConstraint cons = allCons.get(0); - if(!result.containsKey(cons)) { + if (!result.containsKey(cons)) { result.put(cons, null); - if(!cons.getRight().equals(Type.getInternalName(Object.class))) - result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS), null); + if (!cons.getRight().equals(Type.getInternalName(Object.class))) + result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), + Relation.EXTENDS), null); } - + return result; } - + size += result.keySet().size(); // all constraints which have Object on the right side will // be ignored, because they are simplified and can not be changed. - for(TPHConstraint c : allCons) { - if(c.getRight().equals(Type.getInternalName(Object.class))) + for (TPHConstraint c : allCons) { + if (c.getRight().equals(Type.getInternalName(Object.class))) size--; } - // get all tph of the method - ArrayList methodTphs = new ArrayList<>(); - for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) { - if(m.getName().equals(name)) { - methodTphs = m.getTphs(); - break; - } - } + // finder looks for constraints that have the same left hand side // and put them in a list ConstraintsFinder finder = new ConstraintsFinder(allCons); List> foundCons = finder.findConstraints(); - + ArrayList eqCons = new ArrayList<>(); - - for(List list : foundCons) { + + for (List list : foundCons) { // generate a new name and replace the right hand side for each constraint // in list with the new name - NameReplacer replacer = new NameReplacer(list,allCons,methodTphs); + NameReplacer replacer = new NameReplacer(list, allCons, methodTphs, localTphs); // new name -> [all old names] Map> replRes = replacer.replaceNames(); // create an equal constraint for each value in repres String key = replRes.keySet().iterator().next(); - for(String val : replRes.values().iterator().next()) { + for (String val : replRes.values().iterator().next()) { EqualConstraint ec = new EqualConstraint(val, key, Relation.EQUAL); eqCons.add(ec); } - - updateEqualCons(replRes,eqCons); - + for (TPHConstraint c : allCons) { + if (c.getRel() == Relation.EQUAL && key.equals(c.getRight())) { + eqCons.add(c); + } + } + updateEqualCons(replRes, eqCons); + TPHConstraint c = list.get(0); allCons.removeAll(list); allCons.add(c); } - + // check if there are multiple constraint with the same left side. - // if yes => check if the super type in the method, if not + // if yes => check if the super type in the method, if not // then ignore it. // HashMap subAndSuper = new HashMap<>(); // ArrayList eqCons = new ArrayList<>(); @@ -273,246 +300,123 @@ public class Simplify { // }); // System.out.println("----------------"); HashMap subAndSuper = new HashMap<>(); - - for(TPHConstraint c : allCons) { - subAndSuper.put(c.getLeft(), c.getRight()); + + for (TPHConstraint c : allCons) { + if (c.getRel() == Relation.EXTENDS) + subAndSuper.put(c.getLeft(), c.getRight()); } - + + for (TPHConstraint ec : allCons) { + if(ec.getRel() == Relation.EQUAL) { + methodTphs.remove(ec.getLeft()); + localTphs.remove(ec.getLeft()); + if(!localTphs.contains(ec.getRight())) { + localTphs.add(ec.getRight()); + } + if(!methodTphs.contains(ec.getRight())) { + methodTphs.add(ec.getRight()); + } + } + + } + int numOfVisitedPairs = 0; - for(String sub : subAndSuper.keySet()) { - if(isTPHInConstraint(result,sub)) + for (String sub : subAndSuper.keySet()) { + if (isTPHInConstraint(result, sub)) continue; - - if(!containTPH(methodTphs,sub)) + + if (!containTPH(methodTphs, sub)) continue; - - if(numOfVisitedPairs>=size) + + if (numOfVisitedPairs >= size) break; LinkedList tphInRel = new LinkedList<>(); tphInRel.add(sub); String superT = subAndSuper.get(sub); tphInRel.add(superT); - + numOfVisitedPairs++; - while(subAndSuper.containsKey(superT)) { + while (!localTphs.contains(superT) && subAndSuper.containsKey(superT)) { superT = subAndSuper.get(superT); - if(tphInRel.contains(superT)) { + if (tphInRel.contains(superT)) { break; } tphInRel.add(superT); numOfVisitedPairs++; } - + // Subtype String subTphRes = tphInRel.getFirst(); // Die größte Supertype String superTphRes = tphInRel.getLast(); - + // if there is any constraint X < subTph, then // add X at the beginning of the list. - while(subAndSuper.containsValue(subTphRes)) { - for(String tph : subAndSuper.keySet()) { - if(containTPH(methodTphs,tph) && subAndSuper.get(tph).equals(subTphRes)) { + while (!localTphs.contains(subTphRes) && subAndSuper.containsValue(subTphRes)) { + for (String tph : subAndSuper.keySet()) { + if (containTPH(methodTphs, tph) && subAndSuper.get(tph).equals(subTphRes)) { subTphRes = tph; break; } } - if(subTphRes.equals(tphInRel.getFirst())) { + if (subTphRes.equals(tphInRel.getFirst())) { break; } - - if(isTPHInConstraint(result, subTphRes)) + + if (isTPHInConstraint(result, subTphRes)) break; - + tphInRel.addFirst(subTphRes); numOfVisitedPairs++; } - + subTphRes = tphInRel.getFirst(); // if the last type in the list not a type in method-types // then find the last type in front of this type, which is // a type in method-types int i = 2; - while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) { - superTphRes = tphInRel.get(tphInRel.size()-i); + while (!containTPH(methodTphs, superTphRes) && (tphInRel.size() - i) > 0) { + superTphRes = tphInRel.get(tphInRel.size() - i); i++; } - - if(!containTPH(methodTphs, superTphRes)) { - HashSet equals = getEqualsTphsFromEqualCons(eqCons,superTphRes); - if(classTPHSContainsTPH(tphsClass,superTphRes)) { + + if (!containTPH(methodTphs, superTphRes)) { + HashSet equals = getEqualsTphsFromEqualCons(eqCons, superTphRes); + if (classTPHSContainsTPH(tphsClass, superTphRes)) { result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals); } else { - result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), equals); + result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), + equals); } - + } else { - HashSet equals = getEqualsTphsFromEqualCons(eqCons,subTphRes); + HashSet equals = getEqualsTphsFromEqualCons(eqCons, subTphRes); result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals); - if(!isTPHInConstraint(result, superTphRes) && !isTphInEqualSet(result,superTphRes)) { - HashSet equals2 = getEqualsTphsFromEqualCons(eqCons,superTphRes); - result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), equals2); + if (!isTPHInConstraint(result, superTphRes) && !isTphInEqualSet(result, superTphRes)) { + HashSet equals2 = getEqualsTphsFromEqualCons(eqCons, superTphRes); + result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), + equals2); } } } - - for(String tph : methodTphs) { - if(!isTPHInConstraint(result, tph) && !isTphInEqualSet(result,tph)) { - HashSet equals = getEqualsTphsFromEqualCons(eqCons,tph); + +// for(String tph : methodTphs) { + for (String tph : localTphs) { + if (!isTPHInConstraint(result, tph) && !isTphInEqualSet(result, tph)) { + HashSet equals = getEqualsTphsFromEqualCons(eqCons, tph); result.put(new ExtendsConstraint(tph, Type.getInternalName(Object.class), Relation.EXTENDS), equals); } } - - System.out.println("EndResult: "); - result.forEach((c,hs)->{ - if(c!=null) { - System.out.print(c.toString() + " -> "); - if(hs == null) { - System.out.print(" [] "); - }else { - hs.forEach(s->{ - System.out.print(s + ", "); - }); - } - } - - - System.out.println(); - }); - System.out.println("----------------"); - return result; - } - - - private static void updateEqualCons(Map> replRes, ArrayList eqCons) { - List oldNames = replRes.values().iterator().next(); - String newName = replRes.keySet().iterator().next(); - for(TPHConstraint c : eqCons) { -// if(oldNames.contains(c.getLeft())) -// c.setLeft(newName); - if(oldNames.contains(c.getRight())) - c.setRight(newName); - } - - } - - public static HashMap> simplifyConstraintsClass(TPHExtractor tphExtractor, ArrayList tphsClass) { - // all constraints that will be simplified - ArrayList allCons = tphExtractor.allCons; - 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); - // the reverse constraint is removed because - // otherwise there is the same constraint twice - // (e.g. A A=B and B=A) - consToRemove.add(revCon); - c.setRel(Relation.EQUAL); - substituteTPH(allCons,left, right); - } - } - } - - - allCons.removeAll(consToRemove); - consToRemove = new ArrayList<>(); - - int size = allCons.size(); - - HashMap> result = new HashMap<>(); - - // check if there is any long cycle (e.g. A allTypes = new LinkedList<>(); - // we will put all constraints which are in the cycle, in this ArrayList. - // Later these contraints will be converted to equal-constraints - ArrayList constraints = new ArrayList<>(size); - int visited = 0; - - // contains all constraints - HashMap ss1 = new HashMap<>(); - - for(TPHConstraint constr : allCons) { - ss1.put(constr.getLeft(), constr.getRight()); - } - - for(TPHConstraint c : allCons) { - - if(visited >= size) - break; - // Only extends-constraints will be checked - if(c.getRel() == Relation.EXTENDS) { - ++visited; - - String left = c.getLeft(); - String right = c.getRight(); - // put the types in linked list - allTypes.add(left); - allTypes.add(right); - - constraints.add(c); - - boolean isCycle = false; - - // iterate through the map to check if there is a cycle - while(ss1.containsKey(right)) { - ++visited; - String oldRight = right; - right = ss1.get(right); - - TPHConstraint toAdd = getConstraint(oldRight, right, allCons); - - if(toAdd != null) - constraints.add(toAdd); - - if(left.equals(right)) { - isCycle = true; - break; - } - - allTypes.add(right); - } - - if(isCycle) { - // convert all constraints to equal constraints - setAllEqual(constraints); - // these constraints will be removed from allCons - consToRemove.addAll(constraints); - // all equal types will be substitute with one type - substituteAllTPH(allCons,constraints,left); - - HashSet eq = new HashSet<>(); - // put all equal types in a set - for(String t:allTypes) { - eq.add(t); - } - // generate a new constraint (left < Object) - TPHConstraint constraint = new ExtendsConstraint(left, Type.getInternalName(Object.class), Relation.EXTENDS); - // put the generated constraint and its equal set into result set - result.put(constraint, eq); - constraints.clear(); - } - allTypes.clear(); - } - } // build an equal set that contains all types - // which are equal and for each equal constraint put left side and right side + // which are equal and for each equal constraint put left side and right side // in this set Then generate a constraint type < Object and put it // with the equal set into the result. - for(TPHConstraint c : allCons) { - if(c.getRel()==Relation.EQUAL) { - if(!isTPHInResEqual(result, c.getLeft())) { + for (TPHConstraint c : allCons) { + if (c.getRel() == Relation.EQUAL) { + if (!isTPHInResEqual(result, c.getLeft())) { HashSet equalTPHs = getEqualsTPHs(result, c); - TPHConstraint constraint = getKeyConstraint(result,c); + TPHConstraint constraint = getKeyConstraint(result, c); equalTPHs.add(c.getLeft()); equalTPHs.add(c.getRight()); result.put(constraint, equalTPHs); @@ -521,131 +425,290 @@ public class Simplify { size--; } } - + // remove all equal-constraints allCons.removeAll(consToRemove); - // add all generated constraints to allCons + // add all generated constraints to allCons allCons.addAll(result.keySet()); - - if(!allCons.isEmpty() && allCons.size()<2) { - TPHConstraint cons = allCons.get(0); - if(!result.containsKey(cons)) { - result.put(cons, null); - result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS), null); - } - - return result; - } - - size += result.keySet().size(); - // all constraints which have Object on the right side will - // be ignored, because they are simplified and can not be changed. - for(TPHConstraint c : allCons) { - if(c.getRight().equals(Type.getInternalName(Object.class))) - size--; - } - - // check if there are multiple constraint with the same left side. - // if yes => check if the super type in the method, if not - // then ignore it. - HashMap subAndSuper = new HashMap<>(); - ArrayList eqCons = new ArrayList<>(); - for(TPHConstraint c : allCons) { - - subAndSuper.put(c.getLeft(), c.getRight()); - } - - int numOfVisitedPairs = 0; - for(String sub : subAndSuper.keySet()) { - if(isTPHInConstraint(result,sub)) - continue; - - if(!classTPHSContainsTPH(tphsClass,sub)) - continue; - - if(numOfVisitedPairs>=size) - break; - LinkedList tphInRel = new LinkedList<>(); - tphInRel.add(sub); - String superT = subAndSuper.get(sub); - tphInRel.add(superT); - - numOfVisitedPairs++; - while(subAndSuper.containsKey(superT)) { - superT = subAndSuper.get(superT); - if(tphInRel.contains(superT)) { - break; - } - tphInRel.add(superT); - numOfVisitedPairs++; - } - - // Subtype - String subTphRes = tphInRel.getFirst(); - // Die größte Supertype - String superTphRes = tphInRel.getLast(); - - // if there is any constraint X < subTph, then - // add X at the beginning of the list. - while(subAndSuper.containsValue(subTphRes)) { - for(String tph : subAndSuper.keySet()) { - if(classTPHSContainsTPH(tphsClass,tph) && subAndSuper.get(tph).equals(subTphRes)) { - subTphRes = tph; - break; - } - } - if(subTphRes.equals(tphInRel.getFirst())) { - break; - } - - if(isTPHInConstraint(result, subTphRes)) - break; - - tphInRel.addFirst(subTphRes); - numOfVisitedPairs++; - } - - subTphRes = tphInRel.getFirst(); - - - - HashSet equals = getEqualsTphsFromEqualCons(eqCons,superTphRes); - result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals); - - } - + System.out.println("EndResult: "); - result.forEach((c,hs)->{ - if(c!=null) { + result.forEach((c, hs) -> { + if (c != null) { System.out.print(c.toString() + " -> "); - if(hs == null) { + if (hs == null) { System.out.print(" [] "); - }else { - hs.forEach(s->{ + } else { + hs.forEach(s -> { System.out.print(s + ", "); }); } } - - + System.out.println(); }); System.out.println("----------------"); return result; } - - + + private static void updateEqualCons(Map> replRes, ArrayList eqCons) { + List oldNames = replRes.values().iterator().next(); + String newName = replRes.keySet().iterator().next(); + for (TPHConstraint c : eqCons) { +// if(oldNames.contains(c.getLeft())) +// c.setLeft(newName); + if (oldNames.contains(c.getRight())) + c.setRight(newName); + } + + } + + public static HashMap> simplifyConstraintsClass(TPHExtractor tphExtractor, + ArrayList tphsClass) { + // all constraints that will be simplified + ArrayList allCons = tphExtractor.allCons; + 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); + // the reverse constraint is removed because + // otherwise there is the same constraint twice + // (e.g. A A=B and B=A) + consToRemove.add(revCon); + c.setRel(Relation.EQUAL); + substituteTPH(allCons, left, right); + } + } + } + + allCons.removeAll(consToRemove); + consToRemove = new ArrayList<>(); + + int size = allCons.size(); + + HashMap> result = new HashMap<>(); + + // check if there is any long cycle (e.g. A allTypes = new LinkedList<>(); + // we will put all constraints which are in the cycle, in this ArrayList. + // Later these contraints will be converted to equal-constraints + ArrayList constraints = new ArrayList<>(size); + int visited = 0; + + // contains all constraints + HashMap ss1 = new HashMap<>(); + + for (TPHConstraint constr : allCons) { + ss1.put(constr.getLeft(), constr.getRight()); + } + + for (TPHConstraint c : allCons) { + + if (visited >= size) + break; + // Only extends-constraints will be checked + if (c.getRel() == Relation.EXTENDS) { + ++visited; + + String left = c.getLeft(); + String right = c.getRight(); + // put the types in linked list + allTypes.add(left); + allTypes.add(right); + + constraints.add(c); + + boolean isCycle = false; + + // iterate through the map to check if there is a cycle + while (ss1.containsKey(right)) { + ++visited; + String oldRight = right; + right = ss1.get(right); + + TPHConstraint toAdd = getConstraint(oldRight, right, allCons); + + if (toAdd != null) + constraints.add(toAdd); + + if (left.equals(right)) { + isCycle = true; + break; + } + + allTypes.add(right); + } + + if (isCycle) { + // convert all constraints to equal constraints + setAllEqual(constraints); + // these constraints will be removed from allCons + consToRemove.addAll(constraints); + // all equal types will be substitute with one type + substituteAllTPH(allCons, constraints, left); + + HashSet eq = new HashSet<>(); + // put all equal types in a set + for (String t : allTypes) { + eq.add(t); + } + // generate a new constraint (left < Object) + TPHConstraint constraint = new ExtendsConstraint(left, Type.getInternalName(Object.class), + Relation.EXTENDS); + // put the generated constraint and its equal set into result set + result.put(constraint, eq); + constraints.clear(); + } + allTypes.clear(); + } + } + // build an equal set that contains all types + // which are equal and for each equal constraint put left side and right side + // in this set Then generate a constraint type < Object and put it + // with the equal set into the result. + for (TPHConstraint c : allCons) { + if (c.getRel() == Relation.EQUAL) { + if (!isTPHInResEqual(result, c.getLeft())) { + HashSet equalTPHs = getEqualsTPHs(result, c); + TPHConstraint constraint = getKeyConstraint(result, c); + equalTPHs.add(c.getLeft()); + equalTPHs.add(c.getRight()); + result.put(constraint, equalTPHs); + } + consToRemove.add(c); + size--; + } + } + + // remove all equal-constraints + allCons.removeAll(consToRemove); + // add all generated constraints to allCons + allCons.addAll(result.keySet()); + + if (!allCons.isEmpty() && allCons.size() < 2) { + TPHConstraint cons = allCons.get(0); + if (!result.containsKey(cons)) { + result.put(cons, null); + result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS), + null); + } + + return result; + } + + size += result.keySet().size(); + // all constraints which have Object on the right side will + // be ignored, because they are simplified and can not be changed. + for (TPHConstraint c : allCons) { + if (c.getRight().equals(Type.getInternalName(Object.class))) + size--; + } + + // check if there are multiple constraint with the same left side. + // if yes => check if the super type in the method, if not + // then ignore it. + HashMap subAndSuper = new HashMap<>(); + ArrayList eqCons = new ArrayList<>(); + for (TPHConstraint c : allCons) { + + subAndSuper.put(c.getLeft(), c.getRight()); + } + + int numOfVisitedPairs = 0; + for (String sub : subAndSuper.keySet()) { + if (isTPHInConstraint(result, sub)) + continue; + + if (!classTPHSContainsTPH(tphsClass, sub)) + continue; + + if (numOfVisitedPairs >= size) + break; + LinkedList tphInRel = new LinkedList<>(); + tphInRel.add(sub); + String superT = subAndSuper.get(sub); + tphInRel.add(superT); + + numOfVisitedPairs++; + while (subAndSuper.containsKey(superT)) { + superT = subAndSuper.get(superT); + if (tphInRel.contains(superT)) { + break; + } + tphInRel.add(superT); + numOfVisitedPairs++; + } + + // Subtype + String subTphRes = tphInRel.getFirst(); + // Die größte Supertype + String superTphRes = tphInRel.getLast(); + + // if there is any constraint X < subTph, then + // add X at the beginning of the list. + while (subAndSuper.containsValue(subTphRes)) { + for (String tph : subAndSuper.keySet()) { + if (classTPHSContainsTPH(tphsClass, tph) && subAndSuper.get(tph).equals(subTphRes)) { + subTphRes = tph; + break; + } + } + if (subTphRes.equals(tphInRel.getFirst())) { + break; + } + + if (isTPHInConstraint(result, subTphRes)) + break; + + tphInRel.addFirst(subTphRes); + numOfVisitedPairs++; + } + + subTphRes = tphInRel.getFirst(); + + HashSet equals = getEqualsTphsFromEqualCons(eqCons, superTphRes); + result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals); + + } + + System.out.println("EndResult: "); + result.forEach((c, hs) -> { + if (c != null) { + System.out.print(c.toString() + " -> "); + if (hs == null) { + System.out.print(" [] "); + } else { + hs.forEach(s -> { + System.out.print(s + ", "); + }); + } + } + + System.out.println(); + }); + System.out.println("----------------"); + return result; + } + private static boolean classTPHSContainsTPH(ArrayList tphsClass, String superTphRes) { - for(TypePlaceholder tph : tphsClass) { - if(tph.getName().equals(superTphRes)) + for (TypePlaceholder tph : tphsClass) { + if (tph.getName().equals(superTphRes)) return true; } return false; } private static boolean isTphInEqualSet(HashMap> result, String tph) { - for(HashSet hs: result.values()) { - if(hs.contains(tph)) + for (HashSet hs : result.values()) { + if (hs.contains(tph)) return true; } return false; @@ -653,44 +716,44 @@ public class Simplify { private static HashSet getEqualsTphsFromEqualCons(ArrayList eqCons, String tph) { HashSet ee = new HashSet<>(); - for(TPHConstraint c : eqCons) { - if(c.getLeft().equals(tph)) + for (TPHConstraint c : eqCons) { + if (c.getLeft().equals(tph)) ee.add(c.getRight()); - if(c.getRight().equals(tph)) + if (c.getRight().equals(tph)) ee.add(c.getLeft()); } return ee; } - private static void substituteInMap(HashMap subAndSuper, ArrayList allCons,ArrayList eqCons, String toSubs, - String tph) { + private static void substituteInMap(HashMap subAndSuper, ArrayList allCons, + ArrayList eqCons, String toSubs, String tph) { substituteTPH(allCons, toSubs, tph); - if(subAndSuper.containsKey(toSubs) && subAndSuper.containsKey(tph)) { + if (subAndSuper.containsKey(toSubs) && subAndSuper.containsKey(tph)) { toSubs = subAndSuper.remove(toSubs); EqualConstraint eq = new EqualConstraint(subAndSuper.get(tph), toSubs, Relation.EQUAL); eqCons.add(eq); - substituteInMap(subAndSuper, allCons,eqCons,toSubs, subAndSuper.get(tph)); - } else if(subAndSuper.containsKey(toSubs) && !subAndSuper.containsKey(tph)) { + substituteInMap(subAndSuper, allCons, eqCons, toSubs, subAndSuper.get(tph)); + } else if (subAndSuper.containsKey(toSubs) && !subAndSuper.containsKey(tph)) { String val = subAndSuper.remove(toSubs); subAndSuper.put(tph, val); } else { - for(String k : subAndSuper.keySet()) { + for (String k : subAndSuper.keySet()) { subAndSuper.replace(k, toSubs, tph); } } } private static TPHConstraint getConstraint(String oldRight, String right, ArrayList allCons) { - for(TPHConstraint c : allCons) { - if(c.getLeft().equals(oldRight) && c.getRight().equals(right)) + for (TPHConstraint c : allCons) { + if (c.getLeft().equals(oldRight) && c.getRight().equals(right)) return c; } return null; } private static boolean isTPHInResEqual(HashMap> result, String left) { - for(HashSet eq : result.values()) { - if(eq.contains(left)) { + for (HashSet eq : result.values()) { + if (eq.contains(left)) { return true; } } @@ -699,75 +762,77 @@ public class Simplify { private static void substituteAllTPH(ArrayList allCons, ArrayList constraints, String first) { - for(TPHConstraint c : allCons) { - for(TPHConstraint c2 : constraints) { - if(c.getRel() == Relation.EXTENDS) { - if(c2.getLeft().equals(c.getLeft()) || c2.getRight().equals(c.getLeft())) + for (TPHConstraint c : allCons) { + for (TPHConstraint c2 : constraints) { + if (c.getRel() == Relation.EXTENDS) { + if (c2.getLeft().equals(c.getLeft()) || c2.getRight().equals(c.getLeft())) c.setLeft(first); - if(c2.getLeft().equals(c.getRight()) || c2.getRight().equals(c.getRight())) + if (c2.getLeft().equals(c.getRight()) || c2.getRight().equals(c.getRight())) c.setRight(first); } - + } } } private static void setAllEqual(ArrayList constraints) { - for(TPHConstraint c:constraints) { + for (TPHConstraint c : constraints) { c.setRel(Relation.EQUAL); } } - public static HashMap> simplifyContraints(HashMap> allConstraints) { + public static HashMap> simplifyContraints( + HashMap> allConstraints) { // 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 => put all such TPhs in a map and define "key-Cons" - // -- key-Cons = TPH < Object -- - // put this Constraint and the - // b) no + // a) yes => 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 => put all such TPhs in a map and define "key-Cons" + // -- key-Cons = TPH < Object -- + // put this Constraint and the + // b) no // 3. is ArrayList allCons = new ArrayList<>(); - for(TPHConstraint tphCons : allConstraints.keySet()) { + for (TPHConstraint tphCons : allConstraints.keySet()) { allCons.add(tphCons); } ArrayList consToRemove = new ArrayList<>(); // step 1: - for(TPHConstraint c : allCons) { - + 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) { + 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); + substituteTPH(allCons, left, right); } } } System.out.println(); System.out.println("NEW ALL CONST: " + allCons.size()); - allCons.forEach(c->System.out.println(c.toString())); + allCons.forEach(c -> System.out.println(c.toString())); System.out.println("----------------"); allCons.removeAll(consToRemove); consToRemove = new ArrayList<>(); - + // int size = allCons.size(); - + System.out.println("AFTER DELETE ALL CONST: " + allCons.size()); - allCons.forEach(c->System.out.println(c.toString())); + allCons.forEach(c -> System.out.println(c.toString())); System.out.println("----------------"); HashMap> result = new HashMap<>(); - - for(TPHConstraint c : allCons) { - if(c.getRel()==Relation.EQUAL) { + + for (TPHConstraint c : allCons) { + if (c.getRel() == Relation.EQUAL) { HashSet equalTPHs = getEqualsTPHs(result, c); - TPHConstraint constraint = getKeyConstraint(result,c); + TPHConstraint constraint = getKeyConstraint(result, c); equalTPHs.add(c.getLeft()); equalTPHs.add(c.getRight()); result.put(constraint, equalTPHs); @@ -776,9 +841,9 @@ public class Simplify { } } System.out.println("Step 2 Result: "); - result.forEach((c,hs)->{ + result.forEach((c, hs) -> { System.out.print(c.toString() + " -> "); - hs.forEach(s->{ + hs.forEach(s -> { System.out.print(s + ", "); }); System.out.println(); @@ -786,33 +851,33 @@ public class Simplify { System.out.println("----------------"); allCons.removeAll(consToRemove); allCons.addAll(result.keySet()); - - if(!allCons.isEmpty() && allCons.size()<2) { - if(!result.containsKey(allCons.get(0))) + if (!allCons.isEmpty() && allCons.size() < 2) { + + if (!result.containsKey(allCons.get(0))) result.put(allCons.get(0), null); - + return result; } - + // size += result.keySet().size(); - + // for(TPHConstraint c : allCons) { // if(c.getRight().equals(Type.getInternalName(Object.class))) // size--; // } - + HashMap subAndSuper = new HashMap<>(); - - for(TPHConstraint c : allCons) { + + for (TPHConstraint c : allCons) { subAndSuper.put(c.getLeft(), c.getRight()); } - + // int numOfVisitedPairs = 0; - for(String sub : subAndSuper.keySet()) { - if(isTPHInConstraint(result,sub)) + for (String sub : subAndSuper.keySet()) { + if (isTPHInConstraint(result, sub)) continue; - + // if(numOfVisitedPairs>=size) // break; @@ -820,118 +885,137 @@ public class Simplify { tphInRel.add(sub); String superT = subAndSuper.get(sub); tphInRel.add(superT); - + // numOfVisitedPairs++; - while(subAndSuper.containsKey(superT)) { + while (subAndSuper.containsKey(superT)) { superT = subAndSuper.get(superT); - if(tphInRel.contains(superT)) { + if (tphInRel.contains(superT)) { break; } tphInRel.add(superT); // numOfVisitedPairs++; } - + // Subtype String subTphRes = tphInRel.getFirst(); // Die größte Supertype String superTphRes = tphInRel.getLast(); - - while(subAndSuper.containsValue(subTphRes)) { - for(String tph : subAndSuper.keySet()) { - if(subAndSuper.get(tph).equals(subTphRes)) { + + while (subAndSuper.containsValue(subTphRes)) { + for (String tph : subAndSuper.keySet()) { + if (subAndSuper.get(tph).equals(subTphRes)) { subTphRes = tph; break; } } - if(subTphRes.equals(tphInRel.getFirst())) { + if (subTphRes.equals(tphInRel.getFirst())) { break; } tphInRel.addFirst(subTphRes); // numOfVisitedPairs++; } - + subTphRes = tphInRel.getFirst(); - + int i = 2; - while(superTphRes.equals(Type.getInternalName(Object.class)) && (tphInRel.size()-i) >0) { - superTphRes = tphInRel.get(tphInRel.size()-i); + while (superTphRes.equals(Type.getInternalName(Object.class)) && (tphInRel.size() - i) > 0) { + superTphRes = tphInRel.get(tphInRel.size() - i); i++; } - if(superTphRes.equals(Type.getInternalName(Object.class))) { - result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null); + if (superTphRes.equals(Type.getInternalName(Object.class))) { + result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), + null); } else { result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null); - result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null); + result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), + null); } - + } System.out.println("EndResult: "); - result.forEach((c,hs)->{ - if(c!=null) { + result.forEach((c, hs) -> { + if (c != null) { System.out.print(c.toString() + " -> "); - if(hs == null) { + if (hs == null) { System.out.print(" [] "); - }else { - hs.forEach(s->{ + } else { + hs.forEach(s -> { System.out.print(s + ", "); }); } } - - + System.out.println(); }); System.out.println("----------------"); return result; } - - private static void substituteTPH(ArrayList allCons,String left ,String right) { - allCons.forEach(c->{ - if(c.getRel() == Relation.EXTENDS) { - if(c.getLeft().equals(left)) + + private static 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)) + if (c.getRight().equals(left)) c.setRight(right); } }); } private static TPHConstraint getReverseConstraint(ArrayList allCons, String left, String right) { - for(TPHConstraint c : allCons) { - if(c.getLeft().equals(right) && c.getRight().equals(left)){ + for (TPHConstraint c : allCons) { + if (c.getLeft().equals(right) && c.getRight().equals(left)) { return c; } } return null; } - + private static boolean isTPHInConstraint(HashMap> result, String sub) { - for(TPHConstraint c : result.keySet()) { - if(c.getLeft().equals(sub)) + for (TPHConstraint c : result.keySet()) { + if (c.getLeft().equals(sub)) return true; } return false; } private static boolean containTPH(ArrayList methodTphs, String sub) { - for(String tph : methodTphs) { - if(tph.equals(sub)) + for (String tph : methodTphs) { + if (tph.equals(sub)) return true; } return false; } - private static TPHConstraint getKeyConstraint(HashMap> result, TPHConstraint toFind) { - for(TPHConstraint c : result.keySet()) { - if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight())) + private static TPHConstraint getKeyConstraint(HashMap> result, TPHConstraint toFind, + ArrayList allCons) { + + for (TPHConstraint c : result.keySet()) { + if (c.containTPH(toFind.getLeft())) return c; } + for (TPHConstraint c : allCons) { + if (toFind.getRight().equals(c.getLeft())) + return c; + } + return new ExtendsConstraint(toFind.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS); } - private static HashSet getEqualsTPHs(HashMap> result, TPHConstraint toFind) { - for(TPHConstraint c : result.keySet()) { - if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight())) + private static 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 static 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<>(); diff --git a/src/test/java/bytecode/KompTphTest.java b/src/test/java/bytecode/KompTphTest.java new file mode 100644 index 000000000..8fca0c0ba --- /dev/null +++ b/src/test/java/bytecode/KompTphTest.java @@ -0,0 +1,37 @@ +package bytecode; + +import static org.junit.Assert.*; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; + +import org.junit.BeforeClass; +import org.junit.Test; + +import de.dhbwstuttgart.core.JavaTXCompiler; + +public class KompTphTest { + + private static String path; + private static File fileToTest; + private static JavaTXCompiler compiler; + private static ClassLoader loader; + private static Class classToTest; + private static String pathToClassFile; + private static Object instanceOfClass; + + @Test + public void generateBC() throws Exception { + path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/KompTph.jav"; + fileToTest = new File(path); + compiler = new JavaTXCompiler(fileToTest); + pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"; + compiler.generateBytecode(pathToClassFile); + loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); + classToTest = loader.loadClass("KompTph"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + +} diff --git a/src/test/resources/bytecode/javFiles/KompTph.jav b/src/test/resources/bytecode/javFiles/KompTph.jav new file mode 100644 index 000000000..ec34e154f --- /dev/null +++ b/src/test/resources/bytecode/javFiles/KompTph.jav @@ -0,0 +1,13 @@ +public class KompTph { + public m(a, b, c) { + var d = a; + var e = a; + a = b; + c = b; + m2(a,c); + } + + public m2(a,b){ + m(a,a,b); + } +} \ No newline at end of file