diff --git a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java index 790a9084..84f81958 100644 --- a/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java +++ b/src/main/java/de/dhbwstuttgart/target/generate/ASTToTargetAST.java @@ -15,7 +15,6 @@ import de.dhbwstuttgart.target.tree.expression.TargetBlock; import de.dhbwstuttgart.target.tree.expression.TargetExpression; import de.dhbwstuttgart.target.tree.type.*; import de.dhbwstuttgart.typeinference.result.*; -import de.dhbwstuttgart.util.BiRelation; import java.util.*; import java.util.stream.Collectors; @@ -61,18 +60,20 @@ public class ASTToTargetAST { System.out.println("Simplified constraints: " + simplifiedConstraints); } - void findTypeVariables(RefTypeOrTPHOrWildcardOrGeneric type, Set typeVariables) { + Set findTypeVariables(RefTypeOrTPHOrWildcardOrGeneric type) { + var result = new HashSet(); if (type instanceof TypePlaceholder tph) { tph = equality.getOrDefault(tph, tph); if (concreteTypes.containsKey(tph)) { - findTypeVariables(concreteTypes.get(tph), typeVariables); - return; + result.addAll(findTypeVariables(concreteTypes.get(tph))); + return result; } - typeVariables.add(tph); + result.add(tph); } else if (type instanceof RefType refType) { for (var t : refType.getParaList()) - findTypeVariables(t, typeVariables); + result.addAll(findTypeVariables(t)); } + return result; } boolean hasBound(TypePlaceholder name, Set> generics) { @@ -125,27 +126,29 @@ public class ASTToTargetAST { HashSet typeVariables = new HashSet<>(); HashSet typeVariablesOfFields = new HashSet<>(); - HashSet allTypeVariables = new HashSet<>(); + HashSet typeVariablesOfLocals = new HashSet<>(); for (var field : owner.getFieldDecl()) { - findTypeVariables(field.getType(), typeVariablesOfFields); + typeVariablesOfFields.addAll(findTypeVariables(field.getType())); } //findTypeVariables(method.getReturnType(), typeVariables); for (var arg : method.getParameterList().getFormalparalist()) { - findTypeVariables(arg.getType(), typeVariables); + typeVariables.addAll(findTypeVariables(arg.getType())); } method.block.accept(new TracingStatementVisitor() { @Override public void visit(LocalVarDecl localVarDecl) { - findTypeVariables(localVarDecl.getType(), typeVariables); + var tphs = findTypeVariables(localVarDecl.getType()); + typeVariablesOfLocals.addAll(tphs); + typeVariables.addAll(tphs); } @Override public void visit(MethodCall methodCall) { super.visit(methodCall); - findTypeVariables(methodCall.getType(), typeVariables); + typeVariables.addAll(findTypeVariables(methodCall.getType())); } @Override @@ -164,7 +167,6 @@ public class ASTToTargetAST { } - var visitedMethods = new HashSet(); method.block.accept(new TracingStatementVisitor() { private RefTypeOrTPHOrWildcardOrGeneric superType = new Void(new NullToken()); @@ -181,8 +183,11 @@ public class ASTToTargetAST { .map(x -> x.getType()) .collect(Collectors.toCollection(HashSet::new)) .stream().filter(x -> x instanceof TypePlaceholder) + .map(tph -> equality.getOrDefault(tph, (TypePlaceholder) tph)) .collect(Collectors.toCollection(HashSet::new)); RefTypeOrTPHOrWildcardOrGeneric T2 = superType; + if (T2 instanceof TypePlaceholder tph) T2 = equality.getOrDefault(tph, tph); + System.out.println("T1s: " + T1s + "\nT2: " + T2); //Ende @@ -198,8 +203,6 @@ public class ASTToTargetAST { var optMethod = findMethod(owner, methodCall.name, methodCall.getArgumentList()); if (optMethod.isEmpty()) return; var method = optMethod.get(); - if (visitedMethods.contains(method)) return; - visitedMethods.add(method); var generics = generics(owner, method); Set> all = new HashSet<>(generics); @@ -226,8 +229,6 @@ public class ASTToTargetAST { all.addAll(toAdd); HashSet newPairs = new HashSet<>(); - System.out.println("Result: " + result); - // Loop from hell outer: for (var tph : typeVariables) { @@ -459,12 +460,19 @@ public class ASTToTargetAST { } eliminateCyclesAndInfima(result); - System.out.println(method.name + ": " + result); + usedTPHsOfMethods.put(method, typeVariables); - Set allUsedTPHs = new HashSet<>(); - allUsedTPHs.addAll(typeVariables); - allUsedTPHs.addAll(typeVariablesOfFields); - usedTPHsOfMethods.put(method, allUsedTPHs); + // For eliminating inner type variables we need to figure out which ones are actually used + var typeVariablesOfSignature = new HashSet(); + for (var param : method.getParameterList().getFormalparalist()) { + if (param.getType() instanceof TypePlaceholder tph) + typeVariablesOfSignature.add(equality.getOrDefault(tph, tph)); + } + if (method.getReturnType() instanceof TypePlaceholder tph) + typeVariablesOfSignature.add(equality.getOrDefault(tph, tph)); + + eliminateInnerTypeVariables(typeVariablesOfSignature, result); + System.out.println(method.name + ": " + result); return result; } @@ -509,7 +517,7 @@ public class ASTToTargetAST { } computedGenericsOfClasses.put(classOrInterface, result); eliminateCyclesAndInfima(result); - eliminateInnerTypeVariables(classOrInterface, result); + eliminateInnerTypeVariablesOfClass(classOrInterface, result); equalizeTypeVariables(result); @@ -548,7 +556,7 @@ public class ASTToTargetAST { } } - void eliminateInnerTypeVariables(ClassOrInterface classOrInterface, Set> input) { + void eliminateInnerTypeVariablesOfClass(ClassOrInterface classOrInterface, Set> input) { Set referenced = new HashSet<>(); for (var field : classOrInterface.getFieldDecl()) { findTphs(field.getType(), referenced); @@ -557,27 +565,25 @@ public class ASTToTargetAST { generics(classOrInterface, method); referenced.addAll(usedTPHsOfMethods.get(method)); } + eliminateInnerTypeVariables(referenced, input); + } + void eliminateInnerTypeVariables(Set referenced, Set> input) { var oldInput = new HashSet<>(input); for (var pair : oldInput) { - if (!referenced.contains(pair.getLeft())) { + if (pair instanceof PairTPHsmallerTPH ptph && !referenced.contains(ptph.left)) { input.remove(pair); - if (pair instanceof PairTPHsmallerTPH ptph) - equality.put(ptph.left, ptph.right); + equality.put(ptph.left, ptph.right); for (var pair2 : oldInput) { if (pair2.getRight().equals(pair.getLeft())) { input.remove(pair2); - if (pair instanceof PairTPHsmallerTPH) - addToPairs(input, new PairTPHsmallerTPH((TypePlaceholder) pair2.getLeft(), (TypePlaceholder) pair.getRight())); - else - addToPairs(input, new PairTPHequalRefTypeOrWildcardType((TypePlaceholder) pair2.getLeft(), pair.getRight())); + addToPairs(input, new PairTPHsmallerTPH((TypePlaceholder) pair2.getLeft(), (TypePlaceholder) pair.getRight())); } } } } } - void eliminateCycles(Set> input) { var cycles = findCycles(input); for (var cycle : cycles) {