forked from JavaTX/JavaCompilerCore
- Calculate veriance for new type variables in Infima & Cycles
- Remove referenced check from Infima - Correctly identify contra & covariance for chains for tphs
This commit is contained in:
parent
ed671aeb97
commit
4078239815
@ -18,6 +18,7 @@ import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.result.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -170,7 +171,6 @@ public class ASTToTargetAST {
|
||||
for (var pair : simplifiedConstraints) {
|
||||
if (pair.left.equals(typeVariable) && typeVariables.contains(pair.right)) {
|
||||
addToPairs(result, new PairTPHsmallerTPH(pair.left, equality.getOrDefault(pair.right, pair.right)));
|
||||
typeVariables.add(pair.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -196,7 +196,7 @@ public class ASTToTargetAST {
|
||||
RefTypeOrTPHOrWildcardOrGeneric T2 = superType;
|
||||
if (T2 instanceof TypePlaceholder tph) T2 = equality.getOrDefault(tph, tph);
|
||||
|
||||
System.out.println("T1s: " + T1s + "\nT2: " + T2);
|
||||
System.out.println("T1s: " + T1s + " T2: " + T2);
|
||||
//Ende
|
||||
|
||||
superType = methodCall.receiverType;
|
||||
@ -211,7 +211,7 @@ public class ASTToTargetAST {
|
||||
var optMethod = findMethod(owner, methodCall.name, methodCall.getArgumentList());
|
||||
if (optMethod.isEmpty()) return;
|
||||
var method = optMethod.get();
|
||||
var generics = generics(owner, method).javaGenerics();
|
||||
var generics = generics(owner, method).txGenerics();
|
||||
|
||||
// transitive and
|
||||
var all = transitiveClosure(generics);
|
||||
@ -226,24 +226,24 @@ public class ASTToTargetAST {
|
||||
|
||||
// Loop from hell
|
||||
outer:
|
||||
for (var tph : typeVariables) {
|
||||
if (typeVariablesOfClass.contains(tph)) continue;
|
||||
for (var R1 : typeVariables) {
|
||||
if (typeVariablesOfClass.contains(R1)) continue;
|
||||
for (var generic : all) {
|
||||
if (!(generic.getRight() instanceof TypePlaceholder type))
|
||||
continue;
|
||||
|
||||
for (var pair : simplifiedConstraints) {
|
||||
if (!(pair.left.equals(tph) && pair.right.equals(generic.getLeft())))
|
||||
if (!(pair.left.equals(R1) && pair.right.equals(generic.getLeft())))
|
||||
continue;
|
||||
|
||||
for (var tph2 : typeVariables) {
|
||||
for (var R2 : typeVariables) {
|
||||
for (var pair2 : simplifiedConstraints) {
|
||||
if (!(pair2.right.equals(tph2) && pair2.left.equals(type)))
|
||||
if (!(pair2.right.equals(R2) && pair2.left.equals(type)))
|
||||
continue;
|
||||
if (tph.equals(tph2)) continue;
|
||||
if (!T1s.contains(tph) || !tph2.equals(T2)) continue;
|
||||
if (R1.equals(R2)) continue;
|
||||
if (!T1s.contains(R1) || !R2.equals(T2)) continue;
|
||||
|
||||
var newPair = new PairTPHsmallerTPH(tph, tph2);
|
||||
var newPair = new PairTPHsmallerTPH(R1, R2);
|
||||
newPairs.add(newPair);
|
||||
|
||||
if (!containsRelation(result, newPair))
|
||||
@ -268,7 +268,7 @@ public class ASTToTargetAST {
|
||||
|
||||
@Override
|
||||
public void visit(Assign assign) {
|
||||
superType = assign.lefSide.getType();
|
||||
superType = assign.rightSide.getType();
|
||||
assign.rightSide.accept(this);
|
||||
}
|
||||
|
||||
@ -521,9 +521,6 @@ public class ASTToTargetAST {
|
||||
super.visit(methodCall);
|
||||
typeVariables.addAll(findTypeVariables(methodCall.getType(), equality));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Assign assign) {}
|
||||
});
|
||||
}
|
||||
|
||||
@ -557,7 +554,7 @@ public class ASTToTargetAST {
|
||||
var referenced = new HashSet<TypePlaceholder>();
|
||||
|
||||
eliminateCycles(javaResult, equality, referenced);
|
||||
eliminateInfima(javaResult, equality, referenced);
|
||||
eliminateInfima(javaResult, equality);
|
||||
|
||||
var usedTphs = new HashSet<TypePlaceholder>();
|
||||
// For eliminating inner type variables we need to figure out which ones are actually used
|
||||
@ -575,7 +572,7 @@ public class ASTToTargetAST {
|
||||
{
|
||||
var referenced = new HashSet<TypePlaceholder>();
|
||||
// JavaTX Generics
|
||||
eliminateInfima(txResult, txEquality, referenced);
|
||||
eliminateInfima(txResult, txEquality);
|
||||
|
||||
for (var param : method.getParameterList().getFormalparalist()) {
|
||||
referenced.addAll(findTypeVariables(param.getType(), txEquality));
|
||||
@ -636,9 +633,9 @@ public class ASTToTargetAST {
|
||||
|
||||
var referenced = new HashSet<TypePlaceholder>();
|
||||
eliminateCycles(javaResult, equality, referenced);
|
||||
eliminateInfima(javaResult, equality, referenced);
|
||||
eliminateInfima(javaResult, equality);
|
||||
var txReferenced = new HashSet<TypePlaceholder>();
|
||||
eliminateInfima(txResult, txEquality, txReferenced);
|
||||
eliminateInfima(txResult, txEquality);
|
||||
|
||||
eliminateInnerTypeVariablesOfClass(classOrInterface, javaResult, equality, referenced);
|
||||
equalizeTypeVariables(javaResult, equality);
|
||||
@ -649,19 +646,52 @@ public class ASTToTargetAST {
|
||||
}
|
||||
|
||||
void equalizeTypeVariables(Set<ResultPair<?, ?>> input, Map<TypePlaceholder, TypePlaceholder> equality) {
|
||||
System.out.println(input);
|
||||
for (var pair : new HashSet<>(input)) {
|
||||
if (pair instanceof PairTPHsmallerTPH ptph) {
|
||||
System.out.println(pair + " " + ptph.left.getVariance() + " " + ptph.right.getVariance());
|
||||
if (ptph.left.getVariance() == 1 && ptph.right.getVariance() == -1) {
|
||||
addToEquality(equality, ptph.left, ptph.right);
|
||||
input.remove(ptph);
|
||||
for (var pair2 : new HashSet<>(simplifiedConstraints)) {
|
||||
if (pair2.right.equals(ptph.left)) {
|
||||
simplifiedConstraints.remove(pair2);
|
||||
simplifiedConstraints.add(new PairTPHsmallerTPH(pair2.left, ptph.right));
|
||||
var chain = new ArrayList<TypePlaceholder>();
|
||||
chain.add(ptph.left);
|
||||
chain.add(ptph.right);
|
||||
|
||||
outer: while (true) {
|
||||
var added = false;
|
||||
for (var pair2 : input) {
|
||||
if (pair2 instanceof PairTPHsmallerTPH ptph2 && ptph2.left.equals(chain.get(chain.size() - 1))) {
|
||||
if (chain.contains(ptph2.right)) break outer;
|
||||
chain.add(ptph2.right);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
if (!added) break;
|
||||
}
|
||||
|
||||
var variance = chain.get(0).getVariance();
|
||||
if (variance != 1) continue;
|
||||
var index = 0;
|
||||
for (var tph : chain) {
|
||||
if (variance == 1 && tph.getVariance() == -1) {
|
||||
variance = -1;
|
||||
}
|
||||
if (variance == -1 && tph.getVariance() == 1) {
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
if (variance == 1) continue;
|
||||
|
||||
var start = chain.get(0);
|
||||
var prev = start;
|
||||
for (var i = 1; i < index; i++) {
|
||||
var cur = chain.get(i);
|
||||
addToEquality(equality, cur, start);
|
||||
input.remove(new PairTPHsmallerTPH(prev, chain.get(i)));
|
||||
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)) {
|
||||
input.remove(pair2);
|
||||
input.add(new PairTPHequalRefTypeOrWildcardType(start, pair2.getRight()));
|
||||
}
|
||||
}
|
||||
prev = chain.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -739,6 +769,15 @@ public class ASTToTargetAST {
|
||||
var cycles = findCycles(input);
|
||||
for (var cycle : cycles) {
|
||||
var newTph = TypePlaceholder.fresh(new NullToken());
|
||||
var variance = cycle.get(0).getVariance();
|
||||
for (var tph : cycle) {
|
||||
if (tph.getVariance() != variance) {
|
||||
variance = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
newTph.setVariance(variance);
|
||||
|
||||
referenced.add(newTph);
|
||||
addToPairs(input, new PairTPHequalRefTypeOrWildcardType(newTph, OBJECT));
|
||||
cycle.add(cycle.get(0)); // Make it a complete cycle
|
||||
@ -752,7 +791,7 @@ public class ASTToTargetAST {
|
||||
}
|
||||
}
|
||||
|
||||
void eliminateInfima(Set<ResultPair<?, ?>> input, Map<TypePlaceholder, TypePlaceholder> equality, Set<TypePlaceholder> referenced) {
|
||||
void eliminateInfima(Set<ResultPair<?, ?>> input, Map<TypePlaceholder, TypePlaceholder> equality) {
|
||||
var foundInfima = false;
|
||||
do {
|
||||
foundInfima = false;
|
||||
@ -767,7 +806,16 @@ public class ASTToTargetAST {
|
||||
if (infima.size() > 1) {
|
||||
foundInfima = true;
|
||||
var newTph = TypePlaceholder.fresh(new NullToken());
|
||||
referenced.add(newTph);
|
||||
var variance = infima.stream().findFirst().get().right.getVariance();
|
||||
for (var pair : infima) {
|
||||
if (pair.right.getVariance() != variance) {
|
||||
variance = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
newTph.setVariance(variance);
|
||||
|
||||
//referenced.add(newTph);
|
||||
addToPairs(input, new PairTPHsmallerTPH(left, newTph));
|
||||
input.removeAll(infima);
|
||||
for (var infimum : infima) {
|
||||
|
Loading…
Reference in New Issue
Block a user