This commit is contained in:
Daniel Holle 2023-05-03 10:51:53 +02:00
parent b0cbac529e
commit 25c0c9c101

View File

@ -48,13 +48,13 @@ public class ASTToTargetAST {
@Override
void generics(ClassOrInterface owner, Method method, Set<ResultPair<?, ?>> result, HashSet<TypePlaceholder> referenced) {
eliminateInfima(result);
eliminateInfima(result, referenced);
}
@Override
void generics(ClassOrInterface classOrInterface, Set<ResultPair<?, ?>> result) {
var referenced = new HashSet<TypePlaceholder>();
eliminateInfima(result);
eliminateInfima(result, referenced);
eliminateInnerTypeVariablesOfClass(classOrInterface, result, referenced);
}
}
@ -67,17 +67,17 @@ public class ASTToTargetAST {
@Override
void generics(ClassOrInterface owner, Method method, Set<ResultPair<?, ?>> result, HashSet<TypePlaceholder> referenced) {
eliminateCycles(result, referenced);
eliminateInfima(result);
equalizeTypeVariables(result);
eliminateInfima(result, referenced);
equalizeTypeVariables(result, referenced);
}
@Override
void generics(ClassOrInterface classOrInterface, Set<ResultPair<?, ?>> result) {
var referenced = new HashSet<TypePlaceholder>();
eliminateCycles(result, referenced);
eliminateInfima(result);
eliminateInfima(result, referenced);
eliminateInnerTypeVariablesOfClass(classOrInterface, result, referenced);
equalizeTypeVariables(result);
equalizeTypeVariables(result, referenced);
}
}
@ -86,6 +86,7 @@ public class ASTToTargetAST {
final Map<ClassOrInterface, Set<ResultPair<?, ?>>> computedGenericsOfClasses = new HashMap<>();
final Map<Method, Set<TypePlaceholder>> usedTPHsOfMethods = new HashMap<>();
final Map<Method, Set<ResultPair<?, ?>>> familyOfMethods = new HashMap<>();
final Set<PairTPHsmallerTPH> simplifiedConstraints = new HashSet<>();
final Map<TypePlaceholder, RefTypeOrTPHOrWildcardOrGeneric> concreteTypes = new HashMap<>();
@ -159,7 +160,7 @@ public class ASTToTargetAST {
input.add(pair);
}
void addToEquality(TypePlaceholder from, TypePlaceholder to) {
void addToEquality(TypePlaceholder from, TypePlaceholder to, Set<TypePlaceholder> referenced) {
for (var entry : new HashSet<>(equality.entrySet())) {
if (entry.getValue().equals(from)) {
equality.remove(entry.getKey());
@ -167,6 +168,8 @@ public class ASTToTargetAST {
}
}
equality.put(from, to);
referenced.remove(from);
referenced.add(to);
}
static Set<ResultPair<?, ?>> transitiveClosure(Set<ResultPair<?, ?>> generics) {
@ -354,8 +357,6 @@ public class ASTToTargetAST {
}
});
System.out.println(method.getName() + " " + result);
var closure = transitiveClosure((Set) simplifiedConstraints);
// Type variables with bounds that are also type variables of the class
for (var typeVariable : new HashSet<>(typeVariables)) {
@ -456,7 +457,12 @@ public class ASTToTargetAST {
abstract void generics(ClassOrInterface owner, Method method, Set<ResultPair<?,?>> result, HashSet<TypePlaceholder> javaTypeVariablesOfClass);
Set<ResultPair<?, ?>> family(ClassOrInterface owner, Method method) {
if (familyOfMethods.containsKey(method))
return familyOfMethods.get(method);
var result = new HashSet<ResultPair<?, ?>>();
familyOfMethods.put(method, result);
var classGenerics = generics(owner);
HashSet<TypePlaceholder> typeVariablesOfClass = new HashSet<>();
@ -485,13 +491,11 @@ public class ASTToTargetAST {
typeVariablesOfClass.add((TypePlaceholder) pair.getLeft());
}
var result = family(owner, method);
var result = new HashSet<>(family(owner, method));
computedGenericsOfMethods.put(method, result);
var referenced = new HashSet<TypePlaceholder>();
generics(owner, method, result, referenced);
var usedTphs = new HashSet<TypePlaceholder>();
// For eliminating inner type variables we need to figure out which ones are actually used
for (var param : method.getParameterList().getFormalparalist()) {
@ -501,6 +505,7 @@ public class ASTToTargetAST {
referenced.addAll(usedTphs);
referenced.addAll(typeVariablesOfClass);
generics(owner, method, result, referenced);
usedTPHsOfMethods.put(method, usedTphs);
eliminateInnerTypeVariables(referenced, result);
@ -597,9 +602,9 @@ public class ASTToTargetAST {
}
}
void equalizeTypeVariables(Set<ResultPair<?, ?>> input) {
void equalizeTypeVariables(Set<ResultPair<?, ?>> input, Set<TypePlaceholder> referenced) {
for (var pair : new HashSet<>(input)) {
if (pair instanceof PairTPHsmallerTPH ptph) {
if (pair instanceof PairTPHsmallerTPH ptph && referenced.contains(ptph.left)) {
var chain = new ArrayList<TypePlaceholder>();
chain.add(ptph.left);
chain.add(ptph.right);
@ -623,7 +628,7 @@ public class ASTToTargetAST {
if (variance == 1 && tph.getVariance() == -1) {
variance = -1;
}
if (variance == -1 && tph.getVariance() == 1) {
if (variance == -1 && tph.getVariance() == 1 && referenced.contains(tph)) {
break;
}
index++;
@ -634,8 +639,9 @@ public class ASTToTargetAST {
var prev = start;
for (var i = 1; i < index; i++) {
var cur = chain.get(i);
addToEquality(cur, start);
input.remove(new PairTPHsmallerTPH(prev, chain.get(i)));
if (!referenced.contains(cur)) continue;
addToEquality(cur, start, referenced);
input.remove(new PairTPHsmallerTPH(prev, cur));
for (var pair2 : new HashSet<>(input)) {
// TODO Maybe this would be unnecessary if we were to add the = constraints later on
if (pair2 instanceof PairTPHequalRefTypeOrWildcardType && pair2.getLeft().equals(cur)) {
@ -738,12 +744,12 @@ public class ASTToTargetAST {
var right = cycle.get(i + 1);
var pair = new PairTPHsmallerTPH(left, right);
input.remove(pair);
addToEquality(left, newTph);
addToEquality(left, newTph, referenced);
}
}
}
void eliminateInfima(Set<ResultPair<?, ?>> input) {
void eliminateInfima(Set<ResultPair<?, ?>> input, Set<TypePlaceholder> referenced) {
var foundInfima = false;
do {
foundInfima = false;
@ -771,7 +777,7 @@ public class ASTToTargetAST {
addToPairs(input, new PairTPHsmallerTPH(left, newTph));
input.removeAll(infima);
for (var infimum : infima) {
addToEquality(infimum.right, newTph);
addToEquality(infimum.right, newTph, referenced);
new HashSet<>(input).forEach(pair -> {
if (pair.getLeft().equals(infimum.right)) {
input.remove(pair);