boolean (@NotNull LookupElement item, @NotNull PsiTypeLookupItem castTypeItem, @Nullable PsiType plainQualifier, @NotNull JavaCompletionProcessor processor, @NotNull Set<? extends PsiType> expectedTypes) { PsiType castType = castTypeItem.getType(); if (plainQualifier != null) { Object o = item.getObject(); if (o instanceof PsiMethod) { if (plainQualifier instanceof PsiClassType && castType instanceof PsiClassType) { PsiMethod method = (PsiMethod)o; PsiClassType.ClassResolveResult plainResult = ((PsiClassType)plainQualifier).resolveGenerics(); PsiClass plainClass = plainResult.getElement(); HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature(); PsiMethod plainMethod = plainClass == null ? null : StreamEx.ofTree(signature, s -> StreamEx.of(s.getSuperSignatures())) .map(sig -> MethodSignatureUtil.findMethodBySignature(plainClass, sig, true)) .filter(Objects::nonNull) .findFirst().orElse(null); if (plainMethod != null) { PsiClassType.ClassResolveResult castResult = ((PsiClassType)castType).resolveGenerics(); PsiClass castClass = castResult.getElement(); if (castClass == null || !castClass.isInheritor(plainClass, true)) { return false; } if (!processor.isAccessible(plainMethod)) { return true; } PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType)castType); PsiType typeAfterCast = toRaw(castSub.substitute(method.getReturnType())); PsiType typeDeclared = toRaw(plainResult.getSubstitutor().substitute(plainMethod.getReturnType())); return typeAfterCast != null && typeDeclared != null && !typeAfterCast.equals(typeDeclared) && ContainerUtil.exists(expectedTypes, et -> et.isAssignableFrom(typeAfterCast) && !et.isAssignableFrom(typeDeclared)); } } } return containsMember(castType, o, true) && !containsMember(plainQualifier, o, true); } return false; }