forked from JavaTX/JavaCompilerCore
Simpify Algo korrigiert so dass die lokalen Variablen der Methode beruecksichtigt werden
This commit is contained in:
parent
d010c843df
commit
3e186334a2
@ -5,6 +5,7 @@ package de.dhbwstuttgart.bytecode;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
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.bytecode.utilities.MethodAndTPH;
|
||||||
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
||||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
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.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
|
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
@ -26,7 +31,10 @@ public class TPHExtractor extends AbstractASTWalker{
|
|||||||
// alle TPHs der Klasse: (TPH, is in Method?)
|
// alle TPHs der Klasse: (TPH, is in Method?)
|
||||||
final HashMap<TypePlaceholder, Boolean> allTPHS = new HashMap<>();
|
final HashMap<TypePlaceholder, Boolean> allTPHS = new HashMap<>();
|
||||||
MethodAndTPH methodAndTph;
|
MethodAndTPH methodAndTph;
|
||||||
|
|
||||||
Boolean inMethod = false;
|
Boolean inMethod = false;
|
||||||
|
boolean inLocalOrParam = false;
|
||||||
|
|
||||||
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
||||||
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
|
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
|
||||||
public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
||||||
@ -44,8 +52,11 @@ public class TPHExtractor extends AbstractASTWalker{
|
|||||||
public void visit(TypePlaceholder tph) {
|
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;
|
TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType;
|
||||||
if(inMethod)
|
if (inMethod) {
|
||||||
methodAndTph.getTphs().add(resolvedTPH.getName());
|
methodAndTph.getTphs().add(resolvedTPH.getName());
|
||||||
|
if (inLocalOrParam)
|
||||||
|
methodAndTph.getLocalTphs().add(resolvedTPH.getName());
|
||||||
|
}
|
||||||
|
|
||||||
allTPHS.put(resolvedTPH, inMethod);
|
allTPHS.put(resolvedTPH, inMethod);
|
||||||
resultSet.resolveType(tph).additionalGenerics.forEach(ag -> {
|
resultSet.resolveType(tph).additionalGenerics.forEach(ag -> {
|
||||||
@ -59,6 +70,7 @@ public class TPHExtractor extends AbstractASTWalker{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
|
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
|
||||||
for (int i = 0; i < pairs.size(); ++i) {
|
for (int i = 0; i < pairs.size(); ++i) {
|
||||||
GenericInsertPair p = pairs.get(i);
|
GenericInsertPair p = pairs.get(i);
|
||||||
@ -67,6 +79,7 @@ public class TPHExtractor extends AbstractASTWalker{
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Method method) {
|
public void visit(Method method) {
|
||||||
inMethod = true;
|
inMethod = true;
|
||||||
@ -83,4 +96,25 @@ public class TPHExtractor extends AbstractASTWalker{
|
|||||||
inMethod = true;
|
inMethod = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LocalVarDecl localVarDecl) {
|
||||||
|
inLocalOrParam = true;
|
||||||
|
super.visit(localVarDecl);
|
||||||
|
inLocalOrParam = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LocalVar localVar) {
|
||||||
|
inLocalOrParam = true;
|
||||||
|
super.visit(localVar);
|
||||||
|
inLocalOrParam = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ParameterList formalParameters) {
|
||||||
|
inLocalOrParam = true;
|
||||||
|
super.visit(formalParameters);
|
||||||
|
inLocalOrParam = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
|
|
||||||
public class ConstraintsFinder {
|
public class ConstraintsFinder {
|
||||||
private List<TPHConstraint> allConstaints;
|
private List<TPHConstraint> allConstaints;
|
||||||
@ -18,11 +19,13 @@ public class ConstraintsFinder {
|
|||||||
|
|
||||||
List<TPHConstraint> visitedCons = new ArrayList<>();
|
List<TPHConstraint> visitedCons = new ArrayList<>();
|
||||||
for(TPHConstraint c : allConstaints) {
|
for(TPHConstraint c : allConstaints) {
|
||||||
|
if(c.getRel() == Relation.EXTENDS) {
|
||||||
// get constraints with the same left side
|
// get constraints with the same left side
|
||||||
List<TPHConstraint> cons = getConstraints(c,visitedCons);
|
List<TPHConstraint> cons = getConstraints(c,visitedCons);
|
||||||
if(cons.size()>1)
|
if(cons.size()>1)
|
||||||
result.add(cons);
|
result.add(cons);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ public class MethodAndTPH {
|
|||||||
private String name;
|
private String name;
|
||||||
private final ArrayList<String> tphs = new ArrayList<>();
|
private final ArrayList<String> tphs = new ArrayList<>();
|
||||||
private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
|
private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
|
||||||
|
// tphs of local variables and parameters
|
||||||
|
private final ArrayList<String> localTphs = new ArrayList<>();
|
||||||
|
|
||||||
public MethodAndTPH(String name) {
|
public MethodAndTPH(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -26,4 +28,9 @@ public class MethodAndTPH {
|
|||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArrayList<String> getLocalTphs() {
|
||||||
|
return localTphs;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,14 @@ public class NameReplacer {
|
|||||||
private List<TPHConstraint> constraints;
|
private List<TPHConstraint> constraints;
|
||||||
private List<TPHConstraint> allConstraints;
|
private List<TPHConstraint> allConstraints;
|
||||||
private List<String> tphs;
|
private List<String> tphs;
|
||||||
|
private List<String> localTphs;
|
||||||
|
|
||||||
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints,List<String> tphs) {
|
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints,List<String> tphs, ArrayList<String> localTphs) {
|
||||||
super();
|
super();
|
||||||
this.constraints = constraints;
|
this.constraints = constraints;
|
||||||
this.allConstraints = allConstraints;
|
this.allConstraints = allConstraints;
|
||||||
this.tphs = tphs;
|
this.tphs = tphs;
|
||||||
|
this.localTphs = localTphs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, List<String>> replaceNames() {
|
public Map<String, List<String>> replaceNames() {
|
||||||
@ -34,8 +36,11 @@ public class NameReplacer {
|
|||||||
if(names.contains(cons.getRight()))
|
if(names.contains(cons.getRight()))
|
||||||
cons.setRight(newName);
|
cons.setRight(newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
tphs.removeAll(names);
|
tphs.removeAll(names);
|
||||||
tphs.add(newName);
|
tphs.add(newName);
|
||||||
|
localTphs.removeAll(names);
|
||||||
|
localTphs.add(newName);
|
||||||
|
|
||||||
HashMap<String, List<String>> res = new HashMap<>();
|
HashMap<String, List<String>> res = new HashMap<>();
|
||||||
res.put(newName, names);
|
res.put(newName, names);
|
||||||
|
@ -18,13 +18,15 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|||||||
|
|
||||||
public class Simplify {
|
public class Simplify {
|
||||||
|
|
||||||
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor, ArrayList<TypePlaceholder> tphsClass) {
|
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor,
|
||||||
|
ArrayList<TypePlaceholder> tphsClass) {
|
||||||
// 1. check if there are any simple cycles like L<R and R<L:
|
// 1. check if there are any simple cycles like L<R and R<L:
|
||||||
// a) yes => set L=R and:
|
// a) yes => set L=R and:
|
||||||
// * remove both constraints
|
// * remove both constraints
|
||||||
// * substitute L with R in all constraint
|
// * substitute L with R in all constraint
|
||||||
// b)no => go to next step
|
// b)no => go to next step
|
||||||
// 2. check the result of step 1 if there are any equal-constraints like L=R, M=R ..
|
// 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"
|
// a) yes => put all such TPhs in a map and define "key-Cons"
|
||||||
// -- key-Cons = TPH < Object --
|
// -- key-Cons = TPH < Object --
|
||||||
// put this Constraint and the
|
// put this Constraint and the
|
||||||
@ -32,9 +34,26 @@ public class Simplify {
|
|||||||
// 3. is
|
// 3. is
|
||||||
|
|
||||||
// all constraints that will be simplified
|
// all constraints that will be simplified
|
||||||
ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
|
// ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
|
||||||
|
ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
||||||
|
|
||||||
|
for(TPHConstraint c : tphExtractor.allCons) {
|
||||||
|
TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel());
|
||||||
|
allCons.add(nc);
|
||||||
|
}
|
||||||
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
||||||
|
|
||||||
|
// get all tph of the method
|
||||||
|
ArrayList<String> methodTphs = new ArrayList<>();
|
||||||
|
ArrayList<String> localTphs = new ArrayList<>();
|
||||||
|
for (MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
||||||
|
if (m.getName().equals(name)) {
|
||||||
|
methodTphs = m.getTphs();
|
||||||
|
localTphs = m.getLocalTphs();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// step 1:
|
// step 1:
|
||||||
for (TPHConstraint c : allCons) {
|
for (TPHConstraint c : allCons) {
|
||||||
|
|
||||||
@ -135,7 +154,8 @@ public class Simplify {
|
|||||||
eq.add(t);
|
eq.add(t);
|
||||||
}
|
}
|
||||||
// generate a new constraint (left < Object)
|
// 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
|
// put the generated constraint and its equal set into result set
|
||||||
result.put(constraint, eq);
|
result.put(constraint, eq);
|
||||||
constraints.clear();
|
constraints.clear();
|
||||||
@ -143,23 +163,36 @@ public class Simplify {
|
|||||||
allTypes.clear();
|
allTypes.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (TPHConstraint ec : allCons) {
|
||||||
|
|
||||||
|
if(ec.getRel() == Relation.EQUAL) {
|
||||||
|
if(!localTphs.contains(ec.getRight())) {
|
||||||
|
localTphs.add(ec.getRight());
|
||||||
|
}
|
||||||
|
if(!methodTphs.contains(ec.getRight())) {
|
||||||
|
methodTphs.add(ec.getRight());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
// build an equal set that contains all types
|
// 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
|
// in this set Then generate a constraint type < Object and put it
|
||||||
// with the equal set into the result.
|
// with the equal set into the result.
|
||||||
for(TPHConstraint c : allCons) {
|
// for(TPHConstraint c : allCons) {
|
||||||
if(c.getRel()==Relation.EQUAL) {
|
// if(c.getRel()==Relation.EQUAL) {
|
||||||
if(!isTPHInResEqual(result, c.getLeft())) {
|
// if(!isTPHInResEqual(result, c.getLeft())) {
|
||||||
HashSet<String> equalTPHs = getEqualsTPHs(result, c);
|
// HashSet<String> equalTPHs = getEqualsTPHs(result, c);
|
||||||
TPHConstraint constraint = getKeyConstraint(result,c);
|
// TPHConstraint constraint = getKeyConstraint(result,c);
|
||||||
equalTPHs.add(c.getLeft());
|
// equalTPHs.add(c.getLeft());
|
||||||
equalTPHs.add(c.getRight());
|
// equalTPHs.add(c.getRight());
|
||||||
result.put(constraint, equalTPHs);
|
// result.put(constraint, equalTPHs);
|
||||||
}
|
// }
|
||||||
consToRemove.add(c);
|
// consToRemove.add(c);
|
||||||
size--;
|
// size--;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
System.out.println("Step 2 Result: ");
|
System.out.println("Step 2 Result: ");
|
||||||
result.forEach((c, hs) -> {
|
result.forEach((c, hs) -> {
|
||||||
@ -170,17 +203,14 @@ public class Simplify {
|
|||||||
System.out.println();
|
System.out.println();
|
||||||
});
|
});
|
||||||
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);
|
TPHConstraint cons = allCons.get(0);
|
||||||
if (!result.containsKey(cons)) {
|
if (!result.containsKey(cons)) {
|
||||||
result.put(cons, null);
|
result.put(cons, null);
|
||||||
if (!cons.getRight().equals(Type.getInternalName(Object.class)))
|
if (!cons.getRight().equals(Type.getInternalName(Object.class)))
|
||||||
result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class),
|
||||||
|
Relation.EXTENDS), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -193,14 +223,7 @@ public class Simplify {
|
|||||||
if (c.getRight().equals(Type.getInternalName(Object.class)))
|
if (c.getRight().equals(Type.getInternalName(Object.class)))
|
||||||
size--;
|
size--;
|
||||||
}
|
}
|
||||||
// get all tph of the method
|
|
||||||
ArrayList<String> 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
|
// finder looks for constraints that have the same left hand side
|
||||||
// and put them in a list
|
// and put them in a list
|
||||||
ConstraintsFinder finder = new ConstraintsFinder(allCons);
|
ConstraintsFinder finder = new ConstraintsFinder(allCons);
|
||||||
@ -211,7 +234,7 @@ public class Simplify {
|
|||||||
for (List<TPHConstraint> list : foundCons) {
|
for (List<TPHConstraint> list : foundCons) {
|
||||||
// generate a new name and replace the right hand side for each constraint
|
// generate a new name and replace the right hand side for each constraint
|
||||||
// in list with the new name
|
// 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]
|
// new name -> [all old names]
|
||||||
Map<String, List<String>> replRes = replacer.replaceNames();
|
Map<String, List<String>> replRes = replacer.replaceNames();
|
||||||
// create an equal constraint for each value in repres
|
// create an equal constraint for each value in repres
|
||||||
@ -220,7 +243,11 @@ public class Simplify {
|
|||||||
EqualConstraint ec = new EqualConstraint(val, key, Relation.EQUAL);
|
EqualConstraint ec = new EqualConstraint(val, key, Relation.EQUAL);
|
||||||
eqCons.add(ec);
|
eqCons.add(ec);
|
||||||
}
|
}
|
||||||
|
for (TPHConstraint c : allCons) {
|
||||||
|
if (c.getRel() == Relation.EQUAL && key.equals(c.getRight())) {
|
||||||
|
eqCons.add(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
updateEqualCons(replRes, eqCons);
|
updateEqualCons(replRes, eqCons);
|
||||||
|
|
||||||
TPHConstraint c = list.get(0);
|
TPHConstraint c = list.get(0);
|
||||||
@ -275,9 +302,24 @@ public class Simplify {
|
|||||||
HashMap<String, String> subAndSuper = new HashMap<>();
|
HashMap<String, String> subAndSuper = new HashMap<>();
|
||||||
|
|
||||||
for (TPHConstraint c : allCons) {
|
for (TPHConstraint c : allCons) {
|
||||||
|
if (c.getRel() == Relation.EXTENDS)
|
||||||
subAndSuper.put(c.getLeft(), c.getRight());
|
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;
|
int numOfVisitedPairs = 0;
|
||||||
for (String sub : subAndSuper.keySet()) {
|
for (String sub : subAndSuper.keySet()) {
|
||||||
if (isTPHInConstraint(result, sub))
|
if (isTPHInConstraint(result, sub))
|
||||||
@ -294,7 +336,7 @@ public class Simplify {
|
|||||||
tphInRel.add(superT);
|
tphInRel.add(superT);
|
||||||
|
|
||||||
numOfVisitedPairs++;
|
numOfVisitedPairs++;
|
||||||
while(subAndSuper.containsKey(superT)) {
|
while (!localTphs.contains(superT) && subAndSuper.containsKey(superT)) {
|
||||||
superT = subAndSuper.get(superT);
|
superT = subAndSuper.get(superT);
|
||||||
if (tphInRel.contains(superT)) {
|
if (tphInRel.contains(superT)) {
|
||||||
break;
|
break;
|
||||||
@ -310,7 +352,7 @@ public class Simplify {
|
|||||||
|
|
||||||
// if there is any constraint X < subTph, then
|
// if there is any constraint X < subTph, then
|
||||||
// add X at the beginning of the list.
|
// add X at the beginning of the list.
|
||||||
while(subAndSuper.containsValue(subTphRes)) {
|
while (!localTphs.contains(subTphRes) && subAndSuper.containsValue(subTphRes)) {
|
||||||
for (String tph : subAndSuper.keySet()) {
|
for (String tph : subAndSuper.keySet()) {
|
||||||
if (containTPH(methodTphs, tph) && subAndSuper.get(tph).equals(subTphRes)) {
|
if (containTPH(methodTphs, tph) && subAndSuper.get(tph).equals(subTphRes)) {
|
||||||
subTphRes = tph;
|
subTphRes = tph;
|
||||||
@ -343,7 +385,8 @@ public class Simplify {
|
|||||||
if (classTPHSContainsTPH(tphsClass, superTphRes)) {
|
if (classTPHSContainsTPH(tphsClass, superTphRes)) {
|
||||||
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
|
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
@ -351,18 +394,43 @@ public class Simplify {
|
|||||||
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
|
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
|
||||||
if (!isTPHInConstraint(result, superTphRes) && !isTphInEqualSet(result, superTphRes)) {
|
if (!isTPHInConstraint(result, superTphRes) && !isTphInEqualSet(result, superTphRes)) {
|
||||||
HashSet<String> equals2 = getEqualsTphsFromEqualCons(eqCons, superTphRes);
|
HashSet<String> equals2 = getEqualsTphsFromEqualCons(eqCons, superTphRes);
|
||||||
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), equals2);
|
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS),
|
||||||
|
equals2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(String tph : methodTphs) {
|
// for(String tph : methodTphs) {
|
||||||
|
for (String tph : localTphs) {
|
||||||
if (!isTPHInConstraint(result, tph) && !isTphInEqualSet(result, tph)) {
|
if (!isTPHInConstraint(result, tph) && !isTphInEqualSet(result, tph)) {
|
||||||
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons, tph);
|
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons, tph);
|
||||||
result.put(new ExtendsConstraint(tph, Type.getInternalName(Object.class), Relation.EXTENDS), equals);
|
result.put(new ExtendsConstraint(tph, Type.getInternalName(Object.class), Relation.EXTENDS), equals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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<String> 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());
|
||||||
|
|
||||||
System.out.println("EndResult: ");
|
System.out.println("EndResult: ");
|
||||||
result.forEach((c, hs) -> {
|
result.forEach((c, hs) -> {
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
@ -376,14 +444,12 @@ public class Simplify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
System.out.println();
|
System.out.println();
|
||||||
});
|
});
|
||||||
System.out.println("----------------");
|
System.out.println("----------------");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void updateEqualCons(Map<String, List<String>> replRes, ArrayList<TPHConstraint> eqCons) {
|
private static void updateEqualCons(Map<String, List<String>> replRes, ArrayList<TPHConstraint> eqCons) {
|
||||||
List<String> oldNames = replRes.values().iterator().next();
|
List<String> oldNames = replRes.values().iterator().next();
|
||||||
String newName = replRes.keySet().iterator().next();
|
String newName = replRes.keySet().iterator().next();
|
||||||
@ -396,8 +462,8 @@ public class Simplify {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraintsClass(TPHExtractor tphExtractor,
|
||||||
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraintsClass(TPHExtractor tphExtractor, ArrayList<TypePlaceholder> tphsClass) {
|
ArrayList<TypePlaceholder> tphsClass) {
|
||||||
// all constraints that will be simplified
|
// all constraints that will be simplified
|
||||||
ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
|
ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
|
||||||
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
||||||
@ -421,7 +487,6 @@ public class Simplify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
allCons.removeAll(consToRemove);
|
allCons.removeAll(consToRemove);
|
||||||
consToRemove = new ArrayList<>();
|
consToRemove = new ArrayList<>();
|
||||||
|
|
||||||
@ -496,7 +561,8 @@ public class Simplify {
|
|||||||
eq.add(t);
|
eq.add(t);
|
||||||
}
|
}
|
||||||
// generate a new constraint (left < Object)
|
// 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
|
// put the generated constraint and its equal set into result set
|
||||||
result.put(constraint, eq);
|
result.put(constraint, eq);
|
||||||
constraints.clear();
|
constraints.clear();
|
||||||
@ -531,7 +597,8 @@ public class Simplify {
|
|||||||
TPHConstraint cons = allCons.get(0);
|
TPHConstraint cons = allCons.get(0);
|
||||||
if (!result.containsKey(cons)) {
|
if (!result.containsKey(cons)) {
|
||||||
result.put(cons, null);
|
result.put(cons, null);
|
||||||
result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
result.put(new ExtendsConstraint(cons.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS),
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -607,8 +674,6 @@ public class Simplify {
|
|||||||
|
|
||||||
subTphRes = tphInRel.getFirst();
|
subTphRes = tphInRel.getFirst();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons, superTphRes);
|
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons, superTphRes);
|
||||||
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
|
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
|
||||||
|
|
||||||
@ -627,14 +692,12 @@ public class Simplify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
System.out.println();
|
System.out.println();
|
||||||
});
|
});
|
||||||
System.out.println("----------------");
|
System.out.println("----------------");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static boolean classTPHSContainsTPH(ArrayList<TypePlaceholder> tphsClass, String superTphRes) {
|
private static boolean classTPHSContainsTPH(ArrayList<TypePlaceholder> tphsClass, String superTphRes) {
|
||||||
for (TypePlaceholder tph : tphsClass) {
|
for (TypePlaceholder tph : tphsClass) {
|
||||||
if (tph.getName().equals(superTphRes))
|
if (tph.getName().equals(superTphRes))
|
||||||
@ -662,8 +725,8 @@ public class Simplify {
|
|||||||
return ee;
|
return ee;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void substituteInMap(HashMap<String, String> subAndSuper, ArrayList<TPHConstraint> allCons,ArrayList<TPHConstraint> eqCons, String toSubs,
|
private static void substituteInMap(HashMap<String, String> subAndSuper, ArrayList<TPHConstraint> allCons,
|
||||||
String tph) {
|
ArrayList<TPHConstraint> eqCons, String toSubs, String tph) {
|
||||||
substituteTPH(allCons, toSubs, tph);
|
substituteTPH(allCons, toSubs, tph);
|
||||||
if (subAndSuper.containsKey(toSubs) && subAndSuper.containsKey(tph)) {
|
if (subAndSuper.containsKey(toSubs) && subAndSuper.containsKey(tph)) {
|
||||||
toSubs = subAndSuper.remove(toSubs);
|
toSubs = subAndSuper.remove(toSubs);
|
||||||
@ -718,13 +781,15 @@ public class Simplify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HashMap<TPHConstraint, HashSet<String>> simplifyContraints(HashMap<TPHConstraint, HashSet<String>> allConstraints) {
|
public static HashMap<TPHConstraint, HashSet<String>> simplifyContraints(
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> allConstraints) {
|
||||||
// 1. check if there are any cycles like L<R and R<L:
|
// 1. check if there are any cycles like L<R and R<L:
|
||||||
// a) yes => set L=R and:
|
// a) yes => set L=R and:
|
||||||
// * remove both constraints
|
// * remove both constraints
|
||||||
// * substitute L with R in all constraint
|
// * substitute L with R in all constraint
|
||||||
// b)no => go to next step
|
// b)no => go to next step
|
||||||
// 2. check the result of step 1 if there are any equal-constraints like L=R, M=R ..
|
// 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"
|
// a) yes => put all such TPhs in a map and define "key-Cons"
|
||||||
// -- key-Cons = TPH < Object --
|
// -- key-Cons = TPH < Object --
|
||||||
// put this Constraint and the
|
// put this Constraint and the
|
||||||
@ -858,10 +923,12 @@ public class Simplify {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (superTphRes.equals(Type.getInternalName(Object.class))) {
|
if (superTphRes.equals(Type.getInternalName(Object.class))) {
|
||||||
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS),
|
||||||
|
null);
|
||||||
} else {
|
} else {
|
||||||
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -878,7 +945,6 @@ public class Simplify {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
System.out.println();
|
System.out.println();
|
||||||
});
|
});
|
||||||
System.out.println("----------------");
|
System.out.println("----------------");
|
||||||
@ -921,11 +987,29 @@ public class Simplify {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TPHConstraint getKeyConstraint(HashMap<TPHConstraint, HashSet<String>> result, TPHConstraint toFind) {
|
private static TPHConstraint getKeyConstraint(HashMap<TPHConstraint, HashSet<String>> result, TPHConstraint toFind,
|
||||||
|
ArrayList<TPHConstraint> 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 TPHConstraint getKeyConstraint(HashMap<TPHConstraint, HashSet<String>> result,
|
||||||
|
TPHConstraint toFind) {
|
||||||
|
|
||||||
for (TPHConstraint c : result.keySet()) {
|
for (TPHConstraint c : result.keySet()) {
|
||||||
if (c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight()))
|
if (c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight()))
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ExtendsConstraint(toFind.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS);
|
return new ExtendsConstraint(toFind.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
src/test/java/bytecode/KompTphTest.java
Normal file
37
src/test/java/bytecode/KompTphTest.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
13
src/test/resources/bytecode/javFiles/KompTph.jav
Normal file
13
src/test/resources/bytecode/javFiles/KompTph.jav
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user