forked from JavaTX/JavaCompilerCore
(Transivitaet) Algorithmus funktioniert
This commit is contained in:
parent
35696efd1c
commit
623705d38a
@ -26,6 +26,7 @@ import de.dhbwstuttgart.bytecode.signature.TypeToString;
|
|||||||
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
||||||
@ -61,8 +62,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
||||||
// stores generics and their bounds of class
|
// stores generics and their bounds of class
|
||||||
HashMap<String, String> genericsAndBounds = new HashMap<>();
|
HashMap<String, String> genericsAndBounds = new HashMap<>();
|
||||||
// stores generics and their bounds of method
|
|
||||||
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
|
||||||
|
|
||||||
private final TPHExtractor tphExtractor = new TPHExtractor();
|
private final TPHExtractor tphExtractor = new TPHExtractor();
|
||||||
private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>();
|
private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>();
|
||||||
@ -185,6 +185,10 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
System.out.println(a.getLeft().toString() + " = " + a.getRight().toString());
|
System.out.println(a.getLeft().toString() + " = " + a.getRight().toString());
|
||||||
});
|
});
|
||||||
System.out.println("---------------");
|
System.out.println("---------------");
|
||||||
|
|
||||||
|
// stores generics and their bounds of method
|
||||||
|
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
||||||
|
|
||||||
field.getParameterList().accept(this);
|
field.getParameterList().accept(this);
|
||||||
|
|
||||||
String methParamTypes = field.name+"%%";
|
String methParamTypes = field.name+"%%";
|
||||||
@ -215,8 +219,8 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
}
|
}
|
||||||
String sig = null;
|
String sig = null;
|
||||||
if(hasGen) {
|
if(hasGen) {
|
||||||
ArrayList<GenericInsertPair> pairs = simplifyPairs(field.name,tphExtractor.allPairs, tphExtractor.allCons);
|
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor);
|
||||||
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,pairs);
|
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
||||||
sig = signature.toString();
|
sig = signature.toString();
|
||||||
}
|
}
|
||||||
NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen);
|
NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen);
|
||||||
@ -253,6 +257,8 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
}
|
}
|
||||||
methodNameAndParamsT.add(methParamTypes);
|
methodNameAndParamsT.add(methParamTypes);
|
||||||
System.out.println("Method: "+method.name +" , paramsType: "+methParamTypes);
|
System.out.println("Method: "+method.name +" , paramsType: "+methParamTypes);
|
||||||
|
// stores generics and their bounds of method
|
||||||
|
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
||||||
String methDesc = null;
|
String methDesc = null;
|
||||||
|
|
||||||
// Method getModifiers() ?
|
// Method getModifiers() ?
|
||||||
@ -287,11 +293,9 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
System.out.println("ALL CONST: " + tphExtractor.allCons.size());
|
System.out.println("ALL CONST: " + tphExtractor.allCons.size());
|
||||||
tphExtractor.allCons.forEach(c->System.out.println(c.toString()));
|
tphExtractor.allCons.forEach(c->System.out.println(c.toString()));
|
||||||
System.out.println("----------------");
|
System.out.println("----------------");
|
||||||
HashMap<TPHConstraint, HashSet<String>> constraints = simplifyPairs(method.name,tphExtractor.allCons);
|
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name, tphExtractor);
|
||||||
ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons);
|
// ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons);
|
||||||
System.out.println(method.name + " => Simplified Pairs: ");
|
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
||||||
pairs.forEach(p->System.out.println(p.TA1.getName() + " -> "+p.TA2.getName()));
|
|
||||||
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet, pairs);
|
|
||||||
sig = signature.toString();
|
sig = signature.toString();
|
||||||
}
|
}
|
||||||
System.out.println(method.getName()+" ==> "+sig);
|
System.out.println(method.getName()+" ==> "+sig);
|
||||||
@ -309,419 +313,6 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashMap<TPHConstraint, HashSet<String>> simplifyPairs(String name, ArrayList<TPHConstraint> allCons) {
|
|
||||||
// 1. check if there are any cycles like L<R and R<L:
|
|
||||||
// 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<TPHConstraint> consToRemove = new ArrayList<>();
|
|
||||||
// step 1:
|
|
||||||
for(TPHConstraint c : allCons) {
|
|
||||||
|
|
||||||
String left = c.getLeft();
|
|
||||||
String right = c.getRight();
|
|
||||||
if(c.getRel() == Relation.EXTENDS) {
|
|
||||||
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
|
||||||
if(revCon != null) {
|
|
||||||
revCon.setRel(Relation.EQUAL);
|
|
||||||
consToRemove.add(revCon);
|
|
||||||
c.setRel(Relation.EQUAL);
|
|
||||||
substituteTPH(allCons,left, right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println();
|
|
||||||
System.out.println("NEW ALL CONST: " + allCons.size());
|
|
||||||
allCons.forEach(c->System.out.println(c.toString()));
|
|
||||||
System.out.println("----------------");
|
|
||||||
allCons.removeAll(consToRemove);
|
|
||||||
consToRemove = new ArrayList<>();
|
|
||||||
|
|
||||||
int size = allCons.size();
|
|
||||||
|
|
||||||
System.out.println("AFTER DELETE ALL CONST: " + allCons.size());
|
|
||||||
allCons.forEach(c->System.out.println(c.toString()));
|
|
||||||
System.out.println("----------------");
|
|
||||||
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
|
||||||
|
|
||||||
for(TPHConstraint c : allCons) {
|
|
||||||
if(c.getRel()==Relation.EQUAL) {
|
|
||||||
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--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println("Step 2 Result: ");
|
|
||||||
result.forEach((c,hs)->{
|
|
||||||
System.out.print(c.toString() + " -> ");
|
|
||||||
hs.forEach(s->{
|
|
||||||
System.out.print(s + ", ");
|
|
||||||
});
|
|
||||||
System.out.println();
|
|
||||||
});
|
|
||||||
System.out.println("----------------");
|
|
||||||
allCons.removeAll(consToRemove);
|
|
||||||
allCons.addAll(result.keySet());
|
|
||||||
|
|
||||||
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--;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<TypePlaceholder> methodTphs = new ArrayList<>();
|
|
||||||
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
|
||||||
if(m.getName().equals(name)) {
|
|
||||||
methodTphs = m.getTphs();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap<String, String> subAndSuper = new HashMap<>();
|
|
||||||
for(TPHConstraint c : allCons) {
|
|
||||||
if(subAndSuper.containsKey(c.getLeft())) {
|
|
||||||
LinkedList<String> all = new LinkedList<>();
|
|
||||||
all.add(c.getLeft());
|
|
||||||
String sup =c.getRight();
|
|
||||||
all.add(sup);
|
|
||||||
HashMap<String, String> ss = new HashMap<>();
|
|
||||||
for(TPHConstraint constr : allCons) {
|
|
||||||
ss.put(constr.getLeft(), constr.getRight());
|
|
||||||
}
|
|
||||||
while(ss.containsKey(sup)) {
|
|
||||||
sup = ss.get(sup);
|
|
||||||
all.add(sup);
|
|
||||||
}
|
|
||||||
if(!containTPH(methodTphs, all.getLast()))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
subAndSuper.put(c.getLeft(), c.getRight());
|
|
||||||
}
|
|
||||||
|
|
||||||
int numOfVisitedPairs = 0;
|
|
||||||
for(String sub : subAndSuper.keySet()) {
|
|
||||||
if(isTPHInConstraint(result,sub))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(!containTPH(methodTphs,sub))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(numOfVisitedPairs>=size)
|
|
||||||
break;
|
|
||||||
LinkedList<String> tphInRel = new LinkedList<>();
|
|
||||||
tphInRel.add(sub);
|
|
||||||
String superT = subAndSuper.get(sub);
|
|
||||||
tphInRel.add(superT);
|
|
||||||
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
boolean isCycle = false;
|
|
||||||
while(subAndSuper.containsKey(superT)) {
|
|
||||||
superT = subAndSuper.get(superT);
|
|
||||||
if(tphInRel.contains(superT)) {
|
|
||||||
isCycle = true;
|
|
||||||
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(containTPH(methodTphs,tph) && subAndSuper.get(tph).equals(subTphRes)) {
|
|
||||||
subTphRes = tph;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(subTphRes.equals(tphInRel.getFirst())) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tphInRel.addFirst(subTphRes);
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
subTphRes = tphInRel.getFirst();
|
|
||||||
|
|
||||||
int i = 2;
|
|
||||||
while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) {
|
|
||||||
superTphRes = tphInRel.get(tphInRel.size()-i);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!containTPH(methodTphs, superTphRes)) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println("ZwischenResult: ");
|
|
||||||
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 boolean isTPHInConstraint(HashMap<TPHConstraint, HashSet<String>> result, String sub) {
|
|
||||||
for(TPHConstraint c : result.keySet()) {
|
|
||||||
if(c.getLeft().equals(sub))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean containTPH(ArrayList<TypePlaceholder> methodTphs, String sub) {
|
|
||||||
for(TypePlaceholder tph : methodTphs) {
|
|
||||||
if(tph.getName().equals(sub))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TPHConstraint getKeyConstraint(HashMap<TPHConstraint, HashSet<String>> result, TPHConstraint toFind) {
|
|
||||||
for(TPHConstraint c : result.keySet()) {
|
|
||||||
if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight()))
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
return new ExtendsConstraint(toFind.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
private HashSet<String> getEqualsTPHs(HashMap<TPHConstraint,HashSet<String>> result, TPHConstraint toFind) {
|
|
||||||
for(TPHConstraint c : result.keySet()) {
|
|
||||||
if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight()))
|
|
||||||
return result.get(c);
|
|
||||||
}
|
|
||||||
return new HashSet<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList<GenericInsertPair> simplifyPairs(String methodName, ArrayList<GenericInsertPair> allPairs, ArrayList<TPHConstraint> allCons) {
|
|
||||||
allPairs.forEach(p->System.out.print(p.TA1 + " < "+ p.TA2+ " ; "));
|
|
||||||
|
|
||||||
// 1. check if there are any cycles like L<R and R<L:
|
|
||||||
// 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
|
|
||||||
// b) no
|
|
||||||
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
|
||||||
// step 1:
|
|
||||||
for(TPHConstraint c : allCons) {
|
|
||||||
|
|
||||||
String left = c.getLeft();
|
|
||||||
String right = c.getRight();
|
|
||||||
if(c.getRel() == Relation.EXTENDS) {
|
|
||||||
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
|
||||||
if(revCon != null) {
|
|
||||||
revCon.setRel(Relation.EQUAL);
|
|
||||||
consToRemove.add(revCon);
|
|
||||||
c.setRel(Relation.EQUAL);
|
|
||||||
substituteTPH(allCons,left, right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.out.println();
|
|
||||||
System.out.println("NEW ALL CONST: " + allCons.size());
|
|
||||||
allCons.forEach(c->System.out.println(c.toString()));
|
|
||||||
System.out.println("----------------");
|
|
||||||
allCons.removeAll(consToRemove);
|
|
||||||
System.out.println("AFTER DELETE ALL CONST: " + allCons.size());
|
|
||||||
allCons.forEach(c->System.out.println(c.toString()));
|
|
||||||
System.out.println("----------------");
|
|
||||||
if(allPairs.size() < 2)
|
|
||||||
return allPairs;
|
|
||||||
|
|
||||||
ArrayList<GenericInsertPair> simplifiedPairs = new ArrayList<>();
|
|
||||||
|
|
||||||
ArrayList<HashMap<Integer, TypePlaceholder>> beforeSimplify = new ArrayList<>();
|
|
||||||
|
|
||||||
MethodAndTPH method;
|
|
||||||
ArrayList<TypePlaceholder> methodTphs = new ArrayList<>();
|
|
||||||
ArrayList<GenericInsertPair> methodPairs = new ArrayList<>();
|
|
||||||
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
|
||||||
if(m.getName().equals(methodName)) {
|
|
||||||
methodTphs = m.getTphs();
|
|
||||||
methodPairs = m.getPairs();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap<TypePlaceholder, TypePlaceholder> subAndSuperTph = new HashMap<>();
|
|
||||||
for(GenericInsertPair p : allPairs) {
|
|
||||||
// Tph2.jav
|
|
||||||
if(subAndSuperTph.containsKey(p.TA1)) {
|
|
||||||
if(methodTphs.contains(subAndSuperTph.get(p.TA1)))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
subAndSuperTph.put(p.TA1, p.TA2);
|
|
||||||
}
|
|
||||||
int numOfVisitedPairs = 0;
|
|
||||||
for(TypePlaceholder subTph: subAndSuperTph.keySet()) {
|
|
||||||
|
|
||||||
if(numOfVisitedPairs>=subAndSuperTph.size())
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(!methodTphs.contains(subTph))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
HashMap<Integer, TypePlaceholder> tphsInRel= new HashMap<>();
|
|
||||||
|
|
||||||
tphsInRel.put(tphsInRel.size(), subTph);
|
|
||||||
TypePlaceholder superTph = subAndSuperTph.get(subTph);
|
|
||||||
tphsInRel.put(tphsInRel.size(), superTph);
|
|
||||||
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
boolean isCycle = false;
|
|
||||||
while(subAndSuperTph.containsKey(superTph)) {
|
|
||||||
superTph = subAndSuperTph.get(superTph);
|
|
||||||
if(tphsInRel.containsValue(superTph)) {
|
|
||||||
isCycle = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tphsInRel.put(tphsInRel.size(), superTph);
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtype
|
|
||||||
TypePlaceholder subTphRes = tphsInRel.get(0);
|
|
||||||
// Die größte Supertype
|
|
||||||
TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1);
|
|
||||||
|
|
||||||
while(subAndSuperTph.containsValue(subTphRes)) {
|
|
||||||
for(TypePlaceholder tph : subAndSuperTph.keySet()) {
|
|
||||||
if(methodTphs.contains(tph) && subAndSuperTph.get(tph).equals(subTphRes)) {
|
|
||||||
subTphRes = tph;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(subTphRes.equals(tphsInRel.get(0))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tphsInRel.put(0, subTphRes);
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
subTphRes = tphsInRel.get(0);
|
|
||||||
|
|
||||||
int i = 2;
|
|
||||||
while(!methodTphs.contains(superTphRes) && (tphsInRel.size()-i) >0) {
|
|
||||||
superTphRes = tphsInRel.get(tphsInRel.size()-i);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((methodTphs.contains(superTphRes) || !tphExtractor.allTPHS.containsKey(superTphRes))
|
|
||||||
&& !subTphRes.equals(superTphRes)) {
|
|
||||||
|
|
||||||
beforeSimplify.add(tphsInRel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// teste noch den Fall X < Y und Y nicht in TPHS der Methode
|
|
||||||
// Dann hat man nach der While-Schleife X < Y
|
|
||||||
// Y muss durch Object ersetzt.
|
|
||||||
|
|
||||||
// Zweite Operand für die Fälle wie in Lambda.jav (Paramtrisierte Typen)
|
|
||||||
if((methodTphs.contains(superTphRes) || !tphExtractor.allTPHS.containsKey(superTphRes))
|
|
||||||
&& !subTphRes.equals(superTphRes)) {
|
|
||||||
GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes);
|
|
||||||
simplifiedPairs.add(sPair);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
beforeSimplify.forEach(e->{
|
|
||||||
System.out.println("=> ");
|
|
||||||
e.forEach((v,k) -> {
|
|
||||||
System.out.print(v + "->" + k + ", ");
|
|
||||||
});
|
|
||||||
System.out.println();
|
|
||||||
System.out.println("----------------------");
|
|
||||||
});
|
|
||||||
|
|
||||||
if(beforeSimplify.size()>1) {
|
|
||||||
int i = 0;
|
|
||||||
while(i<beforeSimplify.size()) {
|
|
||||||
TypePlaceholder sub = beforeSimplify.get(i).get(0);
|
|
||||||
|
|
||||||
for(HashMap<Integer, TypePlaceholder> e: beforeSimplify) {
|
|
||||||
if(!e.equals(beforeSimplify.get(i)) && e.containsValue(sub)) {
|
|
||||||
GenericInsertPair sPair = new GenericInsertPair(e.get(0), sub);
|
|
||||||
System.out.println("To remove = " + e.get(0)+ " " +e.get(e.size()-1));
|
|
||||||
removePair(simplifiedPairs,e.get(0), e.get(e.size()-1));
|
|
||||||
simplifiedPairs.add(sPair);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return simplifiedPairs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void substituteTPH(ArrayList<TPHConstraint> allCons,String left ,String right) {
|
|
||||||
allCons.forEach(c->{
|
|
||||||
if(c.getRel() == Relation.EXTENDS) {
|
|
||||||
if(c.getLeft().equals(left))
|
|
||||||
c.setLeft(right);
|
|
||||||
if(c.getRight().equals(left))
|
|
||||||
c.setRight(right);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private TPHConstraint getReverseConstraint(ArrayList<TPHConstraint> allCons, String left, String right) {
|
|
||||||
for(TPHConstraint c : allCons) {
|
|
||||||
if(c.getLeft().equals(right) && c.getRight().equals(left)){
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removePair(ArrayList<GenericInsertPair> simplifiedPairs, TypePlaceholder typePlaceholder, TypePlaceholder typePlaceholder2) {
|
|
||||||
for(GenericInsertPair p : simplifiedPairs) {
|
|
||||||
if(p.TA1.equals(typePlaceholder) && p.TA2.equals(typePlaceholder2)) {
|
|
||||||
simplifiedPairs.remove(p);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ParameterList formalParameters) {
|
public void visit(ParameterList formalParameters) {
|
||||||
paramsAndLocals = new HashMap<>();
|
paramsAndLocals = new HashMap<>();
|
||||||
@ -964,15 +555,15 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TPHExtractor extends AbstractASTWalker{
|
public class TPHExtractor extends AbstractASTWalker{
|
||||||
// Alle TPHs der Felder werden iKopf der Klasse definiert
|
// Alle TPHs der Felder werden iKopf der Klasse definiert
|
||||||
// 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;
|
||||||
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<>();
|
||||||
final ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(TypePlaceholder tph) {
|
public void visit(TypePlaceholder tph) {
|
||||||
|
@ -2,15 +2,18 @@ package de.dhbwstuttgart.bytecode.signature;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.signature.SignatureVisitor;
|
import org.objectweb.asm.signature.SignatureVisitor;
|
||||||
import org.objectweb.asm.signature.SignatureWriter;
|
import org.objectweb.asm.signature.SignatureWriter;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||||
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||||
@ -36,7 +39,7 @@ public class Signature {
|
|||||||
private HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes;
|
private HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes;
|
||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
private ArrayList<GenericInsertPair> commonPairs;
|
private ArrayList<GenericInsertPair> commonPairs;
|
||||||
private ArrayList<GenericInsertPair> methodPairs;
|
private HashMap<TPHConstraint,HashSet<String>> methodConstraints;
|
||||||
|
|
||||||
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,ArrayList<GenericInsertPair> commonPairs) {
|
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,ArrayList<GenericInsertPair> commonPairs) {
|
||||||
this.classOrInterface = classOrInterface;
|
this.classOrInterface = classOrInterface;
|
||||||
@ -47,24 +50,26 @@ public class Signature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Signature(Constructor constructor, HashMap<String, String> genericsAndBounds,
|
public Signature(Constructor constructor, HashMap<String, String> genericsAndBounds,
|
||||||
HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes,ResultSet resultSet,ArrayList<GenericInsertPair> methodPairs) {
|
HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes,ResultSet resultSet,
|
||||||
|
HashMap<TPHConstraint,HashSet<String>> methodConstraints) {
|
||||||
this.constructor = constructor;
|
this.constructor = constructor;
|
||||||
this.genericsAndBounds = genericsAndBounds;
|
this.genericsAndBounds = genericsAndBounds;
|
||||||
this.methodParamsAndTypes = methodParamsAndTypes;
|
this.methodParamsAndTypes = methodParamsAndTypes;
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.methodPairs = methodPairs;
|
this.methodConstraints = methodConstraints;
|
||||||
sw = new SignatureWriter();
|
sw = new SignatureWriter();
|
||||||
createSignatureForConsOrMethod(this.constructor,true);
|
createSignatureForConsOrMethod(this.constructor,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Signature(Method method, HashMap<String, String> genericsAndBoundsMethod,HashMap<String, String> genericsAndBounds,
|
public Signature(Method method, HashMap<String, String> genericsAndBoundsMethod,HashMap<String, String> genericsAndBounds,
|
||||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet, ArrayList<GenericInsertPair> methodPairs) {
|
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet,
|
||||||
|
HashMap<TPHConstraint,HashSet<String>> methodConstraints) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
||||||
this.genericsAndBounds = genericsAndBounds;
|
this.genericsAndBounds = genericsAndBounds;
|
||||||
this.methodParamsAndTypes = methodParamsAndTypes;
|
this.methodParamsAndTypes = methodParamsAndTypes;
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.methodPairs = methodPairs;
|
this.methodConstraints = methodConstraints;
|
||||||
sw = new SignatureWriter();
|
sw = new SignatureWriter();
|
||||||
createSignatureForConsOrMethod(this.method,false);
|
createSignatureForConsOrMethod(this.method,false);
|
||||||
}
|
}
|
||||||
@ -111,15 +116,16 @@ public class Signature {
|
|||||||
getBoundsOfTypeVar(g,genericsAndBoundsMethod);
|
getBoundsOfTypeVar(g,genericsAndBoundsMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: paramtrisierte Typen mit Generics, Type Variablen müssen definiert werden.
|
|
||||||
|
|
||||||
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt
|
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt
|
||||||
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
|
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
|
||||||
if(!isConstructor) {
|
if(!isConstructor) {
|
||||||
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||||
ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
|
ArrayList<TPHConstraint> allConsBeforeSimplify = new ArrayList<>();
|
||||||
|
|
||||||
|
HashMap<TPHConstraint,HashSet<String>> allConstraints = new HashMap<>();
|
||||||
|
|
||||||
if(ret.contains("<")) {
|
if(ret.contains("<")) {
|
||||||
allPairs = getAllPairs((RefType) resultSet.resolveType(method.getReturnType()).resolvedType);
|
allConsBeforeSimplify = getAllConstraints((RefType) resultSet.resolveType(method.getReturnType()).resolvedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||||
@ -127,102 +133,22 @@ public class Signature {
|
|||||||
String pT = t.acceptTV(new TypeToSignature());
|
String pT = t.acceptTV(new TypeToSignature());
|
||||||
|
|
||||||
if(pT.contains("<"))
|
if(pT.contains("<"))
|
||||||
allPairs.addAll(getAllPairs((RefType) t));
|
allConsBeforeSimplify = getAllConstraints((RefType) t);
|
||||||
}
|
}
|
||||||
|
boolean doSimplify = false;
|
||||||
createTypeVars(allPairs);
|
if(!allConsBeforeSimplify.isEmpty()) {
|
||||||
|
addConstraintsToMap(allConstraints,allConsBeforeSimplify);
|
||||||
|
doSimplify = true;
|
||||||
|
}
|
||||||
|
createTypeVars(allConstraints, doSimplify);
|
||||||
|
|
||||||
if(!ret.equals("V")) {
|
if(!ret.equals("V")) {
|
||||||
// TODO TypeToSignature nochmal kontrollieren und schauen ob man dort wirklich
|
|
||||||
// T... braucht und L ...
|
|
||||||
if(ret.contains("$") && !ret.contains("$$") && !ret.contains("<")) {
|
if(ret.contains("$") && !ret.contains("$$") && !ret.contains("<")) {
|
||||||
if(genericsAndBounds.containsKey(ret)) {
|
if(genericsAndBounds.containsKey(ret)) {
|
||||||
genericsAndBoundsMethod.put(ret.substring(1), genericsAndBounds.get(ret.substring(1)));
|
genericsAndBoundsMethod.put(ret.substring(1), genericsAndBounds.get(ret.substring(1)));
|
||||||
}else {
|
|
||||||
sw.visitFormalTypeParameter(ret.substring(1));
|
|
||||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
|
||||||
genericsAndBoundsMethod.put(ret.substring(1), Type.getInternalName(Object.class));
|
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(ret.contains("<")) {
|
|
||||||
// RefType ref = (RefType) resultSet.resolveType(method.getReturnType()).resolvedType;
|
|
||||||
// if(hasTPHs(ref)) {
|
|
||||||
// createSignatureForParameterizedType(ref);
|
|
||||||
// }
|
|
||||||
// System.out.println("HAS WC = " + hasWC(ref));
|
|
||||||
// if(hasWC(ref))
|
|
||||||
// createSigForParamTypeWithWC(ref);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parameters
|
|
||||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
|
|
||||||
String pT = t.acceptTV(new TypeToSignature());
|
|
||||||
// S.o
|
|
||||||
if(t instanceof TypePlaceholder) {
|
|
||||||
String gP = t.acceptTV(new TypeToSignature());
|
|
||||||
if(!genericsAndBounds.containsKey(gP.substring(1)) && !genericsAndBoundsMethod.containsKey(gP.substring(1))) {
|
|
||||||
sw.visitFormalTypeParameter(gP.substring(1));
|
|
||||||
String bound = Type.getInternalName(Object.class);
|
|
||||||
boolean isTypeVar = false;
|
|
||||||
for(GenericInsertPair pair : methodPairs) {
|
|
||||||
if(pT.substring(1,pT.length()-1).equals(pair.TA1.getName())) {
|
|
||||||
bound = pair.TA2.getName()+"$";
|
|
||||||
isTypeVar = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isTypeVar) {
|
|
||||||
sw.visitClassBound().visitTypeVariable(bound);
|
|
||||||
}else {
|
|
||||||
sw.visitClassBound().visitClassType(bound);
|
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
genericsAndBoundsMethod.put(gP.substring(1), bound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if(pT.contains("<")) {
|
|
||||||
// RefType ref = (RefType) methodParamsAndTypes.get(paramName);
|
|
||||||
// if(hasTPHs(ref))
|
|
||||||
// createSignatureForParameterizedType(ref);
|
|
||||||
//
|
|
||||||
// if(hasWC(ref))
|
|
||||||
// createSigForParamTypeWithWC(ref);
|
|
||||||
// }
|
|
||||||
|
|
||||||
for(GenericInsertPair p:methodPairs) {
|
|
||||||
String name = p.TA1.getName()+"$";
|
|
||||||
if(!genericsAndBoundsMethod.containsKey(name)) {
|
|
||||||
sw.visitFormalTypeParameter(name);
|
|
||||||
sw.visitClassBound().visitTypeVariable(p.TA2.getName()+"$");
|
|
||||||
genericsAndBoundsMethod.put(name, p.TA2.getName()+"$");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<TypePlaceholder> types = new ArrayList<>();
|
|
||||||
ArrayList<TypePlaceholder> superTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
for(GenericInsertPair p : methodPairs) {
|
|
||||||
types.add(p.TA1);
|
|
||||||
superTypes.add(p.TA2);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(GenericInsertPair p : methodPairs) {
|
|
||||||
String name = p.TA2.getName()+"$";
|
|
||||||
if(!types.contains(p.TA2) && !genericsAndBoundsMethod.containsKey(name)) {
|
|
||||||
String bound = Type.getInternalName(Object.class);
|
|
||||||
sw.visitFormalTypeParameter(name);
|
|
||||||
sw.visitClassBound().visitClassType(bound);
|
|
||||||
genericsAndBoundsMethod.put(name, bound);
|
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,126 +169,56 @@ public class Signature {
|
|||||||
// sw.visitEnd();
|
// sw.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTypeVars(ArrayList<GenericInsertPair> allPairs) {
|
private void addConstraintsToMap(HashMap<TPHConstraint, HashSet<String>> allConstraints,
|
||||||
allPairs.addAll(methodPairs);
|
ArrayList<TPHConstraint> allConsBeforeSimplify) {
|
||||||
ArrayList<GenericInsertPair> simplifiedPairs = simplifyPairs(allPairs);
|
for(TPHConstraint tphCons : allConsBeforeSimplify) {
|
||||||
|
allConstraints.put(tphCons, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getEqualTPH(HashMap<TPHConstraint, HashSet<String>> methodConstraints, String tph) {
|
||||||
|
for(TPHConstraint cons : methodConstraints.keySet()) {
|
||||||
|
if(methodConstraints.get(cons) != null) {
|
||||||
|
if(methodConstraints.get(cons).contains(tph)) {
|
||||||
|
return cons.getLeft();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tph;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTypeVars(HashMap<TPHConstraint, HashSet<String>> allConstraints, boolean doSimplify) {
|
||||||
|
allConstraints.putAll(methodConstraints);
|
||||||
|
|
||||||
HashMap<String, String> names = new HashMap<>();
|
HashMap<TPHConstraint, HashSet<String>> simplifiedConstraints;
|
||||||
|
if(doSimplify) {
|
||||||
for(GenericInsertPair pair : simplifiedPairs) {
|
simplifiedConstraints = Simplify.simplifyContraints(allConstraints);
|
||||||
// if(ref.getParaList().contains(pair.TA1)) {
|
}else {
|
||||||
String sub = pair.TA1.getName()+"$";
|
simplifiedConstraints = allConstraints;
|
||||||
String superT = pair.TA2.getName()+"$";
|
|
||||||
names.put(sub, superT);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(String sub : names.keySet()) {
|
for(TPHConstraint cons : simplifiedConstraints.keySet()) {
|
||||||
|
// need subst.
|
||||||
|
String sub = cons.getLeft()+"$";
|
||||||
if(!genericsAndBoundsMethod.containsKey(sub) && !genericsAndBounds.containsKey(sub)) {
|
if(!genericsAndBoundsMethod.containsKey(sub) && !genericsAndBounds.containsKey(sub)) {
|
||||||
sw.visitFormalTypeParameter(sub);
|
sw.visitFormalTypeParameter(sub);
|
||||||
String bound = names.get(sub);
|
String bound = cons.getRight();
|
||||||
sw.visitClassBound().visitTypeVariable(bound);
|
if(bound.equals(Type.getInternalName(Object.class))) {
|
||||||
genericsAndBoundsMethod.put(sub, bound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(String superT : names.values()) {
|
|
||||||
if(!names.containsKey(superT)) {
|
|
||||||
if(!genericsAndBoundsMethod.containsKey(superT) && !genericsAndBounds.containsKey(superT)) {
|
|
||||||
sw.visitFormalTypeParameter(superT);
|
|
||||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
||||||
sw.visitClassBound().visitEnd();
|
sw.visitClassBound().visitEnd();
|
||||||
genericsAndBoundsMethod.put(superT, Type.getInternalName(Object.class));
|
genericsAndBoundsMethod.put(sub, bound);
|
||||||
|
} else {
|
||||||
|
String boundName = bound+"$";
|
||||||
|
sw.visitClassBound().visitTypeVariable(boundName);
|
||||||
|
genericsAndBoundsMethod.put(sub, boundName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createSigForParamTypeWithWC(RefType ref) {
|
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
|
||||||
if(p instanceof WildcardType) {
|
|
||||||
String name = null;
|
|
||||||
if(((WildcardType) p).getInnerType() instanceof GenericRefType) {
|
|
||||||
name = new TypeToSignature().visit((GenericRefType)((WildcardType) p).getInnerType());
|
|
||||||
}
|
|
||||||
if(((WildcardType) p).getInnerType() instanceof TypePlaceholder) {
|
|
||||||
name = new TypeToSignature().visit((TypePlaceholder)((WildcardType) p).getInnerType());
|
|
||||||
name = name.substring(1);
|
|
||||||
}
|
|
||||||
if(name != null) {
|
|
||||||
if(!genericsAndBoundsMethod.containsKey(name) && !genericsAndBounds.containsKey(name)) {
|
|
||||||
sw.visitFormalTypeParameter(name);
|
|
||||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
genericsAndBoundsMethod.put(name, Type.getInternalName(Object.class));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasWC(RefType ref) {
|
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
|
||||||
System.out.println("HAS WCs: " + p.acceptTV(new TypeToString()));
|
|
||||||
System.out.println("HAS WCs: " + p.getClass());
|
|
||||||
if(p.acceptTV(new TypeToString()).contains("WC"))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createSignatureForParameterizedType(RefType ref) {
|
private ArrayList<TPHConstraint> getAllConstraints(RefType ref) {
|
||||||
// ArrayList<GenericInsertPair> allPairs = getAllPairs(ref);
|
final ArrayList<TPHConstraint> res = new ArrayList<>();
|
||||||
// allPairs.addAll(methodPairs);
|
|
||||||
// ArrayList<GenericInsertPair> simplifiedPairs = simplifyPairs(allPairs);
|
|
||||||
//
|
|
||||||
// HashMap<String, String> names = new HashMap<>();
|
|
||||||
//
|
|
||||||
// for(GenericInsertPair pair : simplifiedPairs) {
|
|
||||||
// if(ref.getParaList().contains(pair.TA1)) {
|
|
||||||
// String sub = pair.TA1.getName()+"$";
|
|
||||||
// String superT = pair.TA2.getName()+"$";
|
|
||||||
// names.put(sub, superT);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for(String sub : names.keySet()) {
|
|
||||||
// if(!genericsAndBoundsMethod.containsKey(sub) && !genericsAndBounds.containsKey(sub)) {
|
|
||||||
// sw.visitFormalTypeParameter(sub);
|
|
||||||
// String bound = names.get(sub);
|
|
||||||
// sw.visitClassBound().visitTypeVariable(bound);
|
|
||||||
// genericsAndBoundsMethod.put(sub, bound);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for(String superT : names.values()) {
|
|
||||||
// if(!names.containsKey(superT)) {
|
|
||||||
// if(!genericsAndBoundsMethod.containsKey(superT) && !genericsAndBounds.containsKey(superT)) {
|
|
||||||
// sw.visitFormalTypeParameter(superT);
|
|
||||||
// sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
|
||||||
// sw.visitClassBound().visitEnd();
|
|
||||||
// genericsAndBoundsMethod.put(superT, Type.getInternalName(Object.class));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric p: ref.getParaList()) {
|
|
||||||
if(p instanceof TypePlaceholder) {
|
|
||||||
String name = ((TypePlaceholder) p).getName() + "$";
|
|
||||||
if(!genericsAndBoundsMethod.containsKey(name) && !genericsAndBounds.containsKey(name)) {
|
|
||||||
sw.visitFormalTypeParameter(name);
|
|
||||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
genericsAndBoundsMethod.put(name, Type.getInternalName(Object.class));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList<GenericInsertPair> getAllPairs(RefType ref) {
|
|
||||||
final ArrayList<GenericInsertPair> res = new ArrayList<>();
|
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
||||||
ResolvedType resType;
|
ResolvedType resType;
|
||||||
if(p instanceof WildcardType) {
|
if(p instanceof WildcardType) {
|
||||||
@ -374,8 +230,9 @@ public class Signature {
|
|||||||
RefTypeOrTPHOrWildcardOrGeneric resolved = resType.resolvedType;
|
RefTypeOrTPHOrWildcardOrGeneric resolved = resType.resolvedType;
|
||||||
if(resolved instanceof TypePlaceholder) {
|
if(resolved instanceof TypePlaceholder) {
|
||||||
resType.additionalGenerics.forEach(ag ->{
|
resType.additionalGenerics.forEach(ag ->{
|
||||||
if(!contains(res,ag)) {
|
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
|
||||||
res.add(ag);
|
if(!contains(res,constr)) {
|
||||||
|
res.add(constr);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -384,9 +241,10 @@ public class Signature {
|
|||||||
ResolvedType resType2 = resultSet.resolveType(resWC.getInnerType());
|
ResolvedType resType2 = resultSet.resolveType(resWC.getInnerType());
|
||||||
if(resType2.resolvedType instanceof TypePlaceholder) {
|
if(resType2.resolvedType instanceof TypePlaceholder) {
|
||||||
resType2.additionalGenerics.forEach(ag ->{
|
resType2.additionalGenerics.forEach(ag ->{
|
||||||
if(!contains(res,ag)) {
|
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
|
||||||
res.add(ag);
|
if(!contains(res,constr)) {
|
||||||
}
|
res.add(constr);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -395,81 +253,10 @@ public class Signature {
|
|||||||
System.out.println("RES GIP === " + res.size());
|
System.out.println("RES GIP === " + res.size());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
private boolean contains(ArrayList<TPHConstraint> constraints, TPHConstraint constr) {
|
||||||
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
|
for(int i=0; i<constraints.size();++i) {
|
||||||
for(int i=0; i<pairs.size();++i) {
|
TPHConstraint p = constraints.get(i);
|
||||||
GenericInsertPair p = pairs.get(i);
|
if(constr.getLeft().equals(p.getLeft()) && constr.getRight().equals(p.getRight()))
|
||||||
if(p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList<GenericInsertPair> simplifyPairs(ArrayList<GenericInsertPair> allPairs) {
|
|
||||||
ArrayList<GenericInsertPair> simplifiedPairs = new ArrayList<>();
|
|
||||||
|
|
||||||
HashMap<TypePlaceholder, TypePlaceholder> subAndSuperTph = new HashMap<>();
|
|
||||||
for(GenericInsertPair p : allPairs) {
|
|
||||||
if(!p.TA1.equals(p.TA2))
|
|
||||||
subAndSuperTph.put(p.TA1, p.TA2);
|
|
||||||
}
|
|
||||||
|
|
||||||
subAndSuperTph.forEach((k,v)->System.out.println(k.getName() + " || " + v.getName()));
|
|
||||||
|
|
||||||
int numOfVisitedPairs = 0;
|
|
||||||
for(TypePlaceholder subTph: subAndSuperTph.keySet()) {
|
|
||||||
|
|
||||||
if(numOfVisitedPairs>=subAndSuperTph.size())
|
|
||||||
break;
|
|
||||||
|
|
||||||
HashMap<Integer, TypePlaceholder> tphsInRel= new HashMap<>();
|
|
||||||
|
|
||||||
tphsInRel.put(tphsInRel.size(), subTph);
|
|
||||||
TypePlaceholder superTph = subAndSuperTph.get(subTph);
|
|
||||||
tphsInRel.put(tphsInRel.size(), superTph);
|
|
||||||
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
|
|
||||||
while(subAndSuperTph.containsKey(superTph)) {
|
|
||||||
superTph = subAndSuperTph.get(superTph);
|
|
||||||
if(tphsInRel.containsValue(superTph)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tphsInRel.put(tphsInRel.size(), superTph);
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtype
|
|
||||||
TypePlaceholder subTphRes = tphsInRel.get(0);
|
|
||||||
// Die größte Supertype
|
|
||||||
TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1);
|
|
||||||
|
|
||||||
|
|
||||||
while(subAndSuperTph.containsValue(subTphRes)) {
|
|
||||||
for(TypePlaceholder tph : subAndSuperTph.keySet()) {
|
|
||||||
if(subAndSuperTph.get(tph).equals(subTphRes)) {
|
|
||||||
subTphRes = tph;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tphsInRel.put(0, subTphRes);
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
subTphRes = tphsInRel.get(0);
|
|
||||||
GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes);
|
|
||||||
simplifiedPairs.add(sPair);
|
|
||||||
}
|
|
||||||
return simplifiedPairs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasTPHs(RefType ref) {
|
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
|
||||||
System.out.println("HAS TPHs: " + p.acceptTV(new TypeToString()));
|
|
||||||
if(p.acceptTV(new TypeToString()).contains("WC")){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(resultSet.resolveType(p).resolvedType instanceof TypePlaceholder)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -508,6 +295,7 @@ public class Signature {
|
|||||||
// das braucht man nicht es reicht: sv.visitTypeVariable(r.acceptTV(new TypeToSignature())
|
// das braucht man nicht es reicht: sv.visitTypeVariable(r.acceptTV(new TypeToSignature())
|
||||||
//
|
//
|
||||||
String sig2 = r.acceptTV(new TypeToSignature());
|
String sig2 = r.acceptTV(new TypeToSignature());
|
||||||
|
String eqTPH = getEqualTPH(methodConstraints, sig2.substring(1, sig2.length()-1))+"$";
|
||||||
if(!(r instanceof TypePlaceholder)) {
|
if(!(r instanceof TypePlaceholder)) {
|
||||||
if(sig2.contains("$$")) {
|
if(sig2.contains("$$")) {
|
||||||
System.out.println(" Signature FUN$$: "+r);
|
System.out.println(" Signature FUN$$: "+r);
|
||||||
@ -518,7 +306,7 @@ public class Signature {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
|
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
|
||||||
sv.visitTypeVariable(sig2.substring(1, sig2.length()));
|
sv.visitTypeVariable(eqTPH);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
432
src/de/dhbwstuttgart/bytecode/utilities/Simplify.java
Normal file
432
src/de/dhbwstuttgart/bytecode/utilities/Simplify.java
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.BytecodeGen.TPHExtractor;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
|
||||||
|
public class Simplify {
|
||||||
|
|
||||||
|
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor) {
|
||||||
|
// 1. check if there are any cycles like L<R and R<L:
|
||||||
|
// 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<TPHConstraint> allCons = tphExtractor.allCons;
|
||||||
|
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
||||||
|
// step 1:
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
|
||||||
|
String left = c.getLeft();
|
||||||
|
String right = c.getRight();
|
||||||
|
if(c.getRel() == Relation.EXTENDS) {
|
||||||
|
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
||||||
|
if(revCon != null) {
|
||||||
|
revCon.setRel(Relation.EQUAL);
|
||||||
|
consToRemove.add(revCon);
|
||||||
|
c.setRel(Relation.EQUAL);
|
||||||
|
substituteTPH(allCons,left, right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("NEW ALL CONST: " + allCons.size());
|
||||||
|
allCons.forEach(c->System.out.println(c.toString()));
|
||||||
|
System.out.println("----------------");
|
||||||
|
allCons.removeAll(consToRemove);
|
||||||
|
consToRemove = new ArrayList<>();
|
||||||
|
|
||||||
|
int size = allCons.size();
|
||||||
|
|
||||||
|
System.out.println("AFTER DELETE ALL CONST: " + allCons.size());
|
||||||
|
allCons.forEach(c->System.out.println(c.toString()));
|
||||||
|
System.out.println("----------------");
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
if(c.getRel()==Relation.EQUAL) {
|
||||||
|
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--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Step 2 Result: ");
|
||||||
|
result.forEach((c,hs)->{
|
||||||
|
System.out.print(c.toString() + " -> ");
|
||||||
|
hs.forEach(s->{
|
||||||
|
System.out.print(s + ", ");
|
||||||
|
});
|
||||||
|
System.out.println();
|
||||||
|
});
|
||||||
|
System.out.println("----------------");
|
||||||
|
allCons.removeAll(consToRemove);
|
||||||
|
allCons.addAll(result.keySet());
|
||||||
|
|
||||||
|
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--;
|
||||||
|
}
|
||||||
|
ArrayList<TypePlaceholder> methodTphs = new ArrayList<>();
|
||||||
|
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
||||||
|
if(m.getName().equals(name)) {
|
||||||
|
methodTphs = m.getTphs();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<String, String> subAndSuper = new HashMap<>();
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
if(subAndSuper.containsKey(c.getLeft())) {
|
||||||
|
LinkedList<String> all = new LinkedList<>();
|
||||||
|
all.add(c.getLeft());
|
||||||
|
String sup =c.getRight();
|
||||||
|
all.add(sup);
|
||||||
|
HashMap<String, String> ss = new HashMap<>();
|
||||||
|
for(TPHConstraint constr : allCons) {
|
||||||
|
ss.put(constr.getLeft(), constr.getRight());
|
||||||
|
}
|
||||||
|
while(ss.containsKey(sup)) {
|
||||||
|
sup = ss.get(sup);
|
||||||
|
all.add(sup);
|
||||||
|
}
|
||||||
|
if(!containTPH(methodTphs, all.getLast()))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
subAndSuper.put(c.getLeft(), c.getRight());
|
||||||
|
}
|
||||||
|
|
||||||
|
int numOfVisitedPairs = 0;
|
||||||
|
for(String sub : subAndSuper.keySet()) {
|
||||||
|
if(isTPHInConstraint(result,sub))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(!containTPH(methodTphs,sub))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(numOfVisitedPairs>=size)
|
||||||
|
break;
|
||||||
|
LinkedList<String> 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();
|
||||||
|
|
||||||
|
while(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())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tphInRel.addFirst(subTphRes);
|
||||||
|
numOfVisitedPairs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
subTphRes = tphInRel.getFirst();
|
||||||
|
|
||||||
|
int i = 2;
|
||||||
|
while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) {
|
||||||
|
superTphRes = tphInRel.get(tphInRel.size()-i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!containTPH(methodTphs, superTphRes)) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(TypePlaceholder tph : methodTphs) {
|
||||||
|
if(!isTPHInConstraint(result, tph.getName())) {
|
||||||
|
result.put(new ExtendsConstraint(tph.getName(), Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
// 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<TPHConstraint> allCons = new ArrayList<>();
|
||||||
|
for(TPHConstraint tphCons : allConstraints.keySet()) {
|
||||||
|
allCons.add(tphCons);
|
||||||
|
}
|
||||||
|
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
||||||
|
// step 1:
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
|
||||||
|
String left = c.getLeft();
|
||||||
|
String right = c.getRight();
|
||||||
|
if(c.getRel() == Relation.EXTENDS) {
|
||||||
|
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
||||||
|
if(revCon != null) {
|
||||||
|
revCon.setRel(Relation.EQUAL);
|
||||||
|
consToRemove.add(revCon);
|
||||||
|
c.setRel(Relation.EQUAL);
|
||||||
|
substituteTPH(allCons,left, right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("NEW ALL CONST: " + allCons.size());
|
||||||
|
allCons.forEach(c->System.out.println(c.toString()));
|
||||||
|
System.out.println("----------------");
|
||||||
|
allCons.removeAll(consToRemove);
|
||||||
|
consToRemove = new ArrayList<>();
|
||||||
|
|
||||||
|
// int size = allCons.size();
|
||||||
|
|
||||||
|
System.out.println("AFTER DELETE ALL CONST: " + allCons.size());
|
||||||
|
allCons.forEach(c->System.out.println(c.toString()));
|
||||||
|
System.out.println("----------------");
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
if(c.getRel()==Relation.EQUAL) {
|
||||||
|
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--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Step 2 Result: ");
|
||||||
|
result.forEach((c,hs)->{
|
||||||
|
System.out.print(c.toString() + " -> ");
|
||||||
|
hs.forEach(s->{
|
||||||
|
System.out.print(s + ", ");
|
||||||
|
});
|
||||||
|
System.out.println();
|
||||||
|
});
|
||||||
|
System.out.println("----------------");
|
||||||
|
allCons.removeAll(consToRemove);
|
||||||
|
allCons.addAll(result.keySet());
|
||||||
|
|
||||||
|
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<String, String> subAndSuper = new HashMap<>();
|
||||||
|
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
subAndSuper.put(c.getLeft(), c.getRight());
|
||||||
|
}
|
||||||
|
|
||||||
|
// int numOfVisitedPairs = 0;
|
||||||
|
for(String sub : subAndSuper.keySet()) {
|
||||||
|
if(isTPHInConstraint(result,sub))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if(numOfVisitedPairs>=size)
|
||||||
|
// break;
|
||||||
|
|
||||||
|
LinkedList<String> 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();
|
||||||
|
|
||||||
|
while(subAndSuper.containsValue(subTphRes)) {
|
||||||
|
for(String tph : subAndSuper.keySet()) {
|
||||||
|
if(subAndSuper.get(tph).equals(subTphRes)) {
|
||||||
|
subTphRes = tph;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
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 substituteTPH(ArrayList<TPHConstraint> allCons,String left ,String right) {
|
||||||
|
allCons.forEach(c->{
|
||||||
|
if(c.getRel() == Relation.EXTENDS) {
|
||||||
|
if(c.getLeft().equals(left))
|
||||||
|
c.setLeft(right);
|
||||||
|
if(c.getRight().equals(left))
|
||||||
|
c.setRight(right);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TPHConstraint getReverseConstraint(ArrayList<TPHConstraint> allCons, String left, String right) {
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
if(c.getLeft().equals(right) && c.getRight().equals(left)){
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isTPHInConstraint(HashMap<TPHConstraint, HashSet<String>> result, String sub) {
|
||||||
|
for(TPHConstraint c : result.keySet()) {
|
||||||
|
if(c.getLeft().equals(sub))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean containTPH(ArrayList<TypePlaceholder> methodTphs, String sub) {
|
||||||
|
for(TypePlaceholder tph : methodTphs) {
|
||||||
|
if(tph.getName().equals(sub))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TPHConstraint getKeyConstraint(HashMap<TPHConstraint, HashSet<String>> 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<String> getEqualsTPHs(HashMap<TPHConstraint,HashSet<String>> result, TPHConstraint toFind) {
|
||||||
|
for(TPHConstraint c : result.keySet()) {
|
||||||
|
if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight()))
|
||||||
|
return result.get(c);
|
||||||
|
}
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user