forked from JavaTX/JavaCompilerCore
Test more thoroughly and add a new infimum deletion strategy
This commit is contained in:
parent
f5aa90bdbd
commit
6079e96efa
@ -1,5 +1,6 @@
|
||||
package de.dhbwstuttgart.target.generate;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
import java.util.AbstractList;
|
||||
@ -7,12 +8,19 @@ import java.util.List;
|
||||
|
||||
public class BoundsList extends AbstractList<Bound> {
|
||||
private final List<Bound> bounds;
|
||||
public final RefTypeOrTPHOrWildcardOrGeneric base;
|
||||
|
||||
public BoundsList(List<Bound> bounds) {
|
||||
public BoundsList(RefTypeOrTPHOrWildcardOrGeneric base, List<Bound> bounds) {
|
||||
this.base = base;
|
||||
this.bounds = bounds;
|
||||
}
|
||||
|
||||
public BoundsList(List<Bound> bounds) {
|
||||
this(null, bounds);
|
||||
}
|
||||
|
||||
public BoundsList(Bound... bounds) {
|
||||
this.bounds = List.of(bounds);
|
||||
this(null, List.of(bounds));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -826,6 +826,50 @@ public abstract class GenerateGenerics {
|
||||
}
|
||||
}
|
||||
|
||||
TPH findConnectionToReturnType(Set<TPH> returnTypes, Set<Pair> input, Set<TPH> visited, TPH tph) {
|
||||
if (returnTypes.contains(tph)) {
|
||||
return tph;
|
||||
} else {
|
||||
for (var pair : input) if (pair instanceof PairLT ptph) {
|
||||
if (ptph.left.equals(tph) && !visited.contains(ptph.right)) {
|
||||
visited.add(ptph.right);
|
||||
var result = findConnectionToReturnType(returnTypes, input, visited, ptph.right);
|
||||
if (result != null) return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void eliminateInfimaConnectedToReturnType(Method method, Set<Pair> input, Set<TPH> referenced) {
|
||||
var foundInfima = false;
|
||||
do {
|
||||
foundInfima = false;
|
||||
for (var constraint : new HashSet<>(input)) {
|
||||
var left = constraint.left;
|
||||
Set<PairLT> infima = new HashSet<>();
|
||||
for (var pair : input) {
|
||||
if (pair instanceof PairLT stph) {
|
||||
if (pair.left.equals(constraint.left))
|
||||
infima.add(stph);
|
||||
}
|
||||
}
|
||||
if (infima.size() > 1) {
|
||||
for (var pair : infima) {
|
||||
var returnTypes = findTypeVariables(method.getReturnType());
|
||||
var returnType = findConnectionToReturnType(returnTypes, input, new HashSet<>(), pair.left);
|
||||
if (returnType != null && !returnType.equals(pair.left)) {
|
||||
System.out.println("Equals now: " + pair.left.resolve() + " " + returnType.resolve());
|
||||
addToEquality(pair.left.resolve(), returnType.resolve(), referenced);
|
||||
foundInfima = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (foundInfima);
|
||||
input.removeIf((i) -> !(i instanceof PairLT lt) || lt.left.equals(lt.right));
|
||||
}
|
||||
|
||||
void eliminateInfima(Set<Pair> input, Set<TPH> referenced) {
|
||||
var foundInfima = false;
|
||||
do {
|
||||
|
@ -31,7 +31,8 @@ public class GenericsResult {
|
||||
}
|
||||
|
||||
public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz, Method method) {
|
||||
type = resolve(type);
|
||||
var resolvedType = resolve(type);
|
||||
type = resolvedType;
|
||||
if (type instanceof TypePlaceholder) {
|
||||
var methodGenerics = get(method);
|
||||
var classGenerics = get(clazz);
|
||||
@ -58,9 +59,9 @@ public class GenericsResult {
|
||||
}
|
||||
bound.ifPresent(result::add);
|
||||
} while (bound.isPresent());
|
||||
return new BoundsList(result);
|
||||
return new BoundsList(resolvedType, result);
|
||||
}
|
||||
return new BoundsList(List.of());
|
||||
return new BoundsList(resolvedType, List.of());
|
||||
}
|
||||
|
||||
public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||
|
@ -14,6 +14,7 @@ final class JavaGenerics extends GenerateGenerics {
|
||||
@Override
|
||||
void generics(ClassOrInterface owner, Method method, Set<Pair> result, Set<TPH> referenced) {
|
||||
eliminateCycles(result, referenced);
|
||||
eliminateInfimaConnectedToReturnType(method, result, referenced);
|
||||
eliminateInfima(result, referenced);
|
||||
equalizeTypeVariables(result, referenced);
|
||||
eliminateInnerTypeVariables(referenced, result);
|
||||
|
@ -37,6 +37,15 @@ public class TestGenerics {
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertStrictlyEquals(BoundsList a, BoundsList b) {
|
||||
assertEquals(a.base, b.base);
|
||||
assertEquals(a, b);
|
||||
}
|
||||
|
||||
private static void assertStrictlyNotEquals(BoundsList a, BoundsList b) {
|
||||
assertNotEquals(a.base, b.base);
|
||||
}
|
||||
|
||||
private static Result computeGenerics(String filename) throws IOException, ClassNotFoundException {
|
||||
var file = Path.of(rootDirectory + filename).toFile();
|
||||
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()));
|
||||
@ -62,7 +71,7 @@ public class TestGenerics {
|
||||
var ECK1 = generics.getBounds(otherMethod.getParameterList().getParameterAt(0).getType(), result.clazz, anyMethod);
|
||||
var ECK2 = generics.getBounds(otherMethod.getReturnType(), result.clazz, anyMethod);
|
||||
var ECKChain = new BoundsList(onClass(OBJECT));
|
||||
assertEquals(ECK1, ECK2);
|
||||
assertStrictlyEquals(ECK1, ECK2);
|
||||
assertEquals(ECK2, generics.getBounds(b.getType(), result.clazz));
|
||||
|
||||
var M = generics.getBounds(a.getType(), result.clazz);
|
||||
@ -92,21 +101,36 @@ public class TestGenerics {
|
||||
|
||||
var generics = result.genericsResults.get(0);
|
||||
assertEquals(0, generics.get(result.clazz).size());
|
||||
assertEquals(1, generics.get(m).size());
|
||||
assertEquals(2, generics.get(main).size());
|
||||
assertEquals(3, generics.get(m).size());
|
||||
assertEquals(3, generics.get(main).size());
|
||||
|
||||
var N = generics.getBounds(m.getParameterList().getParameterAt(0).getType(), result.clazz, m);
|
||||
var N2 = generics.getBounds(m.getReturnType(), result.clazz, m);
|
||||
{
|
||||
var AJ = generics.getBounds(m.getParameterList().getParameterAt(0).getType(), result.clazz, m);
|
||||
var AK = generics.getBounds(m.getParameterList().getParameterAt(1).getType(), result.clazz, m);
|
||||
var KWU = generics.getBounds(((RefType) generics.resolve(m.getReturnType())).getParaList().get(0), result.clazz, m);
|
||||
var AK2 = generics.getBounds(((RefType) generics.resolve(m.getReturnType())).getParaList().get(1), result.clazz, m);
|
||||
|
||||
var NChain = new BoundsList(onMethod(OBJECT));
|
||||
assertEquals(N, N2);
|
||||
assertEquals(N2, NChain);
|
||||
assertStrictlyEquals(AK, AK2);
|
||||
assertStrictlyNotEquals(AJ, KWU);
|
||||
var NChain = new BoundsList(onMethod(OBJECT));
|
||||
assertEquals(AJ, NChain);
|
||||
assertEquals(AK, NChain);
|
||||
assertEquals(KWU, NChain);
|
||||
}
|
||||
|
||||
var R = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
||||
assertEquals(R, NChain);
|
||||
{
|
||||
var O = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
||||
var P = generics.getBounds(main.getParameterList().getParameterAt(1).getType(), result.clazz, main);
|
||||
var KWQ = generics.getBounds(((RefType) generics.resolve(main.getReturnType())).getParaList().get(1), result.clazz, main);
|
||||
var O2 = generics.getBounds(((RefType) generics.resolve(main.getReturnType())).getParaList().get(0), result.clazz, main);
|
||||
|
||||
var Q2 = generics.getBounds(main.getReturnType(), result.clazz, main);
|
||||
assertEquals(Q2, NChain);
|
||||
assertStrictlyEquals(O, O2);
|
||||
assertStrictlyNotEquals(P, KWQ);
|
||||
var NChain = new BoundsList(onMethod(OBJECT));
|
||||
assertEquals(O, NChain);
|
||||
assertEquals(P, NChain);
|
||||
assertEquals(KWQ, NChain);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -307,14 +331,14 @@ public class TestGenerics {
|
||||
var generics = result.genericsResults.get(0);
|
||||
var O = generics.getBounds(id.getReturnType(), result.clazz, id);
|
||||
var O2 = generics.getBounds(id.getParameterList().getParameterAt(0).getType(), result.clazz, id);
|
||||
assertEquals(O, O2);
|
||||
assertStrictlyEquals(O, O2);
|
||||
assertEquals(O2, new BoundsList(onMethod(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);
|
||||
var S2 = generics.getBounds(main.getParameterList().getParameterAt(1).getType(), result.clazz, main);
|
||||
var T = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
||||
assertStrictlyEquals(S, S2);
|
||||
assertEquals(S2, new BoundsList(onMethod(OBJECT)));
|
||||
assertEquals(T, new BoundsList(onMethod(OBJECT)));
|
||||
}
|
||||
@ -355,7 +379,7 @@ public class TestGenerics {
|
||||
var par2 = generics.resolve(main.getParameterList().getParameterAt(0).getType());
|
||||
var ACK2 = generics.getBounds(((RefType) par2).getParaList().get(0), result.clazz, add);
|
||||
var V = generics.getBounds(add.getParameterList().getParameterAt(1).getType(), result.clazz, add);
|
||||
assertEquals(ACK2, ACK);
|
||||
assertStrictlyEquals(ACK2, ACK);
|
||||
assertEquals(V, O);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user