diff --git a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java index 43e11469..fbe9ce75 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java @@ -218,7 +218,7 @@ public class ASTToTargetAST { for (var g2 : all) { if (g1 instanceof PairTPHsmallerTPH pair) { if (g2.getLeft().equals(pair.getLeft()) && generics.stream().anyMatch(generic -> generic.getLeft().equals(pair.getRight()))) - toAdd.add(new PairTPHsmallerTPH((TypePlaceholder) g1.getLeft(), (TypePlaceholder) g2.getRight())); + toAdd.add(new PairTPHsmallerTPH(pair.left, pair.right)); } } } @@ -460,17 +460,22 @@ public class ASTToTargetAST { } } eliminateCyclesAndInfima(result); - usedTPHsOfMethods.put(method, typeVariables); // For eliminating inner type variables we need to figure out which ones are actually used // TODO Maybe don't do this twice? - var typeVariablesOfSignature = new HashSet(); + var referenced = new HashSet(); for (var param : method.getParameterList().getFormalparalist()) { - typeVariablesOfSignature.addAll(findTypeVariables(param.getType())); + referenced.addAll(findTypeVariables(param.getType())); + } + referenced.addAll(findTypeVariables(method.getReturnType())); + for (var g : genericsOfClass) { + if (g.getLeft() instanceof TypePlaceholder left) + referenced.add(left); } - typeVariablesOfSignature.addAll(findTypeVariables(method.getReturnType())); - eliminateInnerTypeVariables(typeVariablesOfSignature, result); + eliminateInnerTypeVariables(referenced, result); + usedTPHsOfMethods.put(method, referenced); + System.out.println(method.name + ": " + result); return result; @@ -567,37 +572,42 @@ public class ASTToTargetAST { eliminateInnerTypeVariables(referenced, input); } + private void findChain(Set referenced, Set> input, Set> output, TypePlaceholder start, TypePlaceholder end, Set chain) { + if (referenced.contains(end)) { + var pair = new PairTPHsmallerTPH(start, end); + if (input.contains(pair)) output.add(pair); + } + for (var pair : input) { + if (pair instanceof PairTPHsmallerTPH ptph && ptph.left.equals(end)) { + if (chain.contains(ptph.right)) return; + chain = new HashSet<>(chain); + chain.add(ptph.right); + findChain(referenced, input, output, start, ptph.right, chain); + } + } + } + void eliminateInnerTypeVariables(Set referenced, Set> input) { - // Remove type variables that are part of a relation A < B < C where B is not in referenced - // Add new pair A < C - var oldInput = new HashSet<>(input); - for (var pair : oldInput) { - if (pair instanceof PairTPHsmallerTPH ptph && !referenced.contains(ptph.left)) { - input.remove(pair); - equality.put(ptph.left, ptph.right); - for (var pair2 : oldInput) { - if (pair2.getRight().equals(pair.getLeft())) { - input.remove(pair2); - addToPairs(input, new PairTPHsmallerTPH((TypePlaceholder) pair2.getLeft(), (TypePlaceholder) pair.getRight())); - } + var output = new HashSet>(); + for (var tph : referenced) { + for (var pair : input) { + if (pair instanceof PairTPHsmallerTPH pthp && pthp.left.equals(tph)) { + var chain = new HashSet(); + chain.add(tph); + chain.add(pthp.right); + findChain(referenced, input, output, tph, pthp.right, chain); } } } + for (var pair : input) { + if (pair instanceof PairTPHequalRefTypeOrWildcardType rtph) { + if (referenced.contains(rtph.left)) + output.add(rtph); + } + } - // Remove lone type variables, A = RefType where A is in no relation X < A or A < X and A is not in referenced - oldInput = new HashSet<>(input); - outer: - for (var pair : oldInput) { - if (pair instanceof PairTPHequalRefTypeOrWildcardType ptph) { - if (!referenced.contains(ptph.left)) { - for (var pair2 : oldInput) { - if (pair != pair2 && (pair2.getLeft().equals(ptph.left) || pair2.getRight().equals(ptph.left))) - continue outer; - } - input.remove(pair); - } - } - } + input.clear(); + input.addAll(output); } void eliminateCycles(Set> input) { diff --git a/src/test/java/targetast/TestComplete.java b/src/test/java/targetast/TestComplete.java index b2f38f77..4cbe231a 100644 --- a/src/test/java/targetast/TestComplete.java +++ b/src/test/java/targetast/TestComplete.java @@ -14,7 +14,6 @@ import static org.junit.Assert.*; import static targetast.TestCodegen.generateClassFiles; public class TestComplete { - @Test public void applyLambdaTest() throws Exception { var classFiles = generateClassFiles("applyLambda.jav", new ByteArrayClassLoader());