QualifierResolveResult (@NotNull PsiMethodReferenceExpression methodReferenceExpression) { PsiClass containingClass = null; PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; final PsiExpression expression = methodReferenceExpression.getQualifierExpression(); if (expression != null) { PsiType expressionType = expression.getType(); if (expressionType instanceof PsiIntersectionType) { List<PsiClassType> types = ContainerUtil.filterIsInstance(((PsiIntersectionType)expressionType).getConjuncts(), PsiClassType.class); substitutor = types.stream().map(t -> t.resolveGenerics().getSubstitutor()) .reduce(PsiSubstitutor.EMPTY, PsiSubstitutor::putAll); containingClass = JavaPsiFacade.getElementFactory(methodReferenceExpression.getProject()).createTypeParameter( "$SYNTHETIC$", types.toArray(PsiClassType.EMPTY_ARRAY)); } else { if (expressionType instanceof PsiCapturedWildcardType) { expressionType = ((PsiCapturedWildcardType)expressionType).getUpperBound(); } else { expressionType = replaceArrayType(expressionType, expression); } PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(expressionType); containingClass = result.getElement(); if (containingClass != null) { substitutor = result.getSubstitutor(); } } if (containingClass == null && expression instanceof PsiReferenceExpression) { final JavaResolveResult resolveResult = ((PsiReferenceExpression)expression).advancedResolve(false); final PsiElement resolve = resolveResult.getElement(); if (resolve instanceof PsiClass) { containingClass = (PsiClass)resolve; substitutor = resolveResult.getSubstitutor(); return new QualifierResolveResult(containingClass, substitutor, true); } } } else { final PsiTypeElement typeElement = methodReferenceExpression.getQualifierType(); if (typeElement != null) { PsiType type = replaceArrayType(typeElement.getType(), typeElement); PsiClassType.ClassResolveResult result = PsiUtil.resolveGenericsClassInType(type); containingClass = result.getElement(); if (containingClass != null) { return new QualifierResolveResult(containingClass, result.getSubstitutor(), true); } } } return new QualifierResolveResult(containingClass, substitutor, false); }