diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/FunExprOccurrence.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/FunExprOccurrence.java index 9f5dcfef69d6..acf7326f5127 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/java/FunExprOccurrence.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/java/FunExprOccurrence.java @@ -24,6 +24,7 @@ import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.JBIterable; import com.intellij.util.io.DataInputOutputUtil; import com.intellij.util.io.IOUtil; import org.jetbrains.annotations.NotNull; @@ -31,6 +32,7 @@ import org.jetbrains.annotations.NotNull; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.Set; @@ -122,28 +124,38 @@ public class FunExprOccurrence { return member instanceof PsiMethod && hasCompatibleParameter((PsiMethod)member, argIndex, samClasses); } if (member instanceof PsiClass) { - return ContainerUtil.exists(samClasses, c -> InheritanceUtil.isInheritorOrSelf((PsiClass)member, c, true)); + return samClasses.contains(member); } return member instanceof PsiField && - ContainerUtil.exists(samClasses, c -> canPassFunctionalExpression(c, ((PsiField)member).getType())); + ContainerUtil.exists(samClasses, c -> canPassFunctionalExpression(c, ((PsiField)member).getType(), member)); } public static boolean hasCompatibleParameter(PsiMethod method, int argIndex, List samClasses) { PsiParameter[] parameters = method.getParameterList().getParameters(); int paramIndex = method.isVarArgs() ? Math.min(argIndex, parameters.length - 1) : argIndex; return paramIndex < parameters.length && - ContainerUtil.exists(samClasses, c -> canPassFunctionalExpression(c, parameters[paramIndex].getType())); + ContainerUtil.exists(samClasses, c -> canPassFunctionalExpression(c, parameters[paramIndex].getType(), method)); } - private static boolean canPassFunctionalExpression(PsiClass sam, PsiType paramType) { + private static boolean canPassFunctionalExpression(PsiClass sam, PsiType paramType, PsiElement place) { if (paramType instanceof PsiEllipsisType) { paramType = ((PsiEllipsisType)paramType).getComponentType(); } - PsiClass functionalCandidate = PsiUtil.resolveClassInClassTypeOnly(paramType); - if (functionalCandidate instanceof PsiTypeParameter) { - return InheritanceUtil.isInheritorOrSelf(sam, PsiUtil.resolveClassInClassTypeOnly(TypeConversionUtil.erasure(paramType)), true); - } + String paramClassName = paramType instanceof PsiClassType ? ((PsiClassType)paramType).getClassName() : null; + if (paramClassName == null) return false; - return InheritanceUtil.isInheritorOrSelf(functionalCandidate, sam, true); + if (paramClassName.equals(sam.getName())) return true; + + JBIterable typeParameters = JBIterable.generate(place, PsiElement::getContext) + .takeWhile(c -> !(c instanceof PsiFile)) + .filter(PsiTypeParameterListOwner.class) + .flatMap(o -> Arrays.asList(o.getTypeParameters())) + .map(PsiNamedElement::getName); + if (typeParameters.contains(paramClassName)) { + PsiClass functionalCandidate = ((PsiClassType)paramType).resolve(); + return functionalCandidate instanceof PsiTypeParameter && + InheritanceUtil.isInheritorOrSelf(sam, PsiUtil.resolveClassInClassTypeOnly(TypeConversionUtil.erasure(paramType)), true); + } + return false; } }