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