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