List<PsiExtensionMethod> (final @NotNull PsiClass targetClass, final @NotNull String nameHint, final @NotNull PsiElement place) { if (!(place instanceof PsiMethodCallExpression)) { return Collections.emptyList(); } PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)place).getMethodExpression(); PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); if (qualifierExpression == null || !nameHint.equals(methodExpression.getReferenceName()) || qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() instanceof PsiClass) { return Collections.emptyList(); } List<PsiExtensionMethod> result = new SmartList<>(); @Nullable PsiClass context = PsiTreeUtil.getContextOfType(place, PsiClass.class); while (context != null) { final @Nullable PsiAnnotation annotation = context.getAnnotation(LombokClassNames.EXTENSION_METHOD); if (annotation != null) { final Set<PsiClass> providers = PsiAnnotationUtil.getAnnotationValues(annotation, PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME, PsiType.class).stream() .filter(PsiClassType.class::isInstance) .map(PsiClassType.class::cast) .map(PsiClassType::resolve) .filter(Objects::nonNull) .collect(Collectors.toSet()); if (!providers.isEmpty()) { List<PsiExtensionMethod> extensionMethods = collectExtensionMethods(providers, ((PsiMethodCallExpression)place), targetClass); extensionMethods .stream() .map(method -> MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY)) .distinct() .filter(methodSignature -> !targetClass.getVisibleSignatures().contains(methodSignature)) .forEach(methodSignature -> result.add((PsiExtensionMethod)methodSignature.getMethod())); } } context = PsiTreeUtil.getContextOfType(context, PsiClass.class); } return result; }