mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 21:11:28 +07:00
fix intersection types in receiver position (IDEA-144472)
This commit is contained in:
@@ -1290,10 +1290,9 @@ public class InferenceSession {
|
||||
// the type to search is the result of capture conversion (5.1.10) applied to T;
|
||||
// otherwise, the type to search is the same as the type of the first search. Again, the type arguments, if any, are given by the method reference.
|
||||
if (PsiUtil.isRawSubstitutor(containingClass, psiSubstitutor)) {
|
||||
final PsiClassType.ClassResolveResult pResult = PsiUtil.resolveGenericsClassInType(PsiImplUtil.normalizeWildcardTypeByPosition(pType, (PsiExpression)myContext));
|
||||
final PsiClass pClass = pResult.getElement();
|
||||
final PsiSubstitutor receiverSubstitutor = pClass != null ? TypeConversionUtil
|
||||
.getClassSubstitutor(containingClass, pClass, pResult.getSubstitutor()) : null;
|
||||
PsiType normalizedPType = PsiImplUtil.normalizeWildcardTypeByPosition(pType, (PsiExpression)myContext);
|
||||
final PsiSubstitutor receiverSubstitutor = PsiMethodReferenceCompatibilityConstraint
|
||||
.getParameterizedTypeSubstitutor(containingClass, normalizedPType);
|
||||
if (receiverSubstitutor != null) {
|
||||
if (!method.hasTypeParameters()) {
|
||||
if (signature.getParameterTypes().length == 1 || PsiUtil.isRawSubstitutor(containingClass, receiverSubstitutor)) {
|
||||
|
||||
@@ -22,10 +22,7 @@ import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfacePa
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.InferenceSession;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -219,13 +216,8 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
// otherwise, the type to search is the same as the type of the first search. Again, the type arguments, if any, are given by the method reference.
|
||||
if ( PsiUtil.isRawSubstitutor(qContainingClass, psiSubstitutor)) {
|
||||
if (member instanceof PsiMethod && PsiMethodReferenceUtil.isSecondSearchPossible(signature.getParameterTypes(), qualifierResolveResult, myExpression)) {
|
||||
final PsiType pType = signature.getParameterTypes()[0];
|
||||
PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(
|
||||
PsiImplUtil.normalizeWildcardTypeByPosition(pType, myExpression));
|
||||
PsiClass paramClass = resolveResult.getElement();
|
||||
LOG.assertTrue(paramClass != null);
|
||||
psiSubstitutor = TypeConversionUtil.getClassSubstitutor(qContainingClass, paramClass, resolveResult.getSubstitutor());
|
||||
LOG.assertTrue(psiSubstitutor != null);
|
||||
final PsiType pType = PsiImplUtil.normalizeWildcardTypeByPosition(signature.getParameterTypes()[0], myExpression);
|
||||
psiSubstitutor = getParameterizedTypeSubstitutor(qContainingClass, pType);
|
||||
}
|
||||
else if (member instanceof PsiMethod && ((PsiMethod)member).isConstructor() || member instanceof PsiClass) {
|
||||
//15.13.1
|
||||
@@ -253,6 +245,24 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
return psiSubstitutor;
|
||||
}
|
||||
|
||||
public static PsiSubstitutor getParameterizedTypeSubstitutor(PsiClass qContainingClass, PsiType pType) {
|
||||
if (pType instanceof PsiIntersectionType) {
|
||||
for (PsiType type : ((PsiIntersectionType)pType).getConjuncts()) {
|
||||
PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(type);
|
||||
if (InheritanceUtil.isInheritorOrSelf(resolveResult.getElement(), qContainingClass, true)) {
|
||||
return getParameterizedTypeSubstitutor(qContainingClass, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(pType);
|
||||
PsiClass paramClass = resolveResult.getElement();
|
||||
LOG.assertTrue(paramClass != null);
|
||||
PsiSubstitutor psiSubstitutor = TypeConversionUtil.getClassSubstitutor(qContainingClass, paramClass, resolveResult.getSubstitutor());
|
||||
LOG.assertTrue(psiSubstitutor != null);
|
||||
return psiSubstitutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(PsiSubstitutor substitutor, boolean cache) {
|
||||
myT = substitutor.substitute(myT);
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
abstract class Constraint<ConstraintType extends Constraint<ConstraintType>> {
|
||||
|
||||
protected abstract Stream<Event> evStream();
|
||||
|
||||
private void foo(final Set<CConstraint> ctrlSTCs,
|
||||
final Set<BConstraint> probCstrs) {
|
||||
ArrayList<Event> a = new ArrayList<Event>(Stream
|
||||
.concat(ctrlSTCs.stream(), probCstrs.stream())
|
||||
.flatMap(Constraint::evStream)
|
||||
.collect(Collectors.toSet()));
|
||||
}
|
||||
|
||||
private abstract class CConstraint extends Constraint<CConstraint> implements I {}
|
||||
private abstract class BConstraint extends Constraint<BConstraint> implements I {}
|
||||
|
||||
interface I {}
|
||||
interface Event {}
|
||||
|
||||
}
|
||||
@@ -106,6 +106,10 @@ public class MethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIntersectionTypesInReceiverPosition() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user