void (@NotNull CompletionParameters parameters, final boolean filterByScope, @NotNull final PrefixMatcher matcher, @NotNull final Consumer<? super LookupElement> consumer) { final PsiElement insertedElement = parameters.getPosition(); final PsiFile psiFile = insertedElement.getContainingFile(); JavaClassReference ref = JavaClassReferenceCompletionContributor.findJavaClassReference(psiFile, parameters.getOffset()); if (ref != null && ref.getContext() instanceof PsiClass) { return; } if (JavaCompletionContributor.getAnnotationNameIfInside(insertedElement) != null) { MultiMap<String, PsiClass> annoMap = getAllAnnotationClasses(insertedElement, matcher); Processor<PsiClass> processor = new LimitedAccessibleClassPreprocessor(parameters, filterByScope, anno -> { JavaPsiClassReferenceElement item = AllClassesGetter.createLookupItem(anno, JAVA_CLASS_INSERT_HANDLER); item.addLookupStrings(getClassNameWithContainers(anno)); consumer.consume(item); return true; }); for (String name : matcher.sortMatching(annoMap.keySet())) { if (!ContainerUtil.process(annoMap.get(name), processor)) break; } return; } final boolean inPermitsList = JavaCompletionContributor.IN_PERMITS_LIST.accepts(insertedElement); final ElementFilter filter = JavaCompletionContributor.getReferenceFilter(insertedElement); if (filter == null) return; final boolean inJavaContext = insertedElement instanceof PsiIdentifier; final boolean afterNew = AFTER_NEW.accepts(insertedElement); if (afterNew) { final PsiExpression expr = PsiTreeUtil.getContextOfType(insertedElement, PsiExpression.class, true); for (final ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes(expr, true)) { final PsiType type = info.getType(); final PsiClass psiClass = PsiUtil.resolveClassInType(type); if (psiClass != null && psiClass.getName() != null) { consumer.consume(createClassLookupItem(psiClass, inJavaContext)); } final PsiType defaultType = info.getDefaultType(); if (!defaultType.equals(type)) { final PsiClass defClass = PsiUtil.resolveClassInType(defaultType); if (defClass != null && defClass.getName() != null) { consumer.consume(createClassLookupItem(defClass, true)); } } } } final boolean pkgContext = JavaCompletionUtil.inSomePackage(insertedElement); final GlobalSearchScope scope = getReferenceScope(parameters, filterByScope, inPermitsList); JavaLookupElementHighlighter highlighter = JavaCompletionUtil.getHighlighterForPlace(insertedElement); boolean patternContext = JavaPatternCompletionUtil.isPatternContext(psiFile, insertedElement); Processor<PsiClass> classProcessor = new Processor<>() { @Override public boolean process(PsiClass psiClass) { processClass(psiClass, null, ""); return true; } private void processClass(PsiClass psiClass, @Nullable Set<? super PsiClass> visited, String prefix) { boolean isInnerClass = StringUtil.isNotEmpty(prefix); if (isInnerClass && isProcessedIndependently(psiClass)) { return; } if (filter.isAcceptable(psiClass, insertedElement)) { if (!inJavaContext) { JavaPsiClassReferenceElement element = AllClassesGetter.createLookupItem(psiClass, AllClassesGetter.TRY_SHORTENING); element.setLookupString(prefix + element.getLookupString()); consumer.consume(element); } else { Condition<PsiClass> condition = eachClass -> filter.isAcceptable(eachClass, insertedElement) && AllClassesGetter.isAcceptableInContext(insertedElement, eachClass, filterByScope, pkgContext); for (JavaPsiClassReferenceElement element : createClassLookupItems(psiClass, afterNew, JAVA_CLASS_INSERT_HANDLER, condition)) { element.setLookupString(prefix + element.getLookupString()); JavaConstructorCallElement.wrap(element, insertedElement).forEach( e -> consumer.consume(highlighter.highlightIfNeeded(null, e, e.getObject()))); if (patternContext) { JavaPatternCompletionUtil.addPatterns(consumer::consume, insertedElement, element.getObject()); } } } } else { String name = psiClass.getName(); if (name != null) { PsiClass[] innerClasses = psiClass.getInnerClasses(); if (innerClasses.length > 0) { if (visited == null) visited = new HashSet<>(); for (PsiClass innerClass : innerClasses) { if (visited.add(innerClass)) { processClass(innerClass, visited, prefix + name + "."); } } } } } } private boolean isProcessedIndependently(PsiClass psiClass) { String innerName = psiClass.getName(); return innerName != null && matcher.prefixMatches(innerName); } }; final Project project = insertedElement.getProject(); AllClassesGetter.processJavaClasses(matcher, project, scope, new LimitedAccessibleClassPreprocessor(parameters, filterByScope, classProcessor)); }