Genericsgenerator step 2 and 3

This commit is contained in:
Fayez Abu Alia 2019-07-11 15:52:38 +02:00
parent d77f2176f2
commit 347d86a379
12 changed files with 414 additions and 48 deletions

View File

@ -119,7 +119,7 @@ public class TPHExtractor extends AbstractASTWalker {
private static boolean containsConstraint(ArrayList<TPHConstraint> allCons, TPHConstraint c) {
for(TPHConstraint con:allCons) {
if(c.getLeft().equals(con.getLeft()) && c.getRight().equals(c.getRight())) {
if(c.getLeft().equals(con.getLeft()) && c.getRight().equals(con.getRight())) {
return true;
}
}

View File

@ -0,0 +1,31 @@
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.List;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
public class ConstraintsWithSameLeftSide {
private List<TPHConstraint> constraints;
/**
* @param constraints
*/
public ConstraintsWithSameLeftSide(List<TPHConstraint> constraints) {
this.constraints = constraints;
}
/**
* @return the constraints
*/
public List<TPHConstraint> getConstraints() {
return constraints;
}
/**
* @param constraints the constraints to set
*/
public void setConstraints(List<TPHConstraint> constraints) {
this.constraints = constraints;
}
}

View File

@ -4,8 +4,10 @@
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
@ -17,60 +19,116 @@ import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
*/
public class CyclesFinder {
private final List<TPHConstraint> allCons;
public CyclesFinder(List<TPHConstraint> allCons) {
this.allCons = allCons;
}
public List<SimpleCycle> findSimpleCycles() {
List<SimpleCycle> simpleCycles = new ArrayList<>();
allCons.forEach(c->{
allCons.forEach(c -> {
String left = c.getLeft();
String right = c.getRight();
if (c.getRel() == Relation.EXTENDS && !containsInCycle(c,simpleCycles)) {
if (c.getRel() == Relation.EXTENDS && !containsInCycle(c, simpleCycles)) {
Optional<TPHConstraint> revCon = GenericsGeneratorUtility.getReverseConstraint(allCons, left, right);
if(revCon.isPresent()) {
if (revCon.isPresent()) {
TPHConstraint reverseConstraint = revCon.get();
SimpleCycle simpleCycle = new SimpleCycle(c, reverseConstraint);
simpleCycles.add(simpleCycle);
}
}
});
return simpleCycles;
}
private boolean containsInCycle(TPHConstraint c, List<SimpleCycle> simpleCycles) {
return simpleCycles.stream().filter(sc->{
return simpleCycles.stream().filter(sc -> {
return sc.contains(c);
}).count() > 0;
}
public List<LongCycle> findLongCycles() {
List<TPHConstraint> vistedConstraints = new ArrayList<>(allCons.size());
List<LongCycle> longCycles = new ArrayList<>();
Map<String, String> tableOfConstraints = createConstraintsTable();
for (TPHConstraint constraint : allCons) {
if (!vistedConstraints.contains(constraint)) {
vistedConstraints.add(constraint);
checkConstraint(constraint, vistedConstraints, longCycles, tableOfConstraints);
}
}
return longCycles;
}
private void checkConstraint(TPHConstraint constraint, List<TPHConstraint> vistedConstraints,
List<LongCycle> longCycles, Map<String, String> tableOfConstraints) {
List<String> tphsInRelation = new LinkedList<>();
List<TPHConstraint> maybeCycle = new ArrayList<>();
maybeCycle.add(constraint);
tphsInRelation.add(constraint.getLeft());
tphsInRelation.add(constraint.getRight());
Optional<TPHConstraint> nextConstraint = getConstraintInRelation(tphsInRelation, maybeCycle);
while (nextConstraint.isPresent()) {
if(containsInLongCycle(nextConstraint.get(), longCycles)) {
break;
}
nextConstraint = getConstraintInRelation(tphsInRelation, maybeCycle);
if (isCycle(tphsInRelation)) {
addAllToVisitedConstraints(vistedConstraints, maybeCycle);
LongCycle cycle = new LongCycle(maybeCycle);
longCycles.add(cycle);
return;
}
}
addAllToVisitedConstraints(vistedConstraints, maybeCycle);
}
private boolean containsInLongCycle(TPHConstraint c, List<LongCycle> longCycles) {
for(LongCycle cycle : longCycles) {
if(cycle.containConstraint(c))
return true;
}
return false;
}
private void addAllToVisitedConstraints(List<TPHConstraint> vistedConstraints, List<TPHConstraint> maybeCycle) {
for (TPHConstraint con : maybeCycle) {
if (!vistedConstraints.contains(con))
vistedConstraints.add(con);
}
}
private Optional<TPHConstraint> getConstraintInRelation(List<String> tphsInRelation,
List<TPHConstraint> maybeCycle) {
TPHConstraint constraint = getConstraintByLeftSide(tphsInRelation.get(tphsInRelation.size()-1));
Optional<TPHConstraint> nextConstraint = Optional.ofNullable(constraint);
if(nextConstraint.isPresent()) {
maybeCycle.add(constraint);
tphsInRelation.add(constraint.getRight());
}
return nextConstraint;
}
private TPHConstraint getConstraintByLeftSide(String left) {
for(TPHConstraint constraint : allCons) {
vistedConstraints.add(constraint);
checkConstraint(constraint,vistedConstraints);
if(constraint.getLeft().equals(left))
return constraint;
}
return null;
}
private void checkConstraint(TPHConstraint constraint, List<TPHConstraint> vistedConstraints) {
List<String> tphsInRelation = new LinkedList<>();
tphsInRelation.add(constraint.getLeft());
tphsInRelation.add(constraint.getRight());
for(TPHConstraint con : allCons) {
if(!vistedConstraints.contains(con)) {
String left = con.getLeft();
String right = con.getRight();
int lastIndex = tphsInRelation.size()-1;
if(left.equals(tphsInRelation.get(lastIndex))) {
tphsInRelation.add(right);
}
}
private Map<String, String> createConstraintsTable() {
Map<String, String> table = new HashMap<>();
for (TPHConstraint constraint : allCons) {
table.put(constraint.getLeft(), constraint.getRight());
}
return table;
}
private boolean isCycle(List<String> tphsInRelation) {
return tphsInRelation.get(0).equals(tphsInRelation.get(tphsInRelation.size() - 1));
}
}

View File

@ -10,11 +10,14 @@ import java.util.Optional;
import java.util.Set;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.EqualConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.simplifyRes.GenericsGeneratorResult;
import de.dhbwstuttgart.bytecode.utilities.ConstraintsFinder;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
import de.dhbwstuttgart.bytecode.utilities.NameReplacer;
import de.dhbwstuttgart.syntaxtree.Method;
/**
@ -25,12 +28,11 @@ public class GenericsGenerator {
public static List<GenericsGeneratorResult> generateConstraintsForMethod(Method method, TPHExtractor tphExtractor,
List<String> tphsClass) {
List<GenericsGeneratorResult> genericsGeneratorResults = new ArrayList<>();
List<TPHConstraint> allCons = tphExtractor.allCons;
String methodID = MethodUtility.createID(tphExtractor.getResolver(), method);
List<String> methodTPHS = GenericsGeneratorUtility.getMethodTPHS(methodID ,tphExtractor.ListOfMethodsAndTph);
List<TPHConstraint> consToRemove = new ArrayList<>();
CyclesFinder cyclesFinder = new CyclesFinder(allCons);
/* find all simple cycles if they are exist */
List<SimpleCycle> simpleCycles = cyclesFinder.findSimpleCycles();
@ -39,11 +41,21 @@ public class GenericsGenerator {
GenericsGeneratorUtility.modifyRelation(simpleCycles);
GenericsGeneratorUtility.removeAllReverseConstraints(allCons,simpleCycles);
GenericsGeneratorUtility.substituteTPH(allCons, simpleCycles);
GenericsGeneratorUtility.removeEqualConstraints(allCons);
}
/* Step 2 */
List<ConstraintsWithSameLeftSide> foundCons = GenericsGeneratorUtility.findConstraintsWithLeftSameLeftSide(allCons);
GenericsGeneratorUtility.simplifyConstraintsWithSameLeftSide(foundCons,allCons,methodTPHS);
/* find all long cycles */
List<LongCycle> longCycles = cyclesFinder.findLongCycles();
if(!longCycles.isEmpty()) {
GenericsGeneratorUtility.modifyRelationForConstraintsinLongCycle(longCycles);
List<NameReplacementResult> nameReplacementResults = GenericsGeneratorUtility.substituteTPHSFormLongCycle(allCons, longCycles);
GenericsGeneratorUtility.createResults(genericsGeneratorResults,nameReplacementResults);
}
return null;
}

View File

@ -4,12 +4,22 @@
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.constraint.EqualConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.simplifyRes.GenericsGeneratorResult;
import de.dhbwstuttgart.bytecode.utilities.ConstraintsFinder;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.bytecode.utilities.NameReplacer;
/**
* @author fayez
@ -73,4 +83,125 @@ public class GenericsGeneratorUtility {
public static void substituteTPH(List<TPHConstraint> allCons, List<SimpleCycle> simpleCycles) {
simpleCycles.forEach(sc->substituteTPH(allCons, sc.getConstraint().getLeft(), sc.getConstraint().getRight()));
}
public static List<ConstraintsWithSameLeftSide> findConstraintsWithLeftSameLeftSide(List<TPHConstraint> allCons) {
// finder looks for constraints that have the same left hand side
// and put them in a list
ConstraintsFinder finder = new ConstraintsFinder(allCons);
List<ConstraintsWithSameLeftSide> foundCons = finder.findConstraints();
return foundCons;
}
public static void simplifyConstraintsWithSameLeftSide(List<ConstraintsWithSameLeftSide> consWithSameLeftSide,
List<TPHConstraint> allCons, List<String> methodTPHS) {
List<TPHConstraint> eqCons = new ArrayList<>();
for (ConstraintsWithSameLeftSide list : consWithSameLeftSide) {
NameReplacementResult replRes = modifyNames(allCons, methodTPHS, list);
createEqualConstraintsForNames(replRes.getName(), replRes.getOldNames(),eqCons);
for (TPHConstraint c : allCons) {
if (c.getRel() == Relation.EQUAL && replRes.getName().equals(c.getRight())) {
eqCons.add(c);
}
}
updateEqualCons(replRes, eqCons);
TPHConstraint c = list.getConstraints().get(0);
allCons.removeAll(list.getConstraints());
allCons.add(c);
}
}
private static void createEqualConstraintsForNames(String name, List<String> equalNames, List<TPHConstraint> eqCons) {
// create an equal constraint for each value in repres
for (String eName : equalNames) {
EqualConstraint ec = new EqualConstraint(eName, name, Relation.EQUAL);
eqCons.add(ec);
}
}
/**
* @param allCons
* @param methodTPHS
* @param list
* @return
*/
public static NameReplacementResult modifyNames(List<TPHConstraint> allCons, List<String> methodTPHS,
ConstraintsWithSameLeftSide list) {
// generate a new name and replace the right hand side for each constraint
// in list with the new name
NameReplacer replacer = new NameReplacer(list.getConstraints(), allCons, methodTPHS);
// new name -> [all old names]
NameReplacementResult replRes = replacer.replaceNames();
return replRes;
}
public static void updateEqualCons(NameReplacementResult nameReplacementResult, List<TPHConstraint> eqCons) {
List<String> oldNames = nameReplacementResult.getOldNames();
String newName = nameReplacementResult.getName();
for (TPHConstraint c : eqCons) {
// if(oldNames.contains(c.getLeft()))
// c.setLeft(newName);
if (oldNames.contains(c.getRight()))
c.setRight(newName);
}
}
public static void modifyRelationForConstraintsinLongCycle(List<LongCycle> longCycles) {
longCycles.stream().map(lc->lc.getConstraints()).flatMap(e->e.stream()).forEach(c->c.setRel(Relation.EQUAL));
}
public static List<NameReplacementResult> substituteTPHSFormLongCycle(List<TPHConstraint> allCons, List<LongCycle> longCycles) {
List<NameReplacementResult> results = new ArrayList<>();
longCycles.forEach(lc->{
Set<String> names = getNamesFromCycle(lc);
String newName = names.stream().findFirst().get();
List<String> equalNames = new ArrayList<>(names);
NameReplacementResult res = new NameReplacementResult(newName, equalNames);
results.add(res);
substituteAll(allCons,names,newName);
});
return results;
}
public static void substituteAll(List<TPHConstraint> allCons, Set<String> names, String newName) {
allCons.stream()
.filter(c-> c.getRel()==Relation.EXTENDS)
.forEach(c->{
if(names.contains(c.getLeft())) {
c.setLeft(newName);
} else if(names.contains(c.getRight())) {
c.setRight(newName);
}
});
}
public static Set<String> getNamesFromCycle(LongCycle lc) {
Set<String> names = new HashSet<>();
lc.getConstraints().forEach(c->names.add(c.getLeft()));
return names;
}
public static void createResults(List<GenericsGeneratorResult> genericsGeneratorResults,
List<NameReplacementResult> nameReplacementResults) {
nameReplacementResults.forEach(n->{
Set<String> equals = new HashSet<>(n.getOldNames());
TPHConstraint cons = new EqualConstraint(n.getName(), Type.getInternalName(Object.class), Relation.EXTENDS);
GenericsGeneratorResult ggRes = new GenericsGeneratorResult(cons, equals);
genericsGeneratorResults.add(ggRes);
});
}
public static void removeEqualConstraints(List<TPHConstraint> allCons) {
List<TPHConstraint> equalConstraints = getEqualConstraints(allCons);
allCons.removeAll(equalConstraints);
}
public static List<TPHConstraint> getEqualConstraints(List<TPHConstraint> allCons) {
return allCons.stream().filter(c->c.getRel()==Relation.EQUAL).collect(Collectors.toList());
}
}

View File

@ -35,4 +35,12 @@ public class LongCycle {
}
return false;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
constraints.forEach(c->sb.append(c.getLeft()+" -> "));
sb.append(constraints.get(constraints.size()-1).getRight());
return sb.toString();
}
}

View File

@ -0,0 +1,49 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.List;
/**
* @author fayez
*
*/
public class NameReplacementResult {
private String name;
private List<String> oldNames;
/**
* @param name
* @param oldNames
*/
public NameReplacementResult(String name, List<String> oldNames) {
this.name = name;
this.oldNames = oldNames;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the oldNames
*/
public List<String> getOldNames() {
return oldNames;
}
/**
* @param oldNames the oldNames to set
*/
public void setOldNames(List<String> oldNames) {
this.oldNames = oldNames;
};
}

View File

@ -5,25 +5,27 @@ import java.util.List;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.genericsGenerator.ConstraintsWithSameLeftSide;
public class ConstraintsFinder {
private List<TPHConstraint> allConstaints;
public ConstraintsFinder(List<TPHConstraint> allConstaints) {
super();
this.allConstaints = allConstaints;
}
public List<List<TPHConstraint>> findConstraints() {
List<List<TPHConstraint>> result = new ArrayList<>();
public List<ConstraintsWithSameLeftSide> findConstraints() {
List<ConstraintsWithSameLeftSide> result = new ArrayList<>();
List<TPHConstraint> visitedCons = new ArrayList<>();
for(TPHConstraint c : allConstaints) {
if(c.getRel() == Relation.EXTENDS) {
// get constraints with the same left side
List<TPHConstraint> cons = getConstraints(c,visitedCons);
if(cons.size()>1)
result.add(cons);
if(cons.size()>1) {
ConstraintsWithSameLeftSide consWithSameLeftSide = new ConstraintsWithSameLeftSide(cons);
result.add(consWithSameLeftSide);
}
}
}

View File

@ -6,6 +6,7 @@ import java.util.List;
import java.util.Map;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.genericsGenerator.NameReplacementResult;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
public class NameReplacer {
@ -22,7 +23,53 @@ public class NameReplacer {
this.localTphs = localTphs;
}
public Map<String, List<String>> replaceNames() {
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints,List<String> tphs) {
super();
this.constraints = constraints;
this.allConstraints = allConstraints;
this.tphs = tphs;
}
public NameReplacementResult replaceNames() {
String newName = NameGenerator.makeNewName();
List<String> names = new ArrayList<>();
substituteRightSidesWithNewName(newName, names);
substituteNamesInAllConstraints(newName, names);
tphs.removeAll(names);
tphs.add(newName);
NameReplacementResult res = new NameReplacementResult(newName, names);
return res;
}
/**
* @param newName
* @param names
*/
public void substituteNamesInAllConstraints(String newName, List<String> names) {
for(TPHConstraint cons : allConstraints) {
if(names.contains(cons.getLeft()))
cons.setLeft(newName);
if(names.contains(cons.getRight()))
cons.setRight(newName);
}
}
/**
* @param newName
* @param names
*/
public void substituteRightSidesWithNewName(String newName, List<String> names) {
for(TPHConstraint cons : constraints) {
names.add(cons.getRight());
cons.setRight(newName);
}
}
public Map<String, List<String>> replaceNamesWithLocals() {
String newName = NameGenerator.makeNewName();
ArrayList<String> names = new ArrayList<>();
for(TPHConstraint cons : constraints) {

View File

@ -15,6 +15,9 @@ 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.bytecode.genericsGenerator.ConstraintsWithSameLeftSide;
import de.dhbwstuttgart.bytecode.genericsGenerator.GenericsGeneratorUtility;
import de.dhbwstuttgart.bytecode.genericsGenerator.NameReplacementResult;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
@ -232,19 +235,19 @@ public class Simplify {
// finder looks for constraints that have the same left hand side
// and put them in a list
ConstraintsFinder finder = new ConstraintsFinder(allCons);
List<List<TPHConstraint>> foundCons = finder.findConstraints();
List<ConstraintsWithSameLeftSide> foundCons = finder.findConstraints();
ArrayList<TPHConstraint> eqCons = new ArrayList<>();
for (List<TPHConstraint> list : foundCons) {
for (ConstraintsWithSameLeftSide 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, localTphs);
NameReplacer replacer = new NameReplacer(list.getConstraints(), allCons, methodTphs, localTphs);
// new name -> [all old names]
Map<String, List<String>> replRes = replacer.replaceNames();
NameReplacementResult 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()) {
String key = replRes.getName();
for (String val : replRes.getOldNames()) {
EqualConstraint ec = new EqualConstraint(val, key, Relation.EQUAL);
eqCons.add(ec);
}
@ -253,10 +256,10 @@ public class Simplify {
eqCons.add(c);
}
}
updateEqualCons(replRes, eqCons);
GenericsGeneratorUtility.updateEqualCons(replRes, eqCons);
TPHConstraint c = list.get(0);
allCons.removeAll(list);
TPHConstraint c = list.getConstraints().get(0);
allCons.removeAll(list.getConstraints());
allCons.add(c);
}

View File

@ -1,8 +1,25 @@
public class SimpleCycle {
m(a,b){
a = b;
m(a,b,d){
var g;
var h;
g = h;
h = g;
var y;
var z;
y=z;
z=y;
var j = z;
var x;
b = a;
var c = b;
var f = d;
b = x;
var l = c;
a = l;
}
}

View File

@ -1,9 +1,10 @@
import java.util.Vector;
import java.lang.Integer;
import java.lang.String;
//import java.lang.Byte;
//import java.lang.Boolean;
import java.lang.Byte;
import java.lang.Boolean;
//import java.util.Vector;
//import java.util.Collection;
/*
public class VectorAdd {
@ -29,5 +30,12 @@ public class VectorAdd {
i++;
}
return erg;
}
}
//addEle(z) {
// var x;
// var y;
// x.add(y);
// z = x;
}
}