Remove bounds with Object when more concrete bounds are added

This commit is contained in:
Victorious3 2022-09-22 22:01:28 +02:00
parent 247eb0ef79
commit a660d7a295
2 changed files with 27 additions and 24 deletions

View File

@ -1,8 +1,6 @@
package de.dhbwstuttgart.target.generate; package de.dhbwstuttgart.target.generate;
import com.google.j2objc.annotations.LoopTranslation;
import de.dhbwstuttgart.bytecode.funN.FunNGenerator; import de.dhbwstuttgart.bytecode.funN.FunNGenerator;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
@ -89,6 +87,19 @@ public class ASTToTargetAST {
return containsLeft && containsRight; return containsLeft && containsRight;
} }
static void addToPairs(Set<ResultPair<?, ?>> input, ResultPair<?, ?> pair) {
if (pair instanceof PairTPHsmallerTPH) {
input.removeIf(pair2 -> {
if (pair2 instanceof PairTPHequalRefTypeOrWildcardType) {
return pair2.getLeft().equals(pair.getLeft()) && pair2.getRight().equals(OBJECT);
}
return false;
});
}
input.add(pair);
}
// Family of generated Generics // Family of generated Generics
Set<ResultPair<?, ?>> generics(ClassOrInterface owner, Method method) { Set<ResultPair<?, ?>> generics(ClassOrInterface owner, Method method) {
if (computedGenericsOfMethods.containsKey(method)) if (computedGenericsOfMethods.containsKey(method))
@ -133,7 +144,7 @@ public class ASTToTargetAST {
for (var typeVariable : new HashSet<>(typeVariables)) { for (var typeVariable : new HashSet<>(typeVariables)) {
for (var pair : simplifiedConstraints) { for (var pair : simplifiedConstraints) {
if (pair.left.equals(typeVariable) && typeVariables.contains(pair.right)) { if (pair.left.equals(typeVariable) && typeVariables.contains(pair.right)) {
result.add(new PairTPHsmallerTPH(pair.left, equality.getOrDefault(pair.right, pair.right))); addToPairs(result, new PairTPHsmallerTPH(pair.left, equality.getOrDefault(pair.right, pair.right)));
typeVariables.add(pair.right); typeVariables.add(pair.right);
} }
} }
@ -199,7 +210,7 @@ public class ASTToTargetAST {
newPairs.add(newPair); newPairs.add(newPair);
if (!containsRelation(result, newPair)) if (!containsRelation(result, newPair))
result.add(newPair); addToPairs(result, newPair);
continue outer; continue outer;
} }
} }
@ -216,7 +227,7 @@ public class ASTToTargetAST {
for (var typeVariable : new HashSet<>(typeVariables)) { for (var typeVariable : new HashSet<>(typeVariables)) {
for (var pair : simplifiedConstraints) { for (var pair : simplifiedConstraints) {
if (pair.left.equals(typeVariable) && typeVariablesOfFields.contains(pair.right)) { if (pair.left.equals(typeVariable) && typeVariablesOfFields.contains(pair.right)) {
result.add(new PairTPHsmallerTPH(pair.left, equality.getOrDefault(pair.right, pair.right))); addToPairs(result, new PairTPHsmallerTPH(pair.left, equality.getOrDefault(pair.right, pair.right)));
typeVariables.add(pair.right); typeVariables.add(pair.right);
} }
} }
@ -230,7 +241,7 @@ public class ASTToTargetAST {
continue outer; continue outer;
} }
if (!hasBound(typeVariable, genericsOfClass)) if (!hasBound(typeVariable, genericsOfClass))
result.add(new PairTPHequalRefTypeOrWildcardType(typeVariable, OBJECT)); addToPairs(result, new PairTPHequalRefTypeOrWildcardType(typeVariable, OBJECT));
} }
// All unbounded bounds // All unbounded bounds
@ -241,7 +252,7 @@ public class ASTToTargetAST {
continue outer; continue outer;
} }
if (!hasBound(pair.right, genericsOfClass) && typeVariables.contains(pair.right)) if (!hasBound(pair.right, genericsOfClass) && typeVariables.contains(pair.right))
result.add(new PairTPHequalRefTypeOrWildcardType(pair.right, OBJECT)); addToPairs(result, new PairTPHequalRefTypeOrWildcardType(pair.right, OBJECT));
} }
eliminateCyclesAndInfima(result); eliminateCyclesAndInfima(result);
@ -309,7 +320,7 @@ public class ASTToTargetAST {
for (var pair2 : new HashSet<>(input)) { for (var pair2 : new HashSet<>(input)) {
if (pair2 instanceof PairTPHsmallerTPH ptph2 && ptph2.right.equals(ptph.left)) { if (pair2 instanceof PairTPHsmallerTPH ptph2 && ptph2.right.equals(ptph.left)) {
input.remove(pair2); input.remove(pair2);
input.add(new PairTPHsmallerTPH(ptph2.left, ptph.right)); addToPairs(input, new PairTPHsmallerTPH(ptph2.left, ptph.right));
} }
} }
} }
@ -351,9 +362,9 @@ public class ASTToTargetAST {
if (pair2.getRight().equals(pair.getLeft())) { if (pair2.getRight().equals(pair.getLeft())) {
input.remove(pair2); input.remove(pair2);
if (pair instanceof PairTPHsmallerTPH) if (pair instanceof PairTPHsmallerTPH)
input.add(new PairTPHsmallerTPH((TypePlaceholder) pair2.getLeft(), (TypePlaceholder) pair.getRight())); addToPairs(input, new PairTPHsmallerTPH((TypePlaceholder) pair2.getLeft(), (TypePlaceholder) pair.getRight()));
else else
input.add(new PairTPHequalRefTypeOrWildcardType((TypePlaceholder) pair2.getLeft(), pair.getRight())); addToPairs(input, new PairTPHequalRefTypeOrWildcardType((TypePlaceholder) pair2.getLeft(), pair.getRight()));
} }
} }
} }
@ -365,7 +376,7 @@ public class ASTToTargetAST {
var cycles = findCycles(input); var cycles = findCycles(input);
for (var cycle : cycles) { for (var cycle : cycles) {
var newTph = TypePlaceholder.fresh(new NullToken()); var newTph = TypePlaceholder.fresh(new NullToken());
input.add(new PairTPHequalRefTypeOrWildcardType(newTph, OBJECT)); addToPairs(input, new PairTPHequalRefTypeOrWildcardType(newTph, OBJECT));
cycle.add(cycle.get(0)); // Make it a complete cycle cycle.add(cycle.get(0)); // Make it a complete cycle
for (var i = 0; i < cycle.size() - 1; i++) { for (var i = 0; i < cycle.size() - 1; i++) {
var left = cycle.get(i); var left = cycle.get(i);
@ -390,7 +401,7 @@ public class ASTToTargetAST {
if (infima.size() > 1) { if (infima.size() > 1) {
foundInfima = true; foundInfima = true;
var newTph = TypePlaceholder.fresh(new NullToken()); var newTph = TypePlaceholder.fresh(new NullToken());
input.add(new PairTPHsmallerTPH(left, newTph)); addToPairs(input, new PairTPHsmallerTPH(left, newTph));
input.removeAll(infima); input.removeAll(infima);
for (var infimum : infima) { for (var infimum : infima) {
equality.put(infimum.right, newTph); equality.put(infimum.right, newTph);
@ -398,14 +409,14 @@ public class ASTToTargetAST {
if (pair.getLeft().equals(infimum.right)) { if (pair.getLeft().equals(infimum.right)) {
input.remove(pair); input.remove(pair);
if (pair instanceof PairTPHsmallerTPH stph) { if (pair instanceof PairTPHsmallerTPH stph) {
input.add(new PairTPHsmallerTPH(newTph, stph.right)); addToPairs(input, new PairTPHsmallerTPH(newTph, stph.right));
} else if (pair instanceof PairTPHequalRefTypeOrWildcardType rtph) { } else if (pair instanceof PairTPHequalRefTypeOrWildcardType rtph) {
input.add(new PairTPHequalRefTypeOrWildcardType(newTph, rtph.getRight())); addToPairs(input, new PairTPHequalRefTypeOrWildcardType(newTph, rtph.getRight()));
} }
} else if (pair.getRight().equals(infimum.right)) { } else if (pair.getRight().equals(infimum.right)) {
input.remove(pair); input.remove(pair);
if (pair instanceof PairTPHsmallerTPH stph) { if (pair instanceof PairTPHsmallerTPH stph) {
input.add(new PairTPHsmallerTPH(stph.left, newTph)); addToPairs(input, new PairTPHsmallerTPH(stph.left, newTph));
} }
} }
}); });
@ -413,15 +424,6 @@ public class ASTToTargetAST {
} }
} }
} while (foundInfima); } while (foundInfima);
// Remove duplicate bounds
for (var pair : new HashSet<>(input)) {
if (pair instanceof PairTPHequalRefTypeOrWildcardType) {
if (input.stream().anyMatch(p -> p instanceof PairTPHsmallerTPH && p.getLeft().equals(pair.getLeft()))) {
input.remove(pair);
}
}
}
} }
TargetType get(TypePlaceholder tph) { TargetType get(TypePlaceholder tph) {

View File

@ -137,6 +137,7 @@ public class TestComplete {
public void infTest() throws Exception { public void infTest() throws Exception {
var classFiles = generateClassFiles("Inf.jav", new ByteArrayClassLoader()); var classFiles = generateClassFiles("Inf.jav", new ByteArrayClassLoader());
var instance = classFiles.get("Inf").getDeclaredConstructor().newInstance(); var instance = classFiles.get("Inf").getDeclaredConstructor().newInstance();
// TODO check generics
} }
@Test @Test