void (@NotNull CompletionParameters parameters, @NotNull PrefixMatcher matcher, @NotNull MyStaticMembersProcessor processor, @NotNull CompletionResultSet result) { PsiElement position = parameters.getPosition(); PsiFile file = position.getContainingFile(); if (file == null) { return; } GlobalSearchScope scope = position.getResolveScope(); Project project = position.getProject(); if (project.isDefault()) { return; } Processor<PsiMember> psiStaticMethodProcessor = new Processor<>() { private int size = 0; private final MultiMap<PsiClass, String> classesToSkip = new MultiMap<>(); @Override public boolean process(PsiMember member) { ProgressManager.checkCanceled(); String name = member.getName(); if (name == null || !matcher.prefixMatches(name)) { return true; } if (!(member instanceof PsiMethod method && method.hasModifier(JvmModifier.STATIC))) { return true; } PsiFile currentFile = method.getContainingFile(); if (method.hasModifier(JvmModifier.PRIVATE) && !file.isEquivalentTo(currentFile)) { return true; } PsiClass containingClass = method.getContainingClass(); String methodName = method.getName(); if (containingClass == null) { return true; } Collection<String> names = classesToSkip.get(containingClass); if (names.contains(methodName)) { return true; } processor.processStaticMember(element -> { size++; result.consume(element); classesToSkip.putValue(containingClass, methodName); }, member, new HashSet<>()); return size < MAX_SIZE; } }; PsiElement originalPosition = parameters.getOriginalPosition(); if (originalPosition != null) { PsiClass nextClass = PsiTreeUtil.getParentOfType(originalPosition, PsiClass.class); while (nextClass != null) { PsiMethod[] methods = nextClass.getMethods(); for (PsiMethod method : methods) { ProgressManager.checkCanceled(); if (!psiStaticMethodProcessor.process(method)) { return; } } nextClass = PsiTreeUtil.getParentOfType(nextClass, PsiClass.class); } } List<JavaStaticMethodNameCache> staticList = JavaStaticMethodNameCache.EP_NAME.getExtensionList(project); Set<Class<? extends PsiShortNamesCache>> used = new HashSet<>(); for (JavaStaticMethodNameCache cache : staticList) { ProgressManager.checkCanceled(); used.add(cache.replaced()); boolean next = cache.processMethodsWithName(name -> matcher.prefixMatches(name), method -> { ProgressManager.checkCanceled(); return psiStaticMethodProcessor.process(method); }, scope, null); if (!next) { return; } } List<PsiShortNamesCache> list = PsiShortNamesCache.EP_NAME.getExtensionList(project); AtomicBoolean stop = new AtomicBoolean(false); for (PsiShortNamesCache cache : list) { //skip processed if (used.contains(cache.getClass())) { continue; } if (stop.get()) { break; } List<String> allNames = new ArrayList<>(); cache.processAllMethodNames(name -> { if (!matcher.prefixMatches(name)) { return true; } allNames.add(name); return true; }, scope, null); for (String name : allNames) { cache.processMethodsWithName(name, method -> { ProgressManager.checkCanceled(); boolean continueProcess = psiStaticMethodProcessor.process(method); stop.set(!continueProcess); return !stop.get(); }, scope, null); } } }