diff --git a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java index 3bf42d7e..f909a59c 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java @@ -48,13 +48,13 @@ public class ASTToTargetAST { @Override void generics(ClassOrInterface owner, Method method, Set> result, HashSet referenced) { - eliminateInfima(result); + eliminateInfima(result, referenced); } @Override void generics(ClassOrInterface classOrInterface, Set> result) { var referenced = new HashSet(); - eliminateInfima(result); + eliminateInfima(result, referenced); eliminateInnerTypeVariablesOfClass(classOrInterface, result, referenced); } } @@ -67,17 +67,17 @@ public class ASTToTargetAST { @Override void generics(ClassOrInterface owner, Method method, Set> result, HashSet referenced) { eliminateCycles(result, referenced); - eliminateInfima(result); - equalizeTypeVariables(result); + eliminateInfima(result, referenced); + equalizeTypeVariables(result, referenced); } @Override void generics(ClassOrInterface classOrInterface, Set> result) { var referenced = new HashSet(); 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>> computedGenericsOfClasses = new HashMap<>(); final Map> usedTPHsOfMethods = new HashMap<>(); + final Map>> familyOfMethods = new HashMap<>(); final Set simplifiedConstraints = new HashSet<>(); final Map 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 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> transitiveClosure(Set> 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> result, HashSet javaTypeVariablesOfClass); Set> family(ClassOrInterface owner, Method method) { + if (familyOfMethods.containsKey(method)) + return familyOfMethods.get(method); + var result = new HashSet>(); + familyOfMethods.put(method, result); + var classGenerics = generics(owner); HashSet 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(); - generics(owner, method, result, referenced); - var usedTphs = new HashSet(); // 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> input) { + void equalizeTypeVariables(Set> input, Set 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(); 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> input) { + void eliminateInfima(Set> input, Set 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);