Iteration
This commit is contained in:
parent
bb0ee7d517
commit
9eb0dd1cf5
@ -23,7 +23,7 @@ public abstract class GenerateGenerics {
|
||||
private final ASTToTargetAST astToTargetAST;
|
||||
|
||||
public class TPH {
|
||||
final TypePlaceholder wrap;
|
||||
private final TypePlaceholder wrap;
|
||||
|
||||
TPH(TypePlaceholder wrap) {
|
||||
this.wrap = wrap;
|
||||
@ -212,6 +212,7 @@ public abstract class GenerateGenerics {
|
||||
equality.put(entry.getKey(), to);
|
||||
}
|
||||
}
|
||||
to.setVariance(from.getVariance());
|
||||
equality.put(from, to);
|
||||
referenced.remove(new TPH(from));
|
||||
referenced.add(new TPH(to));
|
||||
@ -292,8 +293,10 @@ public abstract class GenerateGenerics {
|
||||
if (expressionReceiver.expr instanceof This) {
|
||||
var optMethod = astToTargetAST.findMethod(owner, methodCall.name, methodCall.getArgumentList());
|
||||
if (optMethod.isEmpty()) return;
|
||||
var method = optMethod.get();
|
||||
var generics = generics(owner, method);
|
||||
var method2 = optMethod.get();
|
||||
System.out.println("In: " + method.getName() + " Method: " + method2.getName());
|
||||
System.out.println(simplifiedConstraints);
|
||||
var generics = family(owner, method2);
|
||||
|
||||
// transitive and
|
||||
var all = transitiveClosure(generics);
|
||||
@ -325,6 +328,7 @@ public abstract class GenerateGenerics {
|
||||
if (!T1s.contains(R1) || !T2s.contains(R2)) continue;
|
||||
|
||||
var newPair = new PairLT(R1, R2);
|
||||
System.out.println("New pair: " + newPair);
|
||||
newPairs.add(newPair);
|
||||
|
||||
if (!containsRelation(result, newPair))
|
||||
@ -501,10 +505,10 @@ public abstract class GenerateGenerics {
|
||||
abstract void generics(ClassOrInterface owner, Method method, Set<Pair> result, Set<TPH> javaTypeVariablesOfClass);
|
||||
|
||||
Set<Pair> family(ClassOrInterface owner, Method method) {
|
||||
Set<Pair> result = new HashSet<>();
|
||||
if (familyOfMethods.containsKey(method))
|
||||
return familyOfMethods.get(method);
|
||||
|
||||
var result = new HashSet<Pair>();
|
||||
familyOfMethods.put(method, result);
|
||||
|
||||
var classGenerics = generics(owner);
|
||||
@ -524,19 +528,22 @@ public abstract class GenerateGenerics {
|
||||
}
|
||||
|
||||
Set<Pair> generics(ClassOrInterface owner, Method method) {
|
||||
if (computedGenericsOfMethods.containsKey(method))
|
||||
return computedGenericsOfMethods.get(method);
|
||||
if (computedGenericsOfMethods.containsKey(method)) {
|
||||
var cached = computedGenericsOfMethods.get(method);
|
||||
System.out.println("Cached " + method.getName() + ": " + cached);
|
||||
return cached;
|
||||
}
|
||||
|
||||
var result = new HashSet<Pair>();
|
||||
computedGenericsOfMethods.put(method, result);
|
||||
|
||||
var classGenerics = generics(owner);
|
||||
|
||||
HashSet<TPH> typeVariablesOfClass = new HashSet<>();
|
||||
|
||||
for (var pair : classGenerics) {
|
||||
typeVariablesOfClass.add(pair.left);
|
||||
}
|
||||
|
||||
var result = new HashSet<>(family(owner, method));
|
||||
computedGenericsOfMethods.put(method, result);
|
||||
result.addAll(family(owner, method));
|
||||
|
||||
var referenced = new HashSet<TPH>();
|
||||
|
||||
@ -552,7 +559,7 @@ public abstract class GenerateGenerics {
|
||||
generics(owner, method, result, referenced);
|
||||
usedTPHsOfMethods.put(method, usedTphs);
|
||||
|
||||
addMissingObjectBounds(result, classGenerics, usedTphs);
|
||||
normalize(result, classGenerics, usedTphs);
|
||||
|
||||
System.out.println(this.getClass().getSimpleName() + " " + method.name + ": " + result);
|
||||
return result;
|
||||
@ -631,16 +638,18 @@ public abstract class GenerateGenerics {
|
||||
findTphs(field.getType(), referencedByClass);
|
||||
}
|
||||
|
||||
addMissingObjectBounds(javaResult, null, referencedByClass);
|
||||
normalize(javaResult, null, referencedByClass);
|
||||
|
||||
System.out.println(this.getClass().getSimpleName() + " Class " + classOrInterface.getClassName().getClassName() + ": " + javaResult);
|
||||
return javaResult;
|
||||
}
|
||||
|
||||
void addMissingObjectBounds(Set<Pair> result, Set<Pair> classGenerics, Set<TPH> usedTphs) {
|
||||
void normalize(Set<Pair> result, Set<Pair> classGenerics, Set<TPH> usedTphs) {
|
||||
outer:
|
||||
for (var tph : usedTphs) {
|
||||
for (var p1 : new HashSet<>(result)) {
|
||||
if (p1 instanceof PairLT ptph && ptph.left.equals(ptph.right))
|
||||
result.remove(p1); // TODO This is a bit strange
|
||||
if (p1.left.equals(tph)) continue outer;
|
||||
}
|
||||
|
||||
@ -683,12 +692,13 @@ public abstract class GenerateGenerics {
|
||||
}
|
||||
if (variance == 1) continue;
|
||||
|
||||
|
||||
var start = chain.get(0);
|
||||
var prev = start;
|
||||
for (var i = 1; i < index; i++) {
|
||||
var cur = chain.get(i);
|
||||
if (!referenced.contains(cur)) continue;
|
||||
addToEquality(cur.wrap, start.resolve(), referenced);
|
||||
addToEquality(cur.resolve(), start.resolve(), referenced);
|
||||
TPH finalPrev = prev;
|
||||
input.removeIf(p -> p.equals(new PairLT(finalPrev, cur)));
|
||||
for (var pair2 : new HashSet<>(input)) {
|
||||
@ -722,13 +732,32 @@ public abstract class GenerateGenerics {
|
||||
for (var field : classOrInterface.getFieldDecl()) {
|
||||
findTphs(field.getType(), referenced);
|
||||
}
|
||||
doIterationForMethods(classOrInterface);
|
||||
for (var method : classOrInterface.getMethods()) {
|
||||
generics(classOrInterface, method);
|
||||
referenced.addAll(usedTPHsOfMethods.get(method));
|
||||
}
|
||||
eliminateInnerTypeVariables(referenced, input);
|
||||
}
|
||||
|
||||
void doIterationForMethods(ClassOrInterface classOrInterface) {
|
||||
familyOfMethods.clear();
|
||||
|
||||
var oldFamily = new HashMap<Method, Set<Pair>>();
|
||||
do {
|
||||
oldFamily.clear();
|
||||
oldFamily.putAll(familyOfMethods);
|
||||
familyOfMethods.clear();
|
||||
for (var method : classOrInterface.getMethods()) {
|
||||
family(classOrInterface, method);
|
||||
}
|
||||
System.out.println(familyOfMethods);
|
||||
} while(!oldFamily.equals(familyOfMethods));
|
||||
|
||||
for (var method : classOrInterface.getMethods()) {
|
||||
generics(classOrInterface, method);
|
||||
}
|
||||
}
|
||||
|
||||
private void findChain(Set<TPH> referenced, Set<Pair> input, Set<Pair> output, TPH start, TPH end, Set<TPH> chain) {
|
||||
if (referenced.contains(end)) {
|
||||
var pair = new PairLT(start, end);
|
||||
@ -793,7 +822,7 @@ public abstract class GenerateGenerics {
|
||||
var right = cycle.get(i + 1);
|
||||
var pair = new PairLT(left, right);
|
||||
input.remove(pair);
|
||||
addToEquality(left.wrap, newTph, referenced);
|
||||
addToEquality(left.resolve(), newTph, referenced);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -806,9 +835,10 @@ public abstract class GenerateGenerics {
|
||||
var left = constraint.left;
|
||||
Set<PairLT> infima = new HashSet<>();
|
||||
for (var pair : input) {
|
||||
if (pair instanceof PairLT stph)
|
||||
if (pair.left.wrap.equals(constraint.left.wrap))
|
||||
if (pair instanceof PairLT stph) {
|
||||
if (pair.left.equals(constraint.left))
|
||||
infima.add(stph);
|
||||
}
|
||||
}
|
||||
if (infima.size() > 1) {
|
||||
foundInfima = true;
|
||||
@ -826,19 +856,19 @@ public abstract class GenerateGenerics {
|
||||
addToPairs(input, new PairLT(left, new TPH(newTph)));
|
||||
input.removeAll(infima);
|
||||
for (var infimum : infima) {
|
||||
addToEquality(infimum.right.wrap, newTph, referenced);
|
||||
addToEquality(infimum.right.resolve(), newTph, referenced);
|
||||
new HashSet<>(input).forEach(pair -> {
|
||||
if (pair.left.wrap.equals(infimum.right.wrap)) {
|
||||
if (pair.left.equals(infimum.right)) {
|
||||
input.remove(pair);
|
||||
if (pair instanceof PairLT stph) {
|
||||
if (!newTph.equals(stph.right.wrap))
|
||||
if (!newTph.equals(stph.right.resolve()))
|
||||
addToPairs(input, new PairLT(new TPH(newTph), stph.right));
|
||||
} else if (pair instanceof PairEQ rtph) {
|
||||
addToPairs(input, new PairEQ(new TPH(newTph), rtph.right));
|
||||
}
|
||||
} else if (pair instanceof PairLT stph && stph.right.wrap.equals(infimum.right.wrap)) {
|
||||
} else if (pair instanceof PairLT stph && stph.right.equals(infimum.right)) {
|
||||
input.remove(pair);
|
||||
if (!newTph.equals(stph.left.wrap))
|
||||
if (!newTph.equals(stph.left.resolve()))
|
||||
addToPairs(input, new PairLT(stph.left, new TPH(newTph)));
|
||||
}
|
||||
});
|
||||
|
@ -15,7 +15,7 @@ final class JavaGenerics extends GenerateGenerics {
|
||||
void generics(ClassOrInterface owner, Method method, Set<Pair> result, Set<TPH> referenced) {
|
||||
eliminateCycles(result, referenced);
|
||||
eliminateInfima(result, referenced);
|
||||
//equalizeTypeVariables(result, referenced);
|
||||
equalizeTypeVariables(result, referenced);
|
||||
eliminateInnerTypeVariables(referenced, result);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user