Eliminate transitive children, add missing object bounds
This commit is contained in:
parent
af4db1817a
commit
904bdca2f4
@ -5,7 +5,7 @@ public class TestContraVariant {
|
||||
x = y;
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
main(x) {
|
||||
return m(x);
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
public class TestTwoCalls {
|
||||
|
||||
// <O> O -> O
|
||||
id(b) {
|
||||
var c = b;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
// <T, S> (S, T) -> T
|
||||
main(x,y) {
|
||||
id(x);
|
||||
return id(y);
|
||||
|
@ -552,6 +552,7 @@ public class ASTToTargetAST {
|
||||
methodFindConstraints(owner, method, simplifiedConstraints, txTypeVariables, classGenerics.userDefinedGenerics, txTypeVariablesOfClass, txResult, txEquality);
|
||||
|
||||
{ // Java Generics
|
||||
eliminateTransitives(javaResult);
|
||||
var referenced = new HashSet<TypePlaceholder>();
|
||||
|
||||
eliminateCycles(javaResult, equality, referenced);
|
||||
@ -569,10 +570,12 @@ public class ASTToTargetAST {
|
||||
eliminateInnerTypeVariables(referenced, javaResult);
|
||||
equalizeTypeVariables(javaResult, equality);
|
||||
usedTPHsOfMethods.put(method, usedTphs);
|
||||
addMissingObjectBounds(javaResult, genericsOfClass);
|
||||
}
|
||||
{
|
||||
var referenced = new HashSet<TypePlaceholder>();
|
||||
// JavaTX Generics
|
||||
eliminateTransitives(txResult);
|
||||
eliminateInfima(txResult, txEquality);
|
||||
|
||||
for (var param : method.getParameterList().getFormalparalist()) {
|
||||
@ -582,12 +585,36 @@ public class ASTToTargetAST {
|
||||
referenced.addAll(txTypeVariablesOfClass);
|
||||
|
||||
eliminateInnerTypeVariables(referenced, txResult);
|
||||
addMissingObjectBounds(txResult, txGenericsOfClass);
|
||||
}
|
||||
|
||||
System.out.println(method.name + ": " + txResult + " & " + javaResult);
|
||||
return generics;
|
||||
}
|
||||
|
||||
private void eliminateChain(Set<ResultPair<?, ?>> result, List<TypePlaceholder> chain) {
|
||||
for (var pair : new HashSet<>(result)) {
|
||||
if (pair instanceof PairTPHsmallerTPH ptph && chain.get(chain.size() - 1).equals(ptph.left)) {
|
||||
if (chain.contains(ptph.right)) return;
|
||||
var copy = new ArrayList<>(chain);
|
||||
copy.add(ptph.right);
|
||||
if (copy.size() > 2)
|
||||
result.remove(new PairTPHsmallerTPH(chain.get(0), ptph.right));
|
||||
eliminateChain(result, copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void eliminateTransitives(Set<ResultPair<?,?>> result) {
|
||||
for (var pair : new HashSet<>(result)) if (pair instanceof PairTPHsmallerTPH ptph) {
|
||||
var first = ptph.left;
|
||||
var chain = new ArrayList<TypePlaceholder>();
|
||||
chain.add(ptph.left);
|
||||
chain.add(ptph.right);
|
||||
eliminateChain(result, chain);
|
||||
}
|
||||
}
|
||||
|
||||
void findAllBounds(RefTypeOrTPHOrWildcardOrGeneric type, Set<ResultPair<?, ?>> generics, Map<TypePlaceholder, TypePlaceholder> equality) {
|
||||
if (type instanceof TypePlaceholder tph) {
|
||||
tph = equality.getOrDefault(tph, tph);
|
||||
@ -632,6 +659,9 @@ public class ASTToTargetAST {
|
||||
findAllBounds(field.getType(), txResult, txEquality);
|
||||
}
|
||||
|
||||
eliminateTransitives(javaResult);
|
||||
eliminateTransitives(txResult);
|
||||
System.out.println(javaResult);
|
||||
var referenced = new HashSet<TypePlaceholder>();
|
||||
eliminateCycles(javaResult, equality, referenced);
|
||||
eliminateInfima(javaResult, equality);
|
||||
@ -642,10 +672,26 @@ public class ASTToTargetAST {
|
||||
equalizeTypeVariables(javaResult, equality);
|
||||
eliminateInnerTypeVariablesOfClass(classOrInterface, txResult, txEquality, txReferenced);
|
||||
|
||||
addMissingObjectBounds(javaResult, null);
|
||||
addMissingObjectBounds(txResult, null);
|
||||
|
||||
System.out.println("Class " + classOrInterface.getClassName().getClassName() + ": " + txResult + ", " + javaResult);
|
||||
return generics;
|
||||
}
|
||||
|
||||
void addMissingObjectBounds(Set<ResultPair<?,?>> result, Set<ResultPair<?, ?>> filter) {
|
||||
outer: for (var p1 : new HashSet<>(result)) {
|
||||
if (p1 instanceof PairTPHsmallerTPH ptph) {
|
||||
for (var p2 : new HashSet<>(result)) {
|
||||
if (ptph.right.equals(p2.getLeft()))
|
||||
continue outer;
|
||||
}
|
||||
if (filter == null || filter.stream().noneMatch((pair) -> pair.getLeft().equals(ptph.right)))
|
||||
result.add(new PairTPHequalRefTypeOrWildcardType(ptph.right, OBJECT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void equalizeTypeVariables(Set<ResultPair<?, ?>> input, Map<TypePlaceholder, TypePlaceholder> equality) {
|
||||
for (var pair : new HashSet<>(input)) {
|
||||
if (pair instanceof PairTPHsmallerTPH ptph) {
|
||||
|
@ -90,16 +90,15 @@ public class TestGenerics {
|
||||
|
||||
var generics = result.genericsResults.get(0);
|
||||
assertEquals(0, generics.get(result.clazz).size());
|
||||
assertEquals(2, generics.get(m).size());
|
||||
assertEquals(1, generics.get(m).size());
|
||||
assertEquals(2, generics.get(main).size());
|
||||
|
||||
var N = generics.getBounds(m.getParameterList().getParameterAt(0).getType(), result.clazz, m);
|
||||
var NChain = new BoundsList(new Bound(true, ASTToTargetAST.OBJECT));
|
||||
assertEquals(N, NChain);
|
||||
var N2 = generics.getBounds(m.getReturnType(), result.clazz, m);
|
||||
|
||||
var Q = generics.getBounds(m.getReturnType(), result.clazz, m);
|
||||
var QChain = new BoundsList(new Bound(true, TypePlaceholder.of("N")), new Bound(true, ASTToTargetAST.OBJECT));
|
||||
assertEquals(Q, QChain);
|
||||
var NChain = new BoundsList(new Bound(true, ASTToTargetAST.OBJECT));
|
||||
assertEquals(N, N2);
|
||||
assertEquals(N2, NChain);
|
||||
|
||||
var R = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
||||
assertEquals(R, NChain);
|
||||
@ -304,17 +303,18 @@ public class TestGenerics {
|
||||
var main = result.findMethod("main");
|
||||
|
||||
var generics = result.genericsResults.get(0);
|
||||
var Q = generics.getBounds(id.getReturnType(), result.clazz, id);
|
||||
var N = generics.getBounds(id.getParameterList().getParameterAt(0).getType(), result.clazz, id);
|
||||
assertEquals(Q, new BoundsList(new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
assertEquals(N, new BoundsList(new Bound(true, TypePlaceholder.of("Q")), new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
var O = generics.getBounds(id.getReturnType(), result.clazz, id);
|
||||
var O2 = generics.getBounds(id.getParameterList().getParameterAt(0).getType(), result.clazz, id);
|
||||
assertEquals(O, O2);
|
||||
assertEquals(O2, new BoundsList(new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
|
||||
var Q2 = generics.getBounds(main.getReturnType(), result.clazz, main);
|
||||
var R = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
||||
var S = generics.getBounds(main.getParameterList().getParameterAt(1).getType(), result.clazz, main);
|
||||
assertEquals(Q2, new BoundsList(new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
assertEquals(R, new BoundsList(new Bound(true, TypePlaceholder.of("Q")), new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
assertEquals(S, new BoundsList(new Bound(true, TypePlaceholder.of("Q")), new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
// TODO Maybe test in other ways if the parameter generics equals the return generics
|
||||
var S = generics.getBounds(main.getReturnType(), result.clazz, main);
|
||||
var S2 = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
||||
var T = generics.getBounds(main.getParameterList().getParameterAt(1).getType(), result.clazz, main);
|
||||
assertEquals(S, S2);
|
||||
assertEquals(S2, new BoundsList(new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
assertEquals(T, new BoundsList(new Bound(true, ASTToTargetAST.OBJECT)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user