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;
|
package de.dhbwstuttgart.target.generate;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
|
||||||
import java.util.AbstractList;
|
import java.util.AbstractList;
|
||||||
@ -7,12 +8,19 @@ import java.util.List;
|
|||||||
|
|
||||||
public class BoundsList extends AbstractList<Bound> {
|
public class BoundsList extends AbstractList<Bound> {
|
||||||
private final List<Bound> bounds;
|
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;
|
this.bounds = bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BoundsList(List<Bound> bounds) {
|
||||||
|
this(null, bounds);
|
||||||
|
}
|
||||||
|
|
||||||
public BoundsList(Bound... bounds) {
|
public BoundsList(Bound... bounds) {
|
||||||
this.bounds = List.of(bounds);
|
this(null, List.of(bounds));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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) {
|
void eliminateInfima(Set<Pair> input, Set<TPH> referenced) {
|
||||||
var foundInfima = false;
|
var foundInfima = false;
|
||||||
do {
|
do {
|
||||||
|
@ -31,7 +31,8 @@ public class GenericsResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz, Method method) {
|
public BoundsList getBounds(RefTypeOrTPHOrWildcardOrGeneric type, ClassOrInterface clazz, Method method) {
|
||||||
type = resolve(type);
|
var resolvedType = resolve(type);
|
||||||
|
type = resolvedType;
|
||||||
if (type instanceof TypePlaceholder) {
|
if (type instanceof TypePlaceholder) {
|
||||||
var methodGenerics = get(method);
|
var methodGenerics = get(method);
|
||||||
var classGenerics = get(clazz);
|
var classGenerics = get(clazz);
|
||||||
@ -58,9 +59,9 @@ public class GenericsResult {
|
|||||||
}
|
}
|
||||||
bound.ifPresent(result::add);
|
bound.ifPresent(result::add);
|
||||||
} while (bound.isPresent());
|
} 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) {
|
public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
|
@ -14,6 +14,7 @@ final class JavaGenerics extends GenerateGenerics {
|
|||||||
@Override
|
@Override
|
||||||
void generics(ClassOrInterface owner, Method method, Set<Pair> result, Set<TPH> referenced) {
|
void generics(ClassOrInterface owner, Method method, Set<Pair> result, Set<TPH> referenced) {
|
||||||
eliminateCycles(result, referenced);
|
eliminateCycles(result, referenced);
|
||||||
|
eliminateInfimaConnectedToReturnType(method, result, referenced);
|
||||||
eliminateInfima(result, referenced);
|
eliminateInfima(result, referenced);
|
||||||
equalizeTypeVariables(result, referenced);
|
equalizeTypeVariables(result, referenced);
|
||||||
eliminateInnerTypeVariables(referenced, result);
|
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 {
|
private static Result computeGenerics(String filename) throws IOException, ClassNotFoundException {
|
||||||
var file = Path.of(rootDirectory + filename).toFile();
|
var file = Path.of(rootDirectory + filename).toFile();
|
||||||
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()));
|
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 ECK1 = generics.getBounds(otherMethod.getParameterList().getParameterAt(0).getType(), result.clazz, anyMethod);
|
||||||
var ECK2 = generics.getBounds(otherMethod.getReturnType(), result.clazz, anyMethod);
|
var ECK2 = generics.getBounds(otherMethod.getReturnType(), result.clazz, anyMethod);
|
||||||
var ECKChain = new BoundsList(onClass(OBJECT));
|
var ECKChain = new BoundsList(onClass(OBJECT));
|
||||||
assertEquals(ECK1, ECK2);
|
assertStrictlyEquals(ECK1, ECK2);
|
||||||
assertEquals(ECK2, generics.getBounds(b.getType(), result.clazz));
|
assertEquals(ECK2, generics.getBounds(b.getType(), result.clazz));
|
||||||
|
|
||||||
var M = generics.getBounds(a.getType(), result.clazz);
|
var M = generics.getBounds(a.getType(), result.clazz);
|
||||||
@ -92,21 +101,36 @@ 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(1, generics.get(m).size());
|
assertEquals(3, generics.get(m).size());
|
||||||
assertEquals(2, generics.get(main).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));
|
assertStrictlyEquals(AK, AK2);
|
||||||
assertEquals(N, N2);
|
assertStrictlyNotEquals(AJ, KWU);
|
||||||
assertEquals(N2, NChain);
|
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);
|
assertStrictlyEquals(O, O2);
|
||||||
assertEquals(Q2, NChain);
|
assertStrictlyNotEquals(P, KWQ);
|
||||||
|
var NChain = new BoundsList(onMethod(OBJECT));
|
||||||
|
assertEquals(O, NChain);
|
||||||
|
assertEquals(P, NChain);
|
||||||
|
assertEquals(KWQ, NChain);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -307,14 +331,14 @@ public class TestGenerics {
|
|||||||
var generics = result.genericsResults.get(0);
|
var generics = result.genericsResults.get(0);
|
||||||
var O = generics.getBounds(id.getReturnType(), result.clazz, id);
|
var O = generics.getBounds(id.getReturnType(), result.clazz, id);
|
||||||
var O2 = generics.getBounds(id.getParameterList().getParameterAt(0).getType(), 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)));
|
assertEquals(O2, new BoundsList(onMethod(OBJECT)));
|
||||||
|
|
||||||
// TODO Maybe test in other ways if the parameter generics equals the return generics
|
// TODO Maybe test in other ways if the parameter generics equals the return generics
|
||||||
var S = generics.getBounds(main.getReturnType(), result.clazz, main);
|
var S = generics.getBounds(main.getReturnType(), result.clazz, main);
|
||||||
var S2 = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
var S2 = generics.getBounds(main.getParameterList().getParameterAt(1).getType(), result.clazz, main);
|
||||||
var T = generics.getBounds(main.getParameterList().getParameterAt(1).getType(), result.clazz, main);
|
var T = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
||||||
assertEquals(S, S2);
|
assertStrictlyEquals(S, S2);
|
||||||
assertEquals(S2, new BoundsList(onMethod(OBJECT)));
|
assertEquals(S2, new BoundsList(onMethod(OBJECT)));
|
||||||
assertEquals(T, 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 par2 = generics.resolve(main.getParameterList().getParameterAt(0).getType());
|
||||||
var ACK2 = generics.getBounds(((RefType) par2).getParaList().get(0), result.clazz, add);
|
var ACK2 = generics.getBounds(((RefType) par2).getParaList().get(0), result.clazz, add);
|
||||||
var V = generics.getBounds(add.getParameterList().getParameterAt(1).getType(), result.clazz, add);
|
var V = generics.getBounds(add.getParameterList().getParameterAt(1).getType(), result.clazz, add);
|
||||||
assertEquals(ACK2, ACK);
|
assertStrictlyEquals(ACK2, ACK);
|
||||||
assertEquals(V, O);
|
assertEquals(V, O);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user