mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-21 05:51:25 +07:00
method refs: missed super class substitution (IDEA-126969)
This commit is contained in:
@@ -44,7 +44,15 @@ public class PsiMethodReferenceUtil {
|
||||
public static String checkReturnType(PsiMethodReferenceExpression expression, JavaResolveResult result, PsiType functionalInterfaceType) {
|
||||
final PsiElement resolve = result.getElement();
|
||||
if (resolve instanceof PsiMethod) {
|
||||
final PsiClass containingClass = ((PsiMethod)resolve).getContainingClass();
|
||||
LOG.assertTrue(containingClass != null);
|
||||
PsiSubstitutor subst = result.getSubstitutor();
|
||||
PsiClass qContainingClass = getQualifierResolveResult(expression).getContainingClass();
|
||||
if (qContainingClass != null && InheritanceUtil.isInheritorOrSelf(qContainingClass, containingClass, true)) {
|
||||
subst = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, subst);
|
||||
LOG.assertTrue(subst != null);
|
||||
}
|
||||
|
||||
|
||||
final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType);
|
||||
|
||||
@@ -57,7 +65,7 @@ public class PsiMethodReferenceUtil {
|
||||
PsiType methodReturnType = subst.substitute(returnType);
|
||||
if (interfaceReturnType != null && interfaceReturnType != PsiType.VOID) {
|
||||
if (methodReturnType == null) {
|
||||
methodReturnType = JavaPsiFacade.getElementFactory(expression.getProject()).createType(((PsiMethod)resolve).getContainingClass(), subst);
|
||||
methodReturnType = JavaPsiFacade.getElementFactory(expression.getProject()).createType(containingClass, subst);
|
||||
}
|
||||
if (!TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType, false)) {
|
||||
return "Bad return type in method reference: cannot convert " + methodReturnType.getCanonicalText() + " to " + interfaceReturnType.getCanonicalText();
|
||||
|
||||
@@ -21,6 +21,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.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
@@ -60,6 +61,10 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
final PsiType interfaceMethodReturnType = interfaceMethod.getReturnType();
|
||||
final PsiType returnType = substitutor.substitute(interfaceMethodReturnType);
|
||||
final PsiType[] typeParameters = myExpression.getTypeParameters();
|
||||
|
||||
final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(myExpression);
|
||||
PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
|
||||
|
||||
if (!myExpression.isExact()) {
|
||||
for (PsiParameter parameter : targetParameters) {
|
||||
if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
|
||||
@@ -70,11 +75,9 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
final PsiMember applicableMember = myExpression.getPotentiallyApplicableMember();
|
||||
LOG.assertTrue(applicableMember != null);
|
||||
|
||||
final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(myExpression);
|
||||
final PsiClass applicableMemberContainingClass = applicableMember.getContainingClass();
|
||||
final PsiClass containingClass = qualifierResolveResult.getContainingClass();
|
||||
|
||||
PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
|
||||
psiSubstitutor = applicableMemberContainingClass == null || containingClass == null || myExpression.isConstructor()
|
||||
? psiSubstitutor
|
||||
: TypeConversionUtil.getSuperClassSubstitutor(applicableMemberContainingClass, containingClass, psiSubstitutor);
|
||||
@@ -143,6 +146,13 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
final PsiType referencedMethodReturnType;
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
LOG.assertTrue(containingClass != null, method);
|
||||
|
||||
PsiClass qContainingClass = qualifierResolveResult.getContainingClass();
|
||||
if (qContainingClass != null && InheritanceUtil.isInheritorOrSelf(qContainingClass, containingClass, true)) {
|
||||
psiSubstitutor = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, PsiSubstitutor.EMPTY);
|
||||
LOG.assertTrue(psiSubstitutor != null);
|
||||
}
|
||||
|
||||
if (method.isConstructor()) {
|
||||
referencedMethodReturnType = JavaPsiFacade.getElementFactory(method.getProject()).createType(containingClass, PsiSubstitutor.EMPTY);
|
||||
}
|
||||
@@ -179,7 +189,6 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
PsiSubstitutor psiSubstitutor = PsiSubstitutor.EMPTY;
|
||||
for (PsiTypeParameter param : method.getTypeParameters()) {
|
||||
if (idx < typeParameters.length) {
|
||||
psiSubstitutor = psiSubstitutor.put(param, typeParameters[idx++]);
|
||||
|
||||
@@ -434,7 +434,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
return true;
|
||||
}
|
||||
|
||||
final PsiSubstitutor subst = result.getSubstitutor();
|
||||
PsiSubstitutor subst = result.getSubstitutor();
|
||||
|
||||
PsiType methodReturnType = null;
|
||||
PsiClass containingClass = null;
|
||||
@@ -451,6 +451,12 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
return false;
|
||||
}
|
||||
|
||||
PsiClass qContainingClass = PsiMethodReferenceUtil.getQualifierResolveResult(this).getContainingClass();
|
||||
if (qContainingClass != null && containingClass != null && InheritanceUtil.isInheritorOrSelf(qContainingClass, containingClass, true)) {
|
||||
subst = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, subst);
|
||||
LOG.assertTrue(subst != null);
|
||||
}
|
||||
|
||||
methodReturnType = subst.substitute(returnType);
|
||||
}
|
||||
else if (resolve instanceof PsiClass) {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class IDEA126969 {
|
||||
void foo(final Stream<List<Integer>> stream) {
|
||||
|
||||
stream.flatMap(List::stream)
|
||||
.forEach(i -> System.out.println(i.floatValue()));
|
||||
|
||||
stream.flatMap(Collection::stream)
|
||||
.forEach(i -> System.out.println(i.floatValue()));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -273,6 +273,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA126969() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user