mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new inference: 2 phase resolution
This commit is contained in:
+2
-2
@@ -400,8 +400,8 @@ public class InferenceIncorporationPhase {
|
||||
}
|
||||
}
|
||||
|
||||
public PsiSubstitutor checkIncorporated(PsiSubstitutor substitutor) {
|
||||
for (InferenceVariable variable : mySession.getInferenceVariables()) { //todo equals bounds?
|
||||
public PsiSubstitutor checkIncorporated(PsiSubstitutor substitutor, Collection<InferenceVariable> variables) {
|
||||
for (InferenceVariable variable : variables) { //todo equals bounds?
|
||||
for (PsiType lowerBound : variable.getBounds(InferenceBound.LOWER)) {
|
||||
lowerBound = substitutor.substitute(lowerBound);
|
||||
if (mySession.isProperType(lowerBound)) {
|
||||
|
||||
+51
-18
@@ -677,28 +677,57 @@ public class InferenceSession {
|
||||
|
||||
private PsiSubstitutor resolveBounds(final Collection<InferenceVariable> inferenceVariables,
|
||||
PsiSubstitutor substitutor) {
|
||||
final List<List<InferenceVariable>> independentVars = InferenceVariablesOrder.resolveOrder(inferenceVariables, this);
|
||||
for (List<InferenceVariable> vars : independentVars) {
|
||||
substitutor = resolveSubset(vars, substitutor, true);
|
||||
if (substitutor == null) {
|
||||
final Collection<InferenceVariable> allVars = new ArrayList<InferenceVariable>(inferenceVariables);
|
||||
while (!allVars.isEmpty()) {
|
||||
final List<InferenceVariable> vars = InferenceVariablesOrder.resolveOrder(allVars, this);
|
||||
if (!myIncorporationPhase.hasCaptureConstraints(vars)) {
|
||||
final PsiSubstitutor firstSubstitutor = resolveSubset(vars, substitutor, true);
|
||||
if (firstSubstitutor != null) {
|
||||
substitutor = firstSubstitutor;
|
||||
allVars.removeAll(vars);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (InferenceVariable var : vars) {
|
||||
final PsiTypeParameter copy = (PsiTypeParameter)var.getParameter().copy();
|
||||
final PsiType lub = getLowerBound(var, substitutor);
|
||||
final PsiType glb = getUpperBound(var, substitutor);
|
||||
final InferenceVariable zVariable = new InferenceVariable(copy);
|
||||
zVariable.addBound(glb, InferenceBound.UPPER);
|
||||
if (lub != PsiType.NULL) {
|
||||
if (!TypeConversionUtil.isAssignable(glb, lub)) {
|
||||
return null;
|
||||
}
|
||||
copy.putUserData(LOWER_BOUND, lub);
|
||||
zVariable.addBound(lub, InferenceBound.LOWER);
|
||||
}
|
||||
myInferenceVariables.put(copy, zVariable);
|
||||
}
|
||||
myIncorporationPhase.forgetCaptures(vars);
|
||||
if (!myIncorporationPhase.incorporate()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return substitutor;
|
||||
}
|
||||
|
||||
|
||||
private PsiType getLowerBound(InferenceVariable var, PsiSubstitutor substitutor) {
|
||||
return composeBound(var, InferenceBound.LOWER, new Function<Pair<PsiType, PsiType>, PsiType>() {
|
||||
@Override
|
||||
public PsiType fun(Pair<PsiType, PsiType> pair) {
|
||||
return GenericsUtil.getLeastUpperBound(pair.first, pair.second, myManager);
|
||||
}
|
||||
}, substitutor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiSubstitutor resolveSubset(Collection<InferenceVariable> vars, PsiSubstitutor substitutor, boolean checkResult) {
|
||||
for (InferenceVariable var : vars) {
|
||||
LOG.assertTrue(var.getInstantiation() == PsiType.NULL);
|
||||
final PsiTypeParameter typeParameter = var.getParameter();
|
||||
final PsiType eqBound = getEqualsBound(var, substitutor);
|
||||
final PsiType lub = eqBound != PsiType.NULL && (myErased || eqBound != null) ? eqBound : composeBound(var, InferenceBound.LOWER, new Function<Pair<PsiType, PsiType>, PsiType>() {
|
||||
@Override
|
||||
public PsiType fun(Pair<PsiType, PsiType> pair) {
|
||||
return GenericsUtil.getLeastUpperBound(pair.first, pair.second, myManager);
|
||||
}
|
||||
}, substitutor);
|
||||
final PsiType lub = eqBound != PsiType.NULL && (myErased || eqBound != null) ? eqBound : getLowerBound(var, substitutor);
|
||||
if (lub != PsiType.NULL) {
|
||||
substitutor = substitutor.put(typeParameter, lub);
|
||||
}
|
||||
@@ -707,16 +736,20 @@ public class InferenceSession {
|
||||
substitutor = substitutor.put(typeParameter, runtimeException);
|
||||
}
|
||||
else {
|
||||
substitutor = substitutor.put(typeParameter, composeBound(var, InferenceBound.UPPER, new Function<Pair<PsiType, PsiType>, PsiType>() {
|
||||
@Override
|
||||
public PsiType fun(Pair<PsiType, PsiType> pair) {
|
||||
return GenericsUtil.getGreatestLowerBound(pair.first, pair.second);
|
||||
}
|
||||
}, substitutor));
|
||||
substitutor = substitutor.put(typeParameter, getUpperBound(var, substitutor));
|
||||
}
|
||||
}
|
||||
|
||||
return checkResult ? myIncorporationPhase.checkIncorporated(substitutor) : substitutor;
|
||||
return checkResult ? myIncorporationPhase.checkIncorporated(substitutor, vars) : substitutor;
|
||||
}
|
||||
|
||||
private PsiType getUpperBound(InferenceVariable var, PsiSubstitutor substitutor) {
|
||||
return composeBound(var, InferenceBound.UPPER, new Function<Pair<PsiType, PsiType>, PsiType>() {
|
||||
@Override
|
||||
public PsiType fun(Pair<PsiType, PsiType> pair) {
|
||||
return GenericsUtil.getGreatestLowerBound(pair.first, pair.second);
|
||||
}
|
||||
}, substitutor);
|
||||
}
|
||||
|
||||
public PsiType getEqualsBound(InferenceVariable var, PsiSubstitutor substitutor) {
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ import java.util.*;
|
||||
|
||||
public class InferenceVariablesOrder {
|
||||
|
||||
public static List<List<InferenceVariable>> resolveOrder(Collection<InferenceVariable> vars, InferenceSession session) {
|
||||
public static List<InferenceVariable> resolveOrder(Collection<InferenceVariable> vars, InferenceSession session) {
|
||||
Map<InferenceVariable, InferenceGraphNode<InferenceVariable>> nodes =
|
||||
new LinkedHashMap<InferenceVariable, InferenceGraphNode<InferenceVariable>>();
|
||||
for (InferenceVariable var : vars) {
|
||||
@@ -52,7 +52,7 @@ public class InferenceVariablesOrder {
|
||||
public List<InferenceVariable> fun(InferenceGraphNode<InferenceVariable> node) {
|
||||
return node.getValue();
|
||||
}
|
||||
});
|
||||
}).iterator().next();
|
||||
}
|
||||
|
||||
public static <T> List<List<InferenceGraphNode<T>>> tarjan(Collection<InferenceGraphNode<T>> nodes) {
|
||||
|
||||
+5
-1
@@ -83,7 +83,11 @@ public class StrictSubtypingConstraint implements ConstraintFormula {
|
||||
if (myT.equals(conjunct)) return true;
|
||||
}
|
||||
}
|
||||
//todo ((PsiTypeParameter)C).getLowerBound()
|
||||
final PsiType lowerBound = CClass.getUserData(InferenceSession.LOWER_BOUND);
|
||||
if (lowerBound != null) {
|
||||
constraints.add(new StrictSubtypingConstraint(lowerBound, myS));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user