mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new inference: different parameterizations condition/wildcards parameterization in return type covered
This commit is contained in:
+20
-3
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.resolve.graphInference;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.constraints.ConstraintFormula;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.constraints.StrictSubtypingConstraint;
|
||||
@@ -22,6 +23,7 @@ import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeEqual
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.Processor;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
@@ -168,7 +170,21 @@ public class InferenceIncorporationPhase {
|
||||
* there exists a supertype (4.10) of S of the form G<S1, ..., Sn> and a supertype of T of the form G<T1, ..., Tn>,
|
||||
* then for all i, 1 ≤ i ≤ n, if Si and Ti are types (not wildcards), the constraint ⟨Si = Ti⟩ is implied.
|
||||
*/
|
||||
private void upUp(List<PsiType> upperBounds) {
|
||||
private boolean upUp(List<PsiType> upperBounds) {
|
||||
return findParameterizationOfTheSameGenericClass(upperBounds, new Processor<Pair<PsiType, PsiType>>() {
|
||||
@Override
|
||||
public boolean process(Pair<PsiType, PsiType> pair) {
|
||||
final PsiType sType = pair.first;
|
||||
final PsiType tType = pair.second;
|
||||
if (!(sType instanceof PsiWildcardType) && !(tType instanceof PsiWildcardType) && sType != null && tType != null) {
|
||||
addConstraint(new TypeEqualityConstraint(sType, tType));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean findParameterizationOfTheSameGenericClass(List<PsiType> upperBounds, Processor<Pair<PsiType, PsiType>> processor) {
|
||||
for (int i = 0; i < upperBounds.size(); i++) {
|
||||
final PsiType sBound = upperBounds.get(i);
|
||||
final PsiClass sClass = PsiUtil.resolveClassInClassTypeOnly(sBound);
|
||||
@@ -188,14 +204,15 @@ public class InferenceIncorporationPhase {
|
||||
for (PsiTypeParameter typeParameter : gClass.getTypeParameters()) {
|
||||
final PsiType sType = sSubstitutor.substitute(typeParameter);
|
||||
final PsiType tType = tSubstitutor.substitute(typeParameter);
|
||||
if (!(sType instanceof PsiWildcardType) && !(tType instanceof PsiWildcardType) && sType != null && tType != null) {
|
||||
addConstraint(new TypeEqualityConstraint(sType, tType));
|
||||
if (!processor.process(Pair.create(sType, tType))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addConstraint(ConstraintFormula constraint) {
|
||||
|
||||
+33
-2
@@ -35,6 +35,7 @@ import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -345,10 +346,16 @@ public class InferenceSession {
|
||||
private InferenceVariable shouldResolveAndInstantiate(PsiType returnType, PsiType targetType) {
|
||||
final InferenceVariable inferenceVariable = getInferenceVariable(returnType);
|
||||
if (inferenceVariable != null) {
|
||||
if (targetType instanceof PsiPrimitiveType && hasPrimitiveWrapperBound(inferenceVariable) ||
|
||||
targetType instanceof PsiClassType && (hasUncheckedBounds(inferenceVariable, (PsiClassType)targetType) || myErased)) {
|
||||
if (targetType instanceof PsiPrimitiveType && hasPrimitiveWrapperBound(inferenceVariable)) {
|
||||
return inferenceVariable;
|
||||
}
|
||||
if (targetType instanceof PsiClassType) {
|
||||
if (myErased ||
|
||||
hasUncheckedBounds(inferenceVariable, (PsiClassType)targetType) ||
|
||||
hasWildcardParameterization(inferenceVariable, (PsiClassType)targetType)) {
|
||||
return inferenceVariable;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -381,6 +388,30 @@ public class InferenceSession {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasWildcardParameterization(InferenceVariable inferenceVariable, PsiClassType targetType) {
|
||||
if (FunctionalInterfaceParameterizationUtil.isWildcardParameterized(targetType)) {
|
||||
final List<PsiType> bounds = inferenceVariable.getBounds(InferenceBound.LOWER);
|
||||
final Processor<Pair<PsiType, PsiType>> differentParameterizationProcessor = new Processor<Pair<PsiType, PsiType>>() {
|
||||
@Override
|
||||
public boolean process(Pair<PsiType, PsiType> pair) {
|
||||
return pair.first == null || pair.second == null || pair.first.equals(pair.second);
|
||||
}
|
||||
};
|
||||
if (InferenceIncorporationPhase.findParameterizationOfTheSameGenericClass(bounds, differentParameterizationProcessor)) return true;
|
||||
final List<PsiType> eqBounds = inferenceVariable.getBounds(InferenceBound.EQ);
|
||||
for (PsiType lowBound : bounds) {
|
||||
if (FunctionalInterfaceParameterizationUtil.isWildcardParameterized(lowBound)) {
|
||||
for (PsiType bound : eqBounds) {
|
||||
if (lowBound.equals(bound)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private PsiType getTargetType(final PsiExpression context, PsiType returnType) {
|
||||
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(context.getParent());
|
||||
if (parent instanceof PsiExpressionList) {
|
||||
|
||||
Reference in New Issue
Block a user