From a2f5914aff0caaf7cc5b0b739b0bb8a43c88760c Mon Sep 17 00:00:00 2001 From: UNV Date: Sat, 12 Apr 2025 09:37:48 +0300 Subject: [PATCH 1/2] Reformatting of query executors. --- .../impl/psi/impl/search/ThrowSearchUtil.java | 254 ++++--- .../search/searches/AllClassesSearch.java | 64 +- .../impl/ClassImplementationsSearch.java | 40 +- .../impl/CompositeShortNamesCache.java | 503 +++++++------ .../impl/MethodImplementationsSearch.java | 67 +- .../indexing/impl/PsiShortNamesCacheImpl.java | 504 +++++++------ .../impl/search/AllClassesSearchExecutor.java | 232 +++--- .../search/AnnotatedElementsSearcher.java | 149 ++-- .../ClassesWithAnnotatedMembersSearcher.java | 43 +- .../ConstructorReferencesSearchHelper.java | 485 ++++++------ .../search/ConstructorReferencesSearcher.java | 72 +- .../JavaAllOverridingMethodsSearcher.java | 127 ++-- .../search/JavaClassInheritorsSearcher.java | 237 +++--- .../search/JavaDirectInheritorsSearcher.java | 360 ++++----- .../JavaFunctionalExpressionSearcher.java | 706 +++++++++--------- .../search/JavaOverridingMethodsSearcher.java | 122 +-- .../search/JavaRecordComponentSearcher.java | 134 ++-- .../search/MethodDeepestSuperSearcher.java | 70 +- .../impl/search/MethodSuperSearcher.java | 128 ++-- .../impl/search/MethodUsagesSearcher.java | 187 +++-- ...PsiAnnotationMethodReferencesSearcher.java | 64 +- .../impl/search/SPIReferencesSearcher.java | 90 +-- .../SimpleAccessorReferenceSearcher.java | 46 +- .../psi/search/PsiShortNameProvider.java | 285 +++---- .../psi/search/PsiShortNamesCache.java | 301 ++++---- .../InferNullityAnnotationsAction.java | 513 +++++++------ .../nullable/NullableStuffInspection.java | 115 +-- .../actions/GenerateJavadocAction.java | 82 +- .../search/AnnotatedPackagesSearcher.java | 200 ++--- .../VariableInIncompleteCodeSearcher.java | 70 +- 30 files changed, 3312 insertions(+), 2938 deletions(-) diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/psi/impl/search/ThrowSearchUtil.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/psi/impl/search/ThrowSearchUtil.java index 68fb68108..65f195ca0 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/psi/impl/search/ThrowSearchUtil.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/psi/impl/search/ThrowSearchUtil.java @@ -38,142 +38,148 @@ */ public class ThrowSearchUtil { - private static final Logger LOG = Logger.getInstance(ThrowSearchUtil.class); + private static final Logger LOG = Logger.getInstance(ThrowSearchUtil.class); - private ThrowSearchUtil() { - } + private ThrowSearchUtil() { + } - public static class Root { - final PsiElement myElement; - final PsiType myType; - final boolean isExact; + public static class Root { + final PsiElement myElement; + final PsiType myType; + final boolean isExact; - public Root(final PsiElement root, final PsiType type, final boolean exact) { - myElement = root; - myType = type; - isExact = exact; - } + public Root(final PsiElement root, final PsiType type, final boolean exact) { + myElement = root; + myType = type; + isExact = exact; + } - public String toString() { - return PsiFormatUtil.formatType(myType, PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES, PsiSubstitutor.EMPTY); - } - } - - public static Key THROW_SEARCH_ROOT_KEY = Key.create("ThrowSearchUtil.root"); - - /** - * @param aCatch - * @param processor - * @param root - * @return true, if we should continue processing - */ - private static boolean processExn(@Nonnull PsiParameter aCatch, @Nonnull Processor processor, @Nonnull Root root) { - final PsiType type = aCatch.getType(); - if (type.isAssignableFrom(root.myType)) { - processor.process(new UsageInfo(aCatch)); - return false; - } - if (!root.isExact && root.myType.isAssignableFrom(type)) { - processor.process(new UsageInfo(aCatch)); - return true; - } - return true; - } - - private static boolean scanCatches(@Nonnull PsiElement elem, - @Nonnull Processor processor, - @Nonnull Root root, - @Nonnull FindUsagesOptions options, - @Nonnull Set processed) { - while (elem != null) { - final PsiElement parent = elem.getParent(); - if (elem instanceof PsiMethod) { - final PsiMethod deepestSuperMethod = ((PsiMethod) elem).findDeepestSuperMethod(); - final PsiMethod method = deepestSuperMethod != null ? deepestSuperMethod : (PsiMethod) elem; - if (!processed.contains(method)) { - processed.add(method); - final PsiReference[] refs = MethodReferencesSearch.search(method, options.searchScope, true).toArray(PsiReference.EMPTY_ARRAY); - for (int i = 0; i != refs.length; ++i) { - if (!scanCatches(refs[i].getElement(), processor, root, options, processed)) return false; - } + public String toString() { + return PsiFormatUtil.formatType(myType, PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES, PsiSubstitutor.EMPTY); } - return true; - } - if (elem instanceof PsiTryStatement) { - final PsiTryStatement aTry = (PsiTryStatement) elem; - final PsiParameter[] catches = aTry.getCatchBlockParameters(); - for (int i = 0; i != catches.length; ++i) { - if (!processExn(catches[i], processor, root)) { + } + + public static Key THROW_SEARCH_ROOT_KEY = Key.create("ThrowSearchUtil.root"); + + /** + * @param aCatch + * @param processor + * @param root + * @return true, if we should continue processing + */ + private static boolean processExn(@Nonnull PsiParameter aCatch, @Nonnull Processor processor, @Nonnull Root root) { + final PsiType type = aCatch.getType(); + if (type.isAssignableFrom(root.myType)) { + processor.process(new UsageInfo(aCatch)); return false; - } } - } else if (parent instanceof PsiTryStatement) { - final PsiTryStatement tryStmt = (PsiTryStatement) parent; - if (elem != tryStmt.getTryBlock()) { - elem = parent.getParent(); - continue; + if (!root.isExact && root.myType.isAssignableFrom(type)) { + processor.process(new UsageInfo(aCatch)); + return true; + } + return true; + } + + private static boolean scanCatches( + @Nonnull PsiElement elem, + @Nonnull Processor processor, + @Nonnull Root root, + @Nonnull FindUsagesOptions options, + @Nonnull Set processed + ) { + while (elem != null) { + final PsiElement parent = elem.getParent(); + if (elem instanceof PsiMethod) { + final PsiMethod deepestSuperMethod = ((PsiMethod)elem).findDeepestSuperMethod(); + final PsiMethod method = deepestSuperMethod != null ? deepestSuperMethod : (PsiMethod)elem; + if (!processed.contains(method)) { + processed.add(method); + final PsiReference[] refs = + MethodReferencesSearch.search(method, options.searchScope, true).toArray(PsiReference.EMPTY_ARRAY); + for (int i = 0; i != refs.length; ++i) { + if (!scanCatches(refs[i].getElement(), processor, root, options, processed)) { + return false; + } + } + } + return true; + } + if (elem instanceof PsiTryStatement) { + final PsiTryStatement aTry = (PsiTryStatement)elem; + final PsiParameter[] catches = aTry.getCatchBlockParameters(); + for (int i = 0; i != catches.length; ++i) { + if (!processExn(catches[i], processor, root)) { + return false; + } + } + } + else if (parent instanceof PsiTryStatement) { + final PsiTryStatement tryStmt = (PsiTryStatement)parent; + if (elem != tryStmt.getTryBlock()) { + elem = parent.getParent(); + continue; + } + } + elem = parent; } - } - elem = parent; + return true; + } + + public static boolean addThrowUsages(@Nonnull Processor processor, @Nonnull Root root, @Nonnull FindUsagesOptions options) { + Set processed = new HashSet(); + return scanCatches(root.myElement, processor, root, options, processed); } - return true; - } - - public static boolean addThrowUsages(@Nonnull Processor processor, @Nonnull Root root, @Nonnull FindUsagesOptions options) { - Set processed = new HashSet(); - return scanCatches(root.myElement, processor, root, options, processed); - } - - /** - * @param exn - * @return is type of exn exactly known - */ - - private static boolean isExactExnType(final PsiExpression exn) { - return exn instanceof PsiNewExpression; - } - - @Nullable - public static Root[] getSearchRoots(final PsiElement element) { - if (element instanceof PsiThrowStatement) { - final PsiThrowStatement aThrow = (PsiThrowStatement) element; - final PsiExpression exn = aThrow.getException(); - return new Root[]{new Root(aThrow.getParent(), exn.getType(), isExactExnType(exn))}; + + /** + * @param exn + * @return is type of exn exactly known + */ + + private static boolean isExactExnType(final PsiExpression exn) { + return exn instanceof PsiNewExpression; } - if (element instanceof PsiKeyword) { - final PsiKeyword kwd = (PsiKeyword) element; - if (PsiKeyword.THROWS.equals(kwd.getText())) { - final PsiElement parent = kwd.getParent(); - if (parent != null && parent.getParent() instanceof PsiMethod) { - final PsiMethod method = (PsiMethod) parent.getParent(); - final PsiReferenceList throwsList = method.getThrowsList(); - final PsiClassType[] exns = throwsList.getReferencedTypes(); - final Root[] roots = new Root[exns.length]; - for (int i = 0; i != roots.length; ++i) { - final PsiClassType exn = exns[i]; - roots[i] = new Root(method, exn, false); // TODO: test for final - } - return roots; + + @Nullable + public static Root[] getSearchRoots(final PsiElement element) { + if (element instanceof PsiThrowStatement) { + final PsiThrowStatement aThrow = (PsiThrowStatement)element; + final PsiExpression exn = aThrow.getException(); + return new Root[]{new Root(aThrow.getParent(), exn.getType(), isExactExnType(exn))}; + } + if (element instanceof PsiKeyword) { + final PsiKeyword kwd = (PsiKeyword)element; + if (PsiKeyword.THROWS.equals(kwd.getText())) { + final PsiElement parent = kwd.getParent(); + if (parent != null && parent.getParent() instanceof PsiMethod) { + final PsiMethod method = (PsiMethod)parent.getParent(); + final PsiReferenceList throwsList = method.getThrowsList(); + final PsiClassType[] exns = throwsList.getReferencedTypes(); + final Root[] roots = new Root[exns.length]; + for (int i = 0; i != roots.length; ++i) { + final PsiClassType exn = exns[i]; + roots[i] = new Root(method, exn, false); // TODO: test for final + } + return roots; + } + } } - } + return null; } - return null; - } - - public static boolean isSearchable(final PsiElement element) { - return getSearchRoots(element) != null; - } - - public static String getSearchableTypeName(final PsiElement e) { - if (e instanceof PsiThrowStatement) { - final PsiThrowStatement aThrow = (PsiThrowStatement) e; - final PsiType type = aThrow.getException().getType(); - return PsiFormatUtil.formatType(type, PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES, PsiSubstitutor.EMPTY); + + public static boolean isSearchable(final PsiElement element) { + return getSearchRoots(element) != null; } - if (e instanceof PsiKeyword && PsiKeyword.THROWS.equals(e.getText())) { - return e.getParent().getText(); + + public static String getSearchableTypeName(final PsiElement e) { + if (e instanceof PsiThrowStatement) { + final PsiThrowStatement aThrow = (PsiThrowStatement)e; + final PsiType type = aThrow.getException().getType(); + return PsiFormatUtil.formatType(type, PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES, PsiSubstitutor.EMPTY); + } + if (e instanceof PsiKeyword && PsiKeyword.THROWS.equals(e.getText())) { + return e.getParent().getText(); + } + LOG.error("invalid searchable element"); + return e.getText(); } - LOG.error("invalid searchable element"); - return e.getText(); - } } diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearch.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearch.java index 0090932e8..5dc03f012 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearch.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearch.java @@ -26,46 +26,48 @@ import consulo.application.util.query.ExtensibleQueryFactory; import consulo.application.util.query.Query; +import java.util.function.Predicate; + public class AllClassesSearch extends ExtensibleQueryFactory { - public static final AllClassesSearch INSTANCE = new AllClassesSearch(); + public static final AllClassesSearch INSTANCE = new AllClassesSearch(); - public static class SearchParameters { - private final SearchScope myScope; - private final Project myProject; - private final Condition myShortNameCondition; + public static class SearchParameters { + private final SearchScope myScope; + private final Project myProject; + private final Condition myShortNameCondition; - public SearchParameters(final SearchScope scope, final Project project) { - this(scope, project, Condition.TRUE); - } + public SearchParameters(final SearchScope scope, final Project project) { + this(scope, project, Condition.TRUE); + } - public SearchParameters(final SearchScope scope, final Project project, final Condition shortNameCondition) { - myScope = scope; - myProject = project; - myShortNameCondition = shortNameCondition; - } + public SearchParameters(final SearchScope scope, final Project project, final Condition shortNameCondition) { + myScope = scope; + myProject = project; + myShortNameCondition = shortNameCondition; + } - public SearchScope getScope() { - return myScope; - } + public SearchScope getScope() { + return myScope; + } - public Project getProject() { - return myProject; - } + public Project getProject() { + return myProject; + } - public boolean nameMatches(String name) { - return myShortNameCondition.value(name); + public boolean nameMatches(String name) { + return myShortNameCondition.value(name); + } } - } - private AllClassesSearch() { - super(AllClassesSearchExecutor.class); - } + private AllClassesSearch() { + super(AllClassesSearchExecutor.class); + } - public static Query search(SearchScope scope, Project project) { - return INSTANCE.createQuery(new SearchParameters(scope, project)); - } + public static Query search(SearchScope scope, Project project) { + return INSTANCE.createQuery(new SearchParameters(scope, project)); + } - public static Query search(SearchScope scope, Project project, Condition shortNameCondition) { - return INSTANCE.createQuery(new SearchParameters(scope, project, shortNameCondition)); - } + public static Query search(SearchScope scope, Project project, Predicate shortNameCondition) { + return INSTANCE.createQuery(new SearchParameters(scope, project, shortNameCondition)); + } } \ No newline at end of file diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/ClassImplementationsSearch.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/ClassImplementationsSearch.java index 6547f4ec0..0181c4954 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/ClassImplementationsSearch.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/ClassImplementationsSearch.java @@ -30,20 +30,32 @@ @ExtensionImpl public class ClassImplementationsSearch implements DefinitionsScopedSearchExecutor { - @Override - public boolean execute(@Nonnull DefinitionsScopedSearch.SearchParameters queryParameters, @Nonnull Processor consumer) { - final PsiElement sourceElement = queryParameters.getElement(); - return !(sourceElement instanceof PsiClass) || processImplementations((PsiClass) sourceElement, consumer, queryParameters.getScope()); - } - - public static boolean processImplementations(final PsiClass psiClass, final Processor processor, SearchScope scope) { - if (!FunctionalExpressionSearch.search(psiClass, scope).forEach(expression -> - { - return processor.process(expression); - })) { - return false; + @Override + public boolean execute( + @Nonnull DefinitionsScopedSearch.SearchParameters queryParameters, + @Nonnull Processor consumer + ) { + final PsiElement sourceElement = queryParameters.getElement(); + return !(sourceElement instanceof PsiClass) || processImplementations( + (PsiClass)sourceElement, + consumer, + queryParameters.getScope() + ); } - return ClassInheritorsSearch.search(psiClass, scope, true).forEach(new PsiElementProcessorAdapter<>((PsiElementProcessor) element -> processor.process(element))); - } + public static boolean processImplementations( + final PsiClass psiClass, + final Processor processor, + SearchScope scope + ) { + if (!FunctionalExpressionSearch.search(psiClass, scope).forEach(expression -> + { + return processor.process(expression); + })) { + return false; + } + + return ClassInheritorsSearch.search(psiClass, scope, true) + .forEach(new PsiElementProcessorAdapter<>((PsiElementProcessor)element -> processor.process(element))); + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/CompositeShortNamesCache.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/CompositeShortNamesCache.java index 55abfa86c..830807fa7 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/CompositeShortNamesCache.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/CompositeShortNamesCache.java @@ -35,6 +35,7 @@ import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -43,302 +44,316 @@ @Singleton @ServiceImpl public class CompositeShortNamesCache extends PsiShortNamesCache { - private final List myCaches; + private final List myCaches; - @Inject - public CompositeShortNamesCache(Project project) { - myCaches = project.isDefault() ? List.of() : project.getExtensionList(PsiShortNameProvider.class); - } + @Inject + public CompositeShortNamesCache(Project project) { + myCaches = project.isDefault() ? List.of() : project.getExtensionList(PsiShortNameProvider.class); + } - @Override - @Nonnull - public PsiFile[] getFilesByName(@Nonnull String name) { - Merger merger = null; - for (PsiShortNameProvider cache : myCaches) { - PsiFile[] classes = cache.getFilesByName(name); - if (classes.length != 0) { - if (merger == null) { - merger = new Merger<>(); + @Override + @Nonnull + public PsiFile[] getFilesByName(@Nonnull String name) { + Merger merger = null; + for (PsiShortNameProvider cache : myCaches) { + PsiFile[] classes = cache.getFilesByName(name); + if (classes.length != 0) { + if (merger == null) { + merger = new Merger<>(); + } + merger.add(classes); + } } - merger.add(classes); - } + PsiFile[] result = merger == null ? null : merger.getResult(); + return result != null ? result : PsiFile.EMPTY_ARRAY; } - PsiFile[] result = merger == null ? null : merger.getResult(); - return result != null ? result : PsiFile.EMPTY_ARRAY; - } - @Override - @Nonnull - public String[] getAllFileNames() { - Merger merger = new Merger<>(); - for (PsiShortNameProvider cache : myCaches) { - merger.add(cache.getAllFileNames()); + @Override + @Nonnull + public String[] getAllFileNames() { + Merger merger = new Merger<>(); + for (PsiShortNameProvider cache : myCaches) { + merger.add(cache.getAllFileNames()); + } + String[] result = merger.getResult(); + return result != null ? result : ArrayUtil.EMPTY_STRING_ARRAY; } - String[] result = merger.getResult(); - return result != null ? result : ArrayUtil.EMPTY_STRING_ARRAY; - } - @Override - @Nonnull - public PsiClass[] getClassesByName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { - Merger merger = null; - for (PsiShortNameProvider cache : myCaches) { - PsiClass[] classes = cache.getClassesByName(name, scope); - if (classes.length != 0) { - if (merger == null) { - merger = new Merger<>(); + @Override + @Nonnull + public PsiClass[] getClassesByName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { + Merger merger = null; + for (PsiShortNameProvider cache : myCaches) { + PsiClass[] classes = cache.getClassesByName(name, scope); + if (classes.length != 0) { + if (merger == null) { + merger = new Merger<>(); + } + merger.add(classes); + } } - merger.add(classes); - } + PsiClass[] result = merger == null ? null : merger.getResult(); + return result != null ? result : PsiClass.EMPTY_ARRAY; } - PsiClass[] result = merger == null ? null : merger.getResult(); - return result != null ? result : PsiClass.EMPTY_ARRAY; - } - @Override - @Nonnull - public String[] getAllClassNames() { - Merger merger = new Merger<>(); - for (PsiShortNameProvider cache : myCaches) { - String[] names = cache.getAllClassNames(); - merger.add(names); + @Override + @Nonnull + public String[] getAllClassNames() { + Merger merger = new Merger<>(); + for (PsiShortNameProvider cache : myCaches) { + String[] names = cache.getAllClassNames(); + merger.add(names); + } + String[] result = merger.getResult(); + return result != null ? result : ArrayUtil.EMPTY_STRING_ARRAY; } - String[] result = merger.getResult(); - return result != null ? result : ArrayUtil.EMPTY_STRING_ARRAY; - } - @Override - public boolean processAllClassNames(Processor processor) { - CommonProcessors.UniqueProcessor uniqueProcessor = new CommonProcessors.UniqueProcessor<>(processor); - for (PsiShortNameProvider cache : myCaches) { - if (!cache.processAllClassNames(uniqueProcessor)) { - return false; - } + @Override + public boolean processAllClassNames(Processor processor) { + CommonProcessors.UniqueProcessor uniqueProcessor = new CommonProcessors.UniqueProcessor<>(processor); + for (PsiShortNameProvider cache : myCaches) { + if (!cache.processAllClassNames(uniqueProcessor)) { + return false; + } + } + return true; } - return true; - } - @Override - public boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - for (PsiShortNameProvider cache : myCaches) { - if (!cache.processAllClassNames(processor, scope, filter)) { - return false; - } + @Override + public boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + for (PsiShortNameProvider cache : myCaches) { + if (!cache.processAllClassNames(processor, scope, filter)) { + return false; + } + } + return true; } - return true; - } - @Override - public boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - for (PsiShortNameProvider cache : myCaches) { - if (!cache.processAllMethodNames(processor, scope, filter)) { - return false; - } + @Override + public boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + for (PsiShortNameProvider cache : myCaches) { + if (!cache.processAllMethodNames(processor, scope, filter)) { + return false; + } + } + return true; } - return true; - } - @Override - public boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - for (PsiShortNameProvider cache : myCaches) { - if (!cache.processAllFieldNames(processor, scope, filter)) { - return false; - } + @Override + public boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + for (PsiShortNameProvider cache : myCaches) { + if (!cache.processAllFieldNames(processor, scope, filter)) { + return false; + } + } + return true; } - return true; - } - @Override - public void getAllClassNames(@Nonnull HashSet dest) { - for (PsiShortNameProvider cache : myCaches) { - cache.getAllClassNames(dest); + @Override + public void getAllClassNames(@Nonnull HashSet dest) { + for (PsiShortNameProvider cache : myCaches) { + cache.getAllClassNames(dest); + } } - } - @Override - @Nonnull - public PsiMethod[] getMethodsByName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { - Merger merger = null; - for (PsiShortNameProvider cache : myCaches) { - PsiMethod[] methods = cache.getMethodsByName(name, scope); - if (methods.length != 0) { - if (merger == null) { - merger = new Merger<>(); + @Override + @Nonnull + public PsiMethod[] getMethodsByName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { + Merger merger = null; + for (PsiShortNameProvider cache : myCaches) { + PsiMethod[] methods = cache.getMethodsByName(name, scope); + if (methods.length != 0) { + if (merger == null) { + merger = new Merger<>(); + } + merger.add(methods); + } } - merger.add(methods); - } + PsiMethod[] result = merger == null ? null : merger.getResult(); + return result == null ? PsiMethod.EMPTY_ARRAY : result; } - PsiMethod[] result = merger == null ? null : merger.getResult(); - return result == null ? PsiMethod.EMPTY_ARRAY : result; - } - @Override - @Nonnull - public PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @Nonnull final String name, @Nonnull final GlobalSearchScope scope, final int maxCount) { - Merger merger = null; - for (PsiShortNameProvider cache : myCaches) { - PsiMethod[] methods = cache.getMethodsByNameIfNotMoreThan(name, scope, maxCount); - if (methods.length == maxCount) { - return methods; - } - if (methods.length != 0) { - if (merger == null) { - merger = new Merger<>(); + @Override + @Nonnull + public PsiMethod[] getMethodsByNameIfNotMoreThan( + @NonNls @Nonnull final String name, + @Nonnull final GlobalSearchScope scope, + final int maxCount + ) { + Merger merger = null; + for (PsiShortNameProvider cache : myCaches) { + PsiMethod[] methods = cache.getMethodsByNameIfNotMoreThan(name, scope, maxCount); + if (methods.length == maxCount) { + return methods; + } + if (methods.length != 0) { + if (merger == null) { + merger = new Merger<>(); + } + merger.add(methods); + } } - merger.add(methods); - } + PsiMethod[] result = merger == null ? null : merger.getResult(); + return result == null ? PsiMethod.EMPTY_ARRAY : result; } - PsiMethod[] result = merger == null ? null : merger.getResult(); - return result == null ? PsiMethod.EMPTY_ARRAY : result; - } - @Nonnull - @Override - public PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount) { - Merger merger = null; - for (PsiShortNameProvider cache : myCaches) { - PsiField[] fields = cache.getFieldsByNameIfNotMoreThan(name, scope, maxCount); - if (fields.length == maxCount) { - return fields; - } - if (fields.length != 0) { - if (merger == null) { - merger = new Merger<>(); + @Nonnull + @Override + public PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount) { + Merger merger = null; + for (PsiShortNameProvider cache : myCaches) { + PsiField[] fields = cache.getFieldsByNameIfNotMoreThan(name, scope, maxCount); + if (fields.length == maxCount) { + return fields; + } + if (fields.length != 0) { + if (merger == null) { + merger = new Merger<>(); + } + merger.add(fields); + } } - merger.add(fields); - } + PsiField[] result = merger == null ? null : merger.getResult(); + return result == null ? PsiField.EMPTY_ARRAY : result; } - PsiField[] result = merger == null ? null : merger.getResult(); - return result == null ? PsiField.EMPTY_ARRAY : result; - } - @Override - public boolean processMethodsWithName(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, @Nonnull Processor processor) { - return processMethodsWithName(name, processor, scope, null); - } + @Override + public boolean processMethodsWithName( + @NonNls @Nonnull String name, + @Nonnull GlobalSearchScope scope, + @Nonnull Processor processor + ) { + return processMethodsWithName(name, processor, scope, null); + } - @Override - public boolean processMethodsWithName(@NonNls @Nonnull String name, @Nonnull Processor processor, - @Nonnull GlobalSearchScope scope, @Nullable IdFilter idFilter) { - for (PsiShortNameProvider cache : myCaches) { - if (!cache.processMethodsWithName(name, processor, scope, idFilter)) { - return false; - } + @Override + public boolean processMethodsWithName( + @NonNls @Nonnull String name, @Nonnull Processor processor, + @Nonnull GlobalSearchScope scope, @Nullable IdFilter idFilter + ) { + for (PsiShortNameProvider cache : myCaches) { + if (!cache.processMethodsWithName(name, processor, scope, idFilter)) { + return false; + } + } + return true; } - return true; - } - @Override - @Nonnull - public String[] getAllMethodNames() { - Merger merger = new Merger<>(); - for (PsiShortNameProvider cache : myCaches) { - merger.add(cache.getAllMethodNames()); + @Override + @Nonnull + public String[] getAllMethodNames() { + Merger merger = new Merger<>(); + for (PsiShortNameProvider cache : myCaches) { + merger.add(cache.getAllMethodNames()); + } + String[] result = merger.getResult(); + return result != null ? result : ArrayUtil.EMPTY_STRING_ARRAY; } - String[] result = merger.getResult(); - return result != null ? result : ArrayUtil.EMPTY_STRING_ARRAY; - } - @Override - public void getAllMethodNames(@Nonnull HashSet set) { - for (PsiShortNameProvider cache : myCaches) { - cache.getAllMethodNames(set); + @Override + public void getAllMethodNames(@Nonnull HashSet set) { + for (PsiShortNameProvider cache : myCaches) { + cache.getAllMethodNames(set); + } } - } - @Override - @Nonnull - public PsiField[] getFieldsByName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { - Merger merger = null; - for (PsiShortNameProvider cache : myCaches) { - PsiField[] classes = cache.getFieldsByName(name, scope); - if (classes.length != 0) { - if (merger == null) { - merger = new Merger<>(); + @Override + @Nonnull + public PsiField[] getFieldsByName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { + Merger merger = null; + for (PsiShortNameProvider cache : myCaches) { + PsiField[] classes = cache.getFieldsByName(name, scope); + if (classes.length != 0) { + if (merger == null) { + merger = new Merger<>(); + } + merger.add(classes); + } } - merger.add(classes); - } + PsiField[] result = merger == null ? null : merger.getResult(); + return result == null ? PsiField.EMPTY_ARRAY : result; } - PsiField[] result = merger == null ? null : merger.getResult(); - return result == null ? PsiField.EMPTY_ARRAY : result; - } - @Override - @Nonnull - public String[] getAllFieldNames() { - Merger merger = null; - for (PsiShortNameProvider cache : myCaches) { - String[] classes = cache.getAllFieldNames(); - if (classes.length != 0) { - if (merger == null) { - merger = new Merger<>(); + @Override + @Nonnull + public String[] getAllFieldNames() { + Merger merger = null; + for (PsiShortNameProvider cache : myCaches) { + String[] classes = cache.getAllFieldNames(); + if (classes.length != 0) { + if (merger == null) { + merger = new Merger<>(); + } + merger.add(classes); + } } - merger.add(classes); - } + String[] result = merger == null ? null : merger.getResult(); + return result == null ? ArrayUtil.EMPTY_STRING_ARRAY : result; } - String[] result = merger == null ? null : merger.getResult(); - return result == null ? ArrayUtil.EMPTY_STRING_ARRAY : result; - } - @Override - public void getAllFieldNames(@Nonnull HashSet set) { - for (PsiShortNameProvider cache : myCaches) { - cache.getAllFieldNames(set); + @Override + public void getAllFieldNames(@Nonnull HashSet set) { + for (PsiShortNameProvider cache : myCaches) { + cache.getAllFieldNames(set); + } } - } - @Override - public boolean processFieldsWithName(@Nonnull String key, @Nonnull Processor processor, @Nonnull GlobalSearchScope scope, - @Nullable IdFilter filter) { - for (PsiShortNameProvider cache : myCaches) { - if (!cache.processFieldsWithName(key, processor, scope, filter)) { - return false; - } + @Override + public boolean processFieldsWithName( + @Nonnull String key, @Nonnull Processor processor, @Nonnull GlobalSearchScope scope, + @Nullable IdFilter filter + ) { + for (PsiShortNameProvider cache : myCaches) { + if (!cache.processFieldsWithName(key, processor, scope, filter)) { + return false; + } + } + return true; } - return true; - } - @Override - public boolean processClassesWithName(@Nonnull String key, @Nonnull Processor processor, @Nonnull GlobalSearchScope scope, - @Nullable IdFilter filter) { - for (PsiShortNameProvider cache : myCaches) { - if (!cache.processClassesWithName(key, processor, scope, filter)) { - return false; - } + @Override + public boolean processClassesWithName( + @Nonnull String key, @Nonnull Processor processor, @Nonnull GlobalSearchScope scope, + @Nullable IdFilter filter + ) { + for (PsiShortNameProvider cache : myCaches) { + if (!cache.processClassesWithName(key, processor, scope, filter)) { + return false; + } + } + return true; } - return true; - } - private static class Merger { - private T[] mySingleItem; - private Set myAllItems; + private static class Merger { + private T[] mySingleItem; + private Set myAllItems; - public void add(@Nonnull T[] items) { - if (items.length == 0) { - return; - } - if (mySingleItem == null) { - mySingleItem = items; - return; - } - if (myAllItems == null) { - T[] elements = mySingleItem; - myAllItems = ContainerUtil.addAll(new HashSet<>(elements.length), elements); - } - ContainerUtil.addAll(myAllItems, items); - } + public void add(@Nonnull T[] items) { + if (items.length == 0) { + return; + } + if (mySingleItem == null) { + mySingleItem = items; + return; + } + if (myAllItems == null) { + T[] elements = mySingleItem; + myAllItems = ContainerUtil.addAll(new HashSet<>(elements.length), elements); + } + ContainerUtil.addAll(myAllItems, items); + } - public T[] getResult() { - if (myAllItems == null) { - return mySingleItem; - } - return myAllItems.toArray(mySingleItem); + public T[] getResult() { + if (myAllItems == null) { + return mySingleItem; + } + return myAllItems.toArray(mySingleItem); + } } - } - @SuppressWarnings({"HardCodedStringLiteral"}) - @Override - public String toString() { - return "Composite cache: " + Arrays.asList(myCaches); - } + @SuppressWarnings({"HardCodedStringLiteral"}) + @Override + public String toString() { + return "Composite cache: " + Arrays.asList(myCaches); + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/MethodImplementationsSearch.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/MethodImplementationsSearch.java index dad308c4f..bb2e1c37a 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/MethodImplementationsSearch.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/MethodImplementationsSearch.java @@ -33,41 +33,48 @@ @ExtensionImpl public class MethodImplementationsSearch implements DefinitionsScopedSearchExecutor { - @Override - public boolean execute(@Nonnull final DefinitionsScopedSearch.SearchParameters queryParameters, @Nonnull final Processor consumer) { - final PsiElement sourceElement = queryParameters.getElement(); - if (sourceElement instanceof PsiMethod) { - return processImplementations((PsiMethod) sourceElement, consumer, queryParameters.getScope()); + @Override + public boolean execute( + @Nonnull final DefinitionsScopedSearch.SearchParameters queryParameters, + @Nonnull final Processor consumer + ) { + final PsiElement sourceElement = queryParameters.getElement(); + if (sourceElement instanceof PsiMethod) { + return processImplementations((PsiMethod)sourceElement, consumer, queryParameters.getScope()); + } + return true; } - return true; - } - public static boolean processImplementations(final PsiMethod psiMethod, final Processor consumer, final SearchScope searchScope) { - if (!FunctionalExpressionSearch.search(psiMethod, searchScope).forEach(new Processor() { - @Override - public boolean process(PsiFunctionalExpression expression) { - return consumer.process(expression); - } - })) { - return false; + public static boolean processImplementations( + final PsiMethod psiMethod, + final Processor consumer, + final SearchScope searchScope + ) { + if (!FunctionalExpressionSearch.search(psiMethod, searchScope).forEach(new Processor() { + @Override + public boolean process(PsiFunctionalExpression expression) { + return consumer.process(expression); + } + })) { + return false; + } + List methods = new ArrayList(); + getOverridingMethods(psiMethod, methods, searchScope); + return ContainerUtil.process(methods, consumer); } - List methods = new ArrayList(); - getOverridingMethods(psiMethod, methods, searchScope); - return ContainerUtil.process(methods, consumer); - } - public static void getOverridingMethods(PsiMethod method, List list, SearchScope scope) { - for (PsiMethod psiMethod : OverridingMethodsSearch.search(method, scope, true)) { - list.add(psiMethod); + public static void getOverridingMethods(PsiMethod method, List list, SearchScope scope) { + for (PsiMethod psiMethod : OverridingMethodsSearch.search(method, scope, true)) { + list.add(psiMethod); + } } - } - @SuppressWarnings("UnusedDeclaration") - @Deprecated - public static PsiMethod[] getMethodImplementations(final PsiMethod method, SearchScope scope) { - List result = new ArrayList(); + @SuppressWarnings("UnusedDeclaration") + @Deprecated + public static PsiMethod[] getMethodImplementations(final PsiMethod method, SearchScope scope) { + List result = new ArrayList(); - getOverridingMethods(method, result, scope); - return result.toArray(new PsiMethod[result.size()]); - } + getOverridingMethods(method, result, scope); + return result.toArray(new PsiMethod[result.size()]); + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/PsiShortNamesCacheImpl.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/PsiShortNamesCacheImpl.java index b88332eb6..2bd785efe 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/PsiShortNamesCacheImpl.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/PsiShortNamesCacheImpl.java @@ -51,242 +51,306 @@ @ExtensionImpl public class PsiShortNamesCacheImpl implements PsiShortNameProvider { - private final Project myProject; - - @Inject - public PsiShortNamesCacheImpl(Project project) { - myProject = project; - } - - @Override - @Nonnull - public PsiFile[] getFilesByName(@Nonnull String name) { - return FilenameIndex.getFilesByName(myProject, name, GlobalSearchScope.projectScope(myProject)); - } - - @Override - @Nonnull - public String[] getAllFileNames() { - return FilenameIndex.getAllFilenames(myProject); - } - - @Override - @Nonnull - public PsiClass[] getClassesByName(@Nonnull String name, @Nonnull final GlobalSearchScope scope) { - final Collection classes = JavaShortClassNameIndex.getInstance().get(name, myProject, scope); - - if (classes.isEmpty()) { - return PsiClass.EMPTY_ARRAY; + private final Project myProject; + + @Inject + public PsiShortNamesCacheImpl(Project project) { + myProject = project; + } + + @Override + @Nonnull + public PsiFile[] getFilesByName(@Nonnull String name) { + return FilenameIndex.getFilesByName(myProject, name, GlobalSearchScope.projectScope(myProject)); } - ArrayList list = new ArrayList(classes.size()); - - OuterLoop: - for (PsiClass aClass : classes) { - VirtualFile vFile = aClass.getContainingFile().getVirtualFile(); - if (!scope.contains(vFile)) { - continue; - } - - for (int j = 0; j < list.size(); j++) { - PsiClass aClass1 = list.get(j); - - String qName = aClass.getQualifiedName(); - String qName1 = aClass1.getQualifiedName(); - if (qName != null && qName1 != null && qName.equals(qName1)) { - VirtualFile vFile1 = aClass1.getContainingFile().getVirtualFile(); - int res = scope.compare(vFile1, vFile); - if (res > 0) { - continue OuterLoop; // aClass1 hides aClass - } else if (res < 0) { - list.remove(j); - //noinspection AssignmentToForLoopParameter - j--; // aClass hides aClass1 - } + + @Override + @Nonnull + public String[] getAllFileNames() { + return FilenameIndex.getAllFilenames(myProject); + } + + @Override + @Nonnull + public PsiClass[] getClassesByName(@Nonnull String name, @Nonnull final GlobalSearchScope scope) { + final Collection classes = JavaShortClassNameIndex.getInstance().get(name, myProject, scope); + + if (classes.isEmpty()) { + return PsiClass.EMPTY_ARRAY; + } + ArrayList list = new ArrayList(classes.size()); + + OuterLoop: + for (PsiClass aClass : classes) { + VirtualFile vFile = aClass.getContainingFile().getVirtualFile(); + if (!scope.contains(vFile)) { + continue; + } + + for (int j = 0; j < list.size(); j++) { + PsiClass aClass1 = list.get(j); + + String qName = aClass.getQualifiedName(); + String qName1 = aClass1.getQualifiedName(); + if (qName != null && qName1 != null && qName.equals(qName1)) { + VirtualFile vFile1 = aClass1.getContainingFile().getVirtualFile(); + int res = scope.compare(vFile1, vFile); + if (res > 0) { + continue OuterLoop; // aClass1 hides aClass + } + else if (res < 0) { + list.remove(j); + //noinspection AssignmentToForLoopParameter + j--; // aClass hides aClass1 + } + } + } + + list.add(aClass); } - } + return list.toArray(new PsiClass[list.size()]); + } + + @Override + @Nonnull + public String[] getAllClassNames() { + return ArrayUtil.toStringArray(JavaShortClassNameIndex.getInstance().getAllKeys(myProject)); + } - list.add(aClass); + @Override + public void getAllClassNames(@Nonnull HashSet set) { + processAllClassNames(new CommonProcessors.CollectProcessor(set)); } - return list.toArray(new PsiClass[list.size()]); - } - - @Override - @Nonnull - public String[] getAllClassNames() { - return ArrayUtil.toStringArray(JavaShortClassNameIndex.getInstance().getAllKeys(myProject)); - } - - @Override - public void getAllClassNames(@Nonnull HashSet set) { - processAllClassNames(new CommonProcessors.CollectProcessor(set)); - } - - @Override - public boolean processAllClassNames(Processor processor) { - return JavaShortClassNameIndex.getInstance().processAllKeys(myProject, processor); - } - - @Override - public boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.CLASS_SHORT_NAMES, processor, scope, filter); - } - - @Override - public boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.METHODS, processor, scope, filter); - } - - @Override - public boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.FIELDS, processor, scope, filter); - } - - @Override - @Nonnull - public PsiMethod[] getMethodsByName(@Nonnull String name, @Nonnull final GlobalSearchScope scope) { - Collection methods = StubIndex.getElements(JavaStubIndexKeys.METHODS, name, myProject, - new JavaSourceFilterScope(scope), PsiMethod.class); - if (methods.isEmpty()) { - return PsiMethod.EMPTY_ARRAY; + + @Override + public boolean processAllClassNames(Processor processor) { + return JavaShortClassNameIndex.getInstance().processAllKeys(myProject, processor); } - List list = filterMembers(methods, scope); - return list.toArray(new PsiMethod[list.size()]); - } - - - @Override - @Nonnull - public PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @Nonnull final String name, @Nonnull final GlobalSearchScope scope, final int maxCount) { - final List methods = new SmartList(); - StubIndex.getInstance().processElements(JavaStubIndexKeys.METHODS, name, myProject, scope, PsiMethod.class, new CommonProcessors.CollectProcessor(methods) { - @Override - public boolean process(PsiMethod method) { - return methods.size() != maxCount && super.process(method); - } - }); - if (methods.isEmpty()) { - return PsiMethod.EMPTY_ARRAY; + @Override + public boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.CLASS_SHORT_NAMES, processor, scope, filter); } - List list = filterMembers(methods, scope); - return list.toArray(new PsiMethod[list.size()]); - } - - @Override - public boolean processMethodsWithName(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, @Nonnull Processor processor) { - return StubIndex.getInstance().processElements(JavaStubIndexKeys.METHODS, name, myProject, scope, PsiMethod.class, processor); - } - - @Override - @Nonnull - public String[] getAllMethodNames() { - return ArrayUtil.toStringArray(JavaMethodNameIndex.getInstance().getAllKeys(myProject)); - } - - @Override - public void getAllMethodNames(@Nonnull HashSet set) { - JavaMethodNameIndex.getInstance().processAllKeys(myProject, new CommonProcessors.CollectProcessor(set)); - } - - @Override - @Nonnull - public PsiField[] getFieldsByNameIfNotMoreThan(@Nonnull String name, @Nonnull final GlobalSearchScope scope, final int maxCount) { - final List methods = new SmartList(); - StubIndex.getInstance().processElements(JavaStubIndexKeys.FIELDS, name, myProject, scope, PsiField.class, new CommonProcessors.CollectProcessor(methods) { - @Override - public boolean process(PsiField method) { - return methods.size() != maxCount && super.process(method); - } - }); - if (methods.isEmpty()) { - return PsiField.EMPTY_ARRAY; + @Override + public boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.METHODS, processor, scope, filter); } - List list = filterMembers(methods, scope); - return list.toArray(new PsiField[list.size()]); - } + @Override + public boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.FIELDS, processor, scope, filter); + } - @Nonnull - @Override - public PsiField[] getFieldsByName(@Nonnull String name, @Nonnull final GlobalSearchScope scope) { - final Collection fields = JavaFieldNameIndex.getInstance().get(name, myProject, scope); + @Override + @Nonnull + public PsiMethod[] getMethodsByName(@Nonnull String name, @Nonnull final GlobalSearchScope scope) { + Collection methods = StubIndex.getElements(JavaStubIndexKeys.METHODS, name, myProject, + new JavaSourceFilterScope(scope), PsiMethod.class + ); + if (methods.isEmpty()) { + return PsiMethod.EMPTY_ARRAY; + } - if (fields.isEmpty()) { - return PsiField.EMPTY_ARRAY; + List list = filterMembers(methods, scope); + return list.toArray(new PsiMethod[list.size()]); } - List list = filterMembers(fields, scope); - return list.toArray(new PsiField[list.size()]); - } - - @Override - @Nonnull - public String[] getAllFieldNames() { - return ArrayUtil.toStringArray(JavaFieldNameIndex.getInstance().getAllKeys(myProject)); - } - - @Override - public void getAllFieldNames(@Nonnull HashSet set) { - JavaFieldNameIndex.getInstance().processAllKeys(myProject, new CommonProcessors.CollectProcessor(set)); - } - - @Override - public boolean processFieldsWithName(@Nonnull String name, @Nonnull Processor processor, @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter) { - return StubIndex.getInstance().processElements(JavaStubIndexKeys.FIELDS, name, myProject, new JavaSourceFilterScope(scope), filter, PsiField.class, processor); - } - - @Override - public boolean processMethodsWithName(@NonNls @Nonnull String name, @Nonnull Processor processor, @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter) { - return StubIndex.getInstance().processElements(JavaStubIndexKeys.METHODS, name, myProject, new JavaSourceFilterScope(scope), filter, PsiMethod.class, processor); - } - - @Override - public boolean processClassesWithName(@Nonnull String name, @Nonnull Processor processor, @Nonnull GlobalSearchScope scope, - @Nullable IdFilter filter) { - return StubIndex.getInstance().processElements(JavaStubIndexKeys.CLASS_SHORT_NAMES, name, myProject, new JavaSourceFilterScope(scope), filter, PsiClass.class, processor); - } - - private List filterMembers(Collection members, final GlobalSearchScope scope) { - List result = new ArrayList(members.size()); - Set set = Sets.newHashSet(members.size(), new HashingStrategy() { - @Override - public int hashCode(PsiMember member) { - int code = 0; - final PsiClass clazz = member.getContainingClass(); - if (clazz != null) { - String name = clazz.getName(); - if (name != null) { - code += name.hashCode(); - } else { - //anonymous classes are not equivalent - code += clazz.hashCode(); - } + + @Override + @Nonnull + public PsiMethod[] getMethodsByNameIfNotMoreThan( + @NonNls @Nonnull final String name, + @Nonnull final GlobalSearchScope scope, + final int maxCount + ) { + final List methods = new SmartList(); + StubIndex.getInstance().processElements( + JavaStubIndexKeys.METHODS, + name, + myProject, + scope, + PsiMethod.class, + new CommonProcessors.CollectProcessor(methods) { + @Override + public boolean process(PsiMethod method) { + return methods.size() != maxCount && super.process(method); + } + } + ); + if (methods.isEmpty()) { + return PsiMethod.EMPTY_ARRAY; } - if (member instanceof PsiMethod) { - code += 37 * ((PsiMethod) member).getParameterList().getParametersCount(); + + List list = filterMembers(methods, scope); + return list.toArray(new PsiMethod[list.size()]); + } + + @Override + public boolean processMethodsWithName( + @NonNls @Nonnull String name, + @Nonnull GlobalSearchScope scope, + @Nonnull Processor processor + ) { + return StubIndex.getInstance().processElements(JavaStubIndexKeys.METHODS, name, myProject, scope, PsiMethod.class, processor); + } + + @Override + @Nonnull + public String[] getAllMethodNames() { + return ArrayUtil.toStringArray(JavaMethodNameIndex.getInstance().getAllKeys(myProject)); + } + + @Override + public void getAllMethodNames(@Nonnull HashSet set) { + JavaMethodNameIndex.getInstance().processAllKeys(myProject, new CommonProcessors.CollectProcessor(set)); + } + + @Override + @Nonnull + public PsiField[] getFieldsByNameIfNotMoreThan(@Nonnull String name, @Nonnull final GlobalSearchScope scope, final int maxCount) { + final List methods = new SmartList(); + StubIndex.getInstance().processElements( + JavaStubIndexKeys.FIELDS, + name, + myProject, + scope, + PsiField.class, + new CommonProcessors.CollectProcessor(methods) { + @Override + public boolean process(PsiField method) { + return methods.size() != maxCount && super.process(method); + } + } + ); + if (methods.isEmpty()) { + return PsiField.EMPTY_ARRAY; } - return code; - } - - @Override - public boolean equals(PsiMember object, PsiMember object1) { - return PsiManager.getInstance(myProject).areElementsEquivalent(object, object1); - } - }); - - for (T member : members) { - ProgressIndicatorProvider.checkCanceled(); - - if (!scope.contains(member.getContainingFile().getVirtualFile())) { - continue; - } - if (!set.add(member)) { - continue; - } - result.add(member); + + List list = filterMembers(methods, scope); + return list.toArray(new PsiField[list.size()]); } - return result; - } + @Nonnull + @Override + public PsiField[] getFieldsByName(@Nonnull String name, @Nonnull final GlobalSearchScope scope) { + final Collection fields = JavaFieldNameIndex.getInstance().get(name, myProject, scope); + + if (fields.isEmpty()) { + return PsiField.EMPTY_ARRAY; + } + + List list = filterMembers(fields, scope); + return list.toArray(new PsiField[list.size()]); + } + + @Override + @Nonnull + public String[] getAllFieldNames() { + return ArrayUtil.toStringArray(JavaFieldNameIndex.getInstance().getAllKeys(myProject)); + } + + @Override + public void getAllFieldNames(@Nonnull HashSet set) { + JavaFieldNameIndex.getInstance().processAllKeys(myProject, new CommonProcessors.CollectProcessor(set)); + } + + @Override + public boolean processFieldsWithName( + @Nonnull String name, + @Nonnull Processor processor, + @Nonnull GlobalSearchScope scope, + @Nullable IdFilter filter + ) { + return StubIndex.getInstance().processElements( + JavaStubIndexKeys.FIELDS, + name, + myProject, + new JavaSourceFilterScope(scope), + filter, + PsiField.class, + processor + ); + } + + @Override + public boolean processMethodsWithName( + @NonNls @Nonnull String name, + @Nonnull Processor processor, + @Nonnull GlobalSearchScope scope, + @Nullable IdFilter filter + ) { + return StubIndex.getInstance() + .processElements( + JavaStubIndexKeys.METHODS, + name, + myProject, + new JavaSourceFilterScope(scope), + filter, + PsiMethod.class, + processor + ); + } + + @Override + public boolean processClassesWithName( + @Nonnull String name, + @Nonnull Processor processor, + @Nonnull GlobalSearchScope scope, + @Nullable IdFilter filter + ) { + return StubIndex.getInstance().processElements( + JavaStubIndexKeys.CLASS_SHORT_NAMES, + name, + myProject, + new JavaSourceFilterScope(scope), + filter, + PsiClass.class, + processor + ); + } + + private List filterMembers(Collection members, final GlobalSearchScope scope) { + List result = new ArrayList(members.size()); + Set set = Sets.newHashSet(members.size(), new HashingStrategy() { + @Override + public int hashCode(PsiMember member) { + int code = 0; + final PsiClass clazz = member.getContainingClass(); + if (clazz != null) { + String name = clazz.getName(); + if (name != null) { + code += name.hashCode(); + } + else { + //anonymous classes are not equivalent + code += clazz.hashCode(); + } + } + if (member instanceof PsiMethod) { + code += 37 * ((PsiMethod)member).getParameterList().getParametersCount(); + } + return code; + } + + @Override + public boolean equals(PsiMember object, PsiMember object1) { + return PsiManager.getInstance(myProject).areElementsEquivalent(object, object1); + } + }); + + for (T member : members) { + ProgressIndicatorProvider.checkCanceled(); + + if (!scope.contains(member.getContainingFile().getVirtualFile())) { + continue; + } + if (!set.add(member)) { + continue; + } + result.add(member); + } + + return result; + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AllClassesSearchExecutor.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AllClassesSearchExecutor.java index 89a55aa75..2cb95cb49 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AllClassesSearchExecutor.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AllClassesSearchExecutor.java @@ -40,126 +40,142 @@ import consulo.project.Project; import jakarta.annotation.Nonnull; + import java.util.*; @ExtensionImpl public class AllClassesSearchExecutor implements com.intellij.java.indexing.search.searches.AllClassesSearchExecutor { - @Override - public boolean execute(@Nonnull final AllClassesSearch.SearchParameters queryParameters, @Nonnull final Processor consumer) { - SearchScope scope = queryParameters.getScope(); + @Override + public boolean execute( + @Nonnull final AllClassesSearch.SearchParameters queryParameters, + @Nonnull final Processor consumer + ) { + SearchScope scope = queryParameters.getScope(); + + if (scope instanceof GlobalSearchScope) { + return processAllClassesInGlobalScope((GlobalSearchScope)scope, queryParameters, consumer); + } - if (scope instanceof GlobalSearchScope) { - return processAllClassesInGlobalScope((GlobalSearchScope) scope, queryParameters, consumer); + PsiElement[] scopeRoots = ((LocalSearchScope)scope).getScope(); + for (final PsiElement scopeRoot : scopeRoots) { + if (!processScopeRootForAllClasses(scopeRoot, consumer)) { + return false; + } + } + return true; } - PsiElement[] scopeRoots = ((LocalSearchScope) scope).getScope(); - for (final PsiElement scopeRoot : scopeRoots) { - if (!processScopeRootForAllClasses(scopeRoot, consumer)) { - return false; - } + private static boolean processAllClassesInGlobalScope( + @Nonnull final GlobalSearchScope scope, + @Nonnull final AllClassesSearch.SearchParameters parameters, + @Nonnull Processor processor + ) { + final Set names = new HashSet(10000); + processClassNames(parameters.getProject(), scope, s -> { + if (parameters.nameMatches(s)) { + names.add(s); + } + return true; + }); + + List sorted = new ArrayList(names); + Collections.sort(sorted, String.CASE_INSENSITIVE_ORDER); + + return processClassesByNames(parameters.getProject(), scope, sorted, processor); } - return true; - } - - private static boolean processAllClassesInGlobalScope(@Nonnull final GlobalSearchScope scope, @Nonnull final AllClassesSearch.SearchParameters parameters, @Nonnull Processor processor) { - final Set names = new HashSet(10000); - processClassNames(parameters.getProject(), scope, s -> { - if (parameters.nameMatches(s)) { - names.add(s); - } - return true; - }); - - List sorted = new ArrayList(names); - Collections.sort(sorted, String.CASE_INSENSITIVE_ORDER); - - return processClassesByNames(parameters.getProject(), scope, sorted, processor); - } - - public static boolean processClassesByNames(Project project, final GlobalSearchScope scope, Collection names, Processor processor) { - final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project); - for (final String name : names) { - ProgressIndicatorProvider.checkCanceled(); - final PsiClass[] classes = MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public PsiClass[] compute() { - return cache.getClassesByName(name, scope); - } - }); - for (PsiClass psiClass : classes) { - ProgressIndicatorProvider.checkCanceled(); - if (!processor.process(psiClass)) { - return false; + + public static boolean processClassesByNames( + Project project, + final GlobalSearchScope scope, + Collection names, + Processor processor + ) { + final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project); + for (final String name : names) { + ProgressIndicatorProvider.checkCanceled(); + final PsiClass[] classes = MethodUsagesSearcher.resolveInReadAction(project, new Computable() { + @Override + public PsiClass[] compute() { + return cache.getClassesByName(name, scope); + } + }); + for (PsiClass psiClass : classes) { + ProgressIndicatorProvider.checkCanceled(); + if (!processor.process(psiClass)) { + return false; + } + } } - } + return true; } - return true; - } - - public static Project processClassNames(final Project project, final GlobalSearchScope scope, final Processor consumer) { - final ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); - - MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public Void compute() { - PsiShortNamesCache.getInstance(project).processAllClassNames(new Processor() { - int i = 0; - - @Override - public boolean process(String s) { - if (indicator != null && i++ % 512 == 0) { - indicator.checkCanceled(); + + public static Project processClassNames(final Project project, final GlobalSearchScope scope, final Processor consumer) { + final ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); + + MethodUsagesSearcher.resolveInReadAction(project, new Computable() { + @Override + public Void compute() { + PsiShortNamesCache.getInstance(project).processAllClassNames(new Processor() { + int i = 0; + + @Override + public boolean process(String s) { + if (indicator != null && i++ % 512 == 0) { + indicator.checkCanceled(); + } + return consumer.process(s); + } + }, scope, IdFilter.getProjectIdFilter(project, true)); + return null; } - return consumer.process(s); - } - }, scope, IdFilter.getProjectIdFilter(project, true)); - return null; - } - }); - - if (indicator != null) { - indicator.checkCanceled(); + }); + + if (indicator != null) { + indicator.checkCanceled(); + } + return project; } - return project; - } - private static boolean processScopeRootForAllClasses(@Nonnull final PsiElement scopeRoot, @Nonnull final Processor processor) { - final boolean[] stopped = {false}; + private static boolean processScopeRootForAllClasses( + @Nonnull final PsiElement scopeRoot, + @Nonnull final Processor processor + ) { + final boolean[] stopped = {false}; + + final JavaElementVisitor visitor = scopeRoot instanceof PsiCompiledElement ? new JavaRecursiveElementVisitor() { + @Override + public void visitElement(PsiElement element) { + if (!stopped[0]) { + super.visitElement(element); + } + } - final JavaElementVisitor visitor = scopeRoot instanceof PsiCompiledElement ? new JavaRecursiveElementVisitor() { - @Override - public void visitElement(PsiElement element) { - if (!stopped[0]) { - super.visitElement(element); - } - } - - @Override - public void visitClass(PsiClass aClass) { - stopped[0] = !processor.process(aClass); - super.visitClass(aClass); - } - } : new JavaRecursiveElementWalkingVisitor() { - @Override - public void visitElement(PsiElement element) { - if (!stopped[0]) { - super.visitElement(element); - } - } - - @Override - public void visitClass(PsiClass aClass) { - stopped[0] = !processor.process(aClass); - super.visitClass(aClass); - } - }; - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - scopeRoot.accept(visitor); - } - }); - - return !stopped[0]; - } + @Override + public void visitClass(PsiClass aClass) { + stopped[0] = !processor.process(aClass); + super.visitClass(aClass); + } + } : new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitElement(PsiElement element) { + if (!stopped[0]) { + super.visitElement(element); + } + } + + @Override + public void visitClass(PsiClass aClass) { + stopped[0] = !processor.process(aClass); + super.visitClass(aClass); + } + }; + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + scopeRoot.accept(visitor); + } + }); + + return !stopped[0]; + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AnnotatedElementsSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AnnotatedElementsSearcher.java index 01f46e5a7..6b3dddc98 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AnnotatedElementsSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AnnotatedElementsSearcher.java @@ -32,6 +32,7 @@ import consulo.util.collection.ContainerUtil; import jakarta.annotation.Nonnull; + import java.util.Collection; import java.util.List; @@ -40,84 +41,88 @@ */ @ExtensionImpl public class AnnotatedElementsSearcher implements AnnotatedElementsSearchExecutor { - @Override - public boolean execute(@Nonnull final AnnotatedElementsSearch.Parameters p, @Nonnull final Processor consumer) { - final PsiClass annClass = p.getAnnotationClass(); - assert annClass.isAnnotationType() : "Annotation type should be passed to annotated members search"; - - final String annotationFQN = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - return annClass.getQualifiedName(); - } - }); - assert annotationFQN != null; - - final PsiManager psiManager = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiManager compute() { - return annClass.getManager(); - } - }); - - final SearchScope useScope = p.getScope(); - final Class[] types = p.getTypes(); - - for (final PsiAnnotation ann : getAnnotationCandidates(annClass, useScope)) { - final PsiModifierListOwner candidate = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiModifierListOwner compute() { - PsiElement parent = ann.getParent(); - if (!(parent instanceof PsiModifierList)) { - return null; // Can be a PsiNameValuePair, if annotation is used to annotate annotation parameters - } - - final PsiElement owner = parent.getParent(); - if (!isInstanceof(owner, types)) { - return null; - } - - final PsiJavaCodeReferenceElement ref = ann.getNameReferenceElement(); - if (ref == null || !psiManager.areElementsEquivalent(ref.resolve(), annClass)) { - return null; - } - - return (PsiModifierListOwner) owner; + @Override + public boolean execute( + @Nonnull final AnnotatedElementsSearch.Parameters p, + @Nonnull final Processor consumer + ) { + final PsiClass annClass = p.getAnnotationClass(); + assert annClass.isAnnotationType() : "Annotation type should be passed to annotated members search"; + + final String annotationFQN = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public String compute() { + return annClass.getQualifiedName(); + } + }); + assert annotationFQN != null; + + final PsiManager psiManager = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiManager compute() { + return annClass.getManager(); + } + }); + + final SearchScope useScope = p.getScope(); + final Class[] types = p.getTypes(); + + for (final PsiAnnotation ann : getAnnotationCandidates(annClass, useScope)) { + final PsiModifierListOwner candidate = + ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiModifierListOwner compute() { + PsiElement parent = ann.getParent(); + if (!(parent instanceof PsiModifierList)) { + return null; // Can be a PsiNameValuePair, if annotation is used to annotate annotation parameters + } + + final PsiElement owner = parent.getParent(); + if (!isInstanceof(owner, types)) { + return null; + } + + final PsiJavaCodeReferenceElement ref = ann.getNameReferenceElement(); + if (ref == null || !psiManager.areElementsEquivalent(ref.resolve(), annClass)) { + return null; + } + + return (PsiModifierListOwner)owner; + } + }); + + if (candidate != null && !consumer.process(candidate)) { + return false; + } } - }); - if (candidate != null && !consumer.process(candidate)) { - return false; - } + return true; } - return true; - } - - private static Collection getAnnotationCandidates(final PsiClass annClass, final SearchScope useScope) { - return ApplicationManager.getApplication().runReadAction(new Computable>() { - @Override - public Collection compute() { - if (useScope instanceof GlobalSearchScope) { - return JavaAnnotationIndex.getInstance().get(annClass.getName(), annClass.getProject(), (GlobalSearchScope) useScope); - } + private static Collection getAnnotationCandidates(final PsiClass annClass, final SearchScope useScope) { + return ApplicationManager.getApplication().runReadAction(new Computable>() { + @Override + public Collection compute() { + if (useScope instanceof GlobalSearchScope) { + return JavaAnnotationIndex.getInstance().get(annClass.getName(), annClass.getProject(), (GlobalSearchScope)useScope); + } + + final List result = ContainerUtil.newArrayList(); + for (PsiElement element : ((LocalSearchScope)useScope).getScope()) { + result.addAll(PsiTreeUtil.findChildrenOfType(element, PsiAnnotation.class)); + } + return result; + } + }); + } - final List result = ContainerUtil.newArrayList(); - for (PsiElement element : ((LocalSearchScope) useScope).getScope()) { - result.addAll(PsiTreeUtil.findChildrenOfType(element, PsiAnnotation.class)); + public static boolean isInstanceof(PsiElement owner, Class[] types) { + for (Class type : types) { + if (type.isInstance(owner)) { + return true; + } } - return result; - } - }); - } - - public static boolean isInstanceof(PsiElement owner, Class[] types) { - for (Class type : types) { - if (type.isInstance(owner)) { - return true; - } + return false; } - return false; - } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ClassesWithAnnotatedMembersSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ClassesWithAnnotatedMembersSearcher.java index d6927d90d..2fb1ab7e3 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ClassesWithAnnotatedMembersSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ClassesWithAnnotatedMembersSearcher.java @@ -30,6 +30,7 @@ import consulo.project.util.query.QueryExecutorBase; import jakarta.annotation.Nonnull; + import java.util.HashSet; import java.util.Set; @@ -37,26 +38,30 @@ * @author yole */ @ExtensionImpl -public class ClassesWithAnnotatedMembersSearcher extends QueryExecutorBase implements ClassesWithAnnotatedMembersSearchExecutor { - @Override - public void processQuery(@Nonnull ClassesWithAnnotatedMembersSearch.Parameters queryParameters, @Nonnull final Processor consumer) { - SearchScope scope = queryParameters.getScope(); - for (QueryExecutor executor : Application.get().getExtensionList(ClassesWithAnnotatedMembersSearchExecutor.class)) { - if (executor instanceof ScopedQueryExecutor) { - scope = scope.intersectWith(GlobalSearchScope.notScope(((ScopedQueryExecutor) executor).getScope(queryParameters))); - } - } +public class ClassesWithAnnotatedMembersSearcher extends QueryExecutorBase + implements ClassesWithAnnotatedMembersSearchExecutor { + @Override + public void processQuery( + @Nonnull ClassesWithAnnotatedMembersSearch.Parameters queryParameters, + @Nonnull final Processor consumer + ) { + SearchScope scope = queryParameters.getScope(); + for (QueryExecutor executor : Application.get().getExtensionList(ClassesWithAnnotatedMembersSearchExecutor.class)) { + if (executor instanceof ScopedQueryExecutor) { + scope = scope.intersectWith(GlobalSearchScope.notScope(((ScopedQueryExecutor)executor).getScope(queryParameters))); + } + } - final Set processed = new HashSet<>(); - AnnotatedElementsSearch.searchPsiMembers(queryParameters.getAnnotationClass(), scope).forEach(member -> - { - PsiClass psiClass = ReadAction.compute(() -> member instanceof PsiClass ? (PsiClass) member : member.getContainingClass()); + final Set processed = new HashSet<>(); + AnnotatedElementsSearch.searchPsiMembers(queryParameters.getAnnotationClass(), scope).forEach(member -> + { + PsiClass psiClass = ReadAction.compute(() -> member instanceof PsiClass ? (PsiClass)member : member.getContainingClass()); - if (psiClass != null && processed.add(psiClass)) { - consumer.process(psiClass); - } + if (psiClass != null && processed.add(psiClass)) { + consumer.process(psiClass); + } - return true; - }); - } + return true; + }); + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearchHelper.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearchHelper.java index 49f413440..1f7a8662f 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearchHelper.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearchHelper.java @@ -44,262 +44,297 @@ * @author max */ public class ConstructorReferencesSearchHelper { - private final PsiManager myManager; + private final PsiManager myManager; - public ConstructorReferencesSearchHelper(@Nonnull PsiManager manager) { - myManager = manager; - } - - /* - * Project is passed around explicitly to avoid invoking PsiElement.getProject each time we need it. There are two reasons: - * 1. Performance. getProject traverses AST upwards - * 2. Exception avoidance. Project is needed outside of read action (to run it via DumbService in the first place), - * and so getProject would fail with an assertion that read action is required but not present. - */ - public boolean processConstructorReferences(@Nonnull final Processor processor, - @Nonnull final PsiMethod constructor, - @Nonnull final PsiClass containingClass, - @Nonnull final SearchScope searchScope, - @Nonnull final Project project, - boolean ignoreAccessScope, - final boolean isStrictSignatureSearch, - @Nonnull SearchRequestCollector collector) { - final boolean[] constructorCanBeCalledImplicitly = new boolean[1]; - final boolean[] isEnum = new boolean[1]; - final boolean[] isUnder18 = new boolean[1]; + public ConstructorReferencesSearchHelper(@Nonnull PsiManager manager) { + myManager = manager; + } - MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public Void compute() { - constructorCanBeCalledImplicitly[0] = constructor.getParameterList().getParametersCount() == 0; - isEnum[0] = containingClass.isEnum(); - isUnder18[0] = PsiUtil.getLanguageLevel(containingClass).isAtLeast(LanguageLevel.JDK_1_8); - return null; - } - }); + /* + * Project is passed around explicitly to avoid invoking PsiElement.getProject each time we need it. There are two reasons: + * 1. Performance. getProject traverses AST upwards + * 2. Exception avoidance. Project is needed outside of read action (to run it via DumbService in the first place), + * and so getProject would fail with an assertion that read action is required but not present. + */ + public boolean processConstructorReferences( + @Nonnull final Processor processor, + @Nonnull final PsiMethod constructor, + @Nonnull final PsiClass containingClass, + @Nonnull final SearchScope searchScope, + @Nonnull final Project project, + boolean ignoreAccessScope, + final boolean isStrictSignatureSearch, + @Nonnull SearchRequestCollector collector + ) { + final boolean[] constructorCanBeCalledImplicitly = new boolean[1]; + final boolean[] isEnum = new boolean[1]; + final boolean[] isUnder18 = new boolean[1]; - if (isEnum[0]) { - if (!processEnumReferences(processor, constructor, project, containingClass)) { - return false; - } - } + MethodUsagesSearcher.resolveInReadAction(project, new Computable() { + @Override + public Void compute() { + constructorCanBeCalledImplicitly[0] = constructor.getParameterList().getParametersCount() == 0; + isEnum[0] = containingClass.isEnum(); + isUnder18[0] = PsiUtil.getLanguageLevel(containingClass).isAtLeast(LanguageLevel.JDK_1_8); + return null; + } + }); - // search usages like "new XXX(..)" - PairProcessor processor1 = new PairProcessor() { - @Override - public boolean process(PsiReference reference, SearchRequestCollector collector) { - PsiElement parent = reference.getElement().getParent(); - if (parent instanceof PsiAnonymousClass) { - parent = parent.getParent(); - } - if (parent instanceof PsiNewExpression) { - PsiMethod constructor1 = ((PsiNewExpression) parent).resolveConstructor(); - if (constructor1 != null) { - if (isStrictSignatureSearch) { - if (myManager.areElementsEquivalent(constructor, constructor1)) { - return processor.process(reference); - } - } else { - if (myManager.areElementsEquivalent(containingClass, constructor1.getContainingClass())) { - return processor.process(reference); - } + if (isEnum[0]) { + if (!processEnumReferences(processor, constructor, project, containingClass)) { + return false; } - } } - return true; - } - }; - ReferencesSearch.searchOptimized(containingClass, searchScope, ignoreAccessScope, collector, true, processor1); - if (isUnder18[0]) { - if (!process18MethodPointers(processor, constructor, project, containingClass, searchScope)) { - return false; - } - } - - // search usages like "this(..)" - if (!MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public Boolean compute() { - return processSuperOrThis(containingClass, constructor, constructorCanBeCalledImplicitly[0], searchScope, project, isStrictSignatureSearch, PsiKeyword.THIS, processor); - } - })) { - return false; - } + // search usages like "new XXX(..)" + PairProcessor processor1 = new PairProcessor() { + @Override + public boolean process(PsiReference reference, SearchRequestCollector collector) { + PsiElement parent = reference.getElement().getParent(); + if (parent instanceof PsiAnonymousClass) { + parent = parent.getParent(); + } + if (parent instanceof PsiNewExpression) { + PsiMethod constructor1 = ((PsiNewExpression)parent).resolveConstructor(); + if (constructor1 != null) { + if (isStrictSignatureSearch) { + if (myManager.areElementsEquivalent(constructor, constructor1)) { + return processor.process(reference); + } + } + else { + if (myManager.areElementsEquivalent(containingClass, constructor1.getContainingClass())) { + return processor.process(reference); + } + } + } + } + return true; + } + }; - // search usages like "super(..)" - Processor processor2 = new Processor() { - @Override - public boolean process(PsiClass inheritor) { - final PsiElement navigationElement = inheritor.getNavigationElement(); - if (navigationElement instanceof PsiClass) { - return processSuperOrThis((PsiClass) navigationElement, constructor, constructorCanBeCalledImplicitly[0], searchScope, project, isStrictSignatureSearch, PsiKeyword.SUPER, - processor); + ReferencesSearch.searchOptimized(containingClass, searchScope, ignoreAccessScope, collector, true, processor1); + if (isUnder18[0]) { + if (!process18MethodPointers(processor, constructor, project, containingClass, searchScope)) { + return false; + } } - return true; - } - }; - return ClassInheritorsSearch.search(containingClass, searchScope, false).forEach(processor2); - } - - private static boolean processEnumReferences(@Nonnull final Processor processor, @Nonnull final PsiMethod constructor, @Nonnull final Project project, - @Nonnull final PsiClass aClass) { - return MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public Boolean compute() { - for (PsiField field : aClass.getFields()) { - if (field instanceof PsiEnumConstant) { - PsiReference reference = field.getReference(); - if (reference != null && reference.isReferenceTo(constructor)) { - if (!processor.process(reference)) { - return false; - } + // search usages like "this(..)" + if (!MethodUsagesSearcher.resolveInReadAction(project, new Computable() { + @Override + public Boolean compute() { + return processSuperOrThis( + containingClass, + constructor, + constructorCanBeCalledImplicitly[0], + searchScope, + project, + isStrictSignatureSearch, + PsiKeyword.THIS, + processor + ); } - } + })) { + return false; } - return true; - } - }); - } - private static boolean process18MethodPointers(@Nonnull final Processor processor, - @Nonnull final PsiMethod constructor, - @Nonnull final Project project, - @Nonnull PsiClass aClass, - SearchScope searchScope) { - return ReferencesSearch.search(aClass, searchScope).forEach(new Processor() { - @Override - public boolean process(PsiReference reference) { - final PsiElement element = reference.getElement(); - if (element != null) { - return MethodUsagesSearcher.resolveInReadAction(project, new Computable() { + // search usages like "super(..)" + Processor processor2 = new Processor() { + @Override + public boolean process(PsiClass inheritor) { + final PsiElement navigationElement = inheritor.getNavigationElement(); + if (navigationElement instanceof PsiClass) { + return processSuperOrThis( + (PsiClass)navigationElement, + constructor, + constructorCanBeCalledImplicitly[0], + searchScope, + project, + isStrictSignatureSearch, + PsiKeyword.SUPER, + processor + ); + } + return true; + } + }; + + return ClassInheritorsSearch.search(containingClass, searchScope, false).forEach(processor2); + } + + private static boolean processEnumReferences( + @Nonnull final Processor processor, + @Nonnull final PsiMethod constructor, + @Nonnull final Project project, + @Nonnull final PsiClass aClass + ) { + return MethodUsagesSearcher.resolveInReadAction(project, new Computable() { @Override public Boolean compute() { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiMethodReferenceExpression && ((PsiMethodReferenceExpression) parent).getReferenceNameElement() instanceof PsiKeyword) { - if (((PsiMethodReferenceExpression) parent).isReferenceTo(constructor)) { - if (!processor.process((PsiReference) parent)) { - return false; - } + for (PsiField field : aClass.getFields()) { + if (field instanceof PsiEnumConstant) { + PsiReference reference = field.getReference(); + if (reference != null && reference.isReferenceTo(constructor)) { + if (!processor.process(reference)) { + return false; + } + } + } } - } - return true; + return true; } - }); - } - return true; - } - }); - } + }); + } - private boolean processSuperOrThis(@Nonnull PsiClass inheritor, - @Nonnull PsiMethod constructor, - final boolean constructorCanBeCalledImplicitly, - @Nonnull SearchScope searchScope, - @Nonnull Project project, - final boolean isStrictSignatureSearch, - @Nonnull String superOrThisKeyword, - @Nonnull Processor processor) { - PsiMethod[] constructors = inheritor.getConstructors(); - if (constructors.length == 0 && constructorCanBeCalledImplicitly) { - if (!processImplicitConstructorCall(inheritor, processor, constructor, project, inheritor)) { - return false; - } + private static boolean process18MethodPointers( + @Nonnull final Processor processor, + @Nonnull final PsiMethod constructor, + @Nonnull final Project project, + @Nonnull PsiClass aClass, + SearchScope searchScope + ) { + return ReferencesSearch.search(aClass, searchScope).forEach(new Processor() { + @Override + public boolean process(PsiReference reference) { + final PsiElement element = reference.getElement(); + if (element != null) { + return MethodUsagesSearcher.resolveInReadAction(project, new Computable() { + @Override + public Boolean compute() { + final PsiElement parent = element.getParent(); + if (parent instanceof PsiMethodReferenceExpression && ((PsiMethodReferenceExpression)parent).getReferenceNameElement() instanceof PsiKeyword) { + if (((PsiMethodReferenceExpression)parent).isReferenceTo(constructor)) { + if (!processor.process((PsiReference)parent)) { + return false; + } + } + } + return true; + } + }); + } + return true; + } + }); } - for (PsiMethod method : constructors) { - PsiCodeBlock body = method.getBody(); - if (body == null || method == constructor && isStrictSignatureSearch) { - continue; - } - PsiStatement[] statements = body.getStatements(); - if (statements.length != 0) { - PsiStatement statement = statements[0]; - if (statement instanceof PsiExpressionStatement) { - PsiExpression expr = ((PsiExpressionStatement) statement).getExpression(); - if (expr instanceof PsiMethodCallExpression) { - PsiReferenceExpression refExpr = ((PsiMethodCallExpression) expr).getMethodExpression(); - if (PsiSearchScopeUtil.isInScope(searchScope, refExpr)) { - if (refExpr.textMatches(superOrThisKeyword)) { - PsiElement referencedElement = refExpr.resolve(); - if (referencedElement instanceof PsiMethod) { - PsiMethod constructor1 = (PsiMethod) referencedElement; - boolean match = isStrictSignatureSearch ? myManager.areElementsEquivalent(constructor1, constructor) : myManager.areElementsEquivalent(constructor - .getContainingClass(), constructor1.getContainingClass()); - if (match && !processor.process(refExpr)) { + + private boolean processSuperOrThis( + @Nonnull PsiClass inheritor, + @Nonnull PsiMethod constructor, + final boolean constructorCanBeCalledImplicitly, + @Nonnull SearchScope searchScope, + @Nonnull Project project, + final boolean isStrictSignatureSearch, + @Nonnull String superOrThisKeyword, + @Nonnull Processor processor + ) { + PsiMethod[] constructors = inheritor.getConstructors(); + if (constructors.length == 0 && constructorCanBeCalledImplicitly) { + if (!processImplicitConstructorCall(inheritor, processor, constructor, project, inheritor)) { + return false; + } + } + for (PsiMethod method : constructors) { + PsiCodeBlock body = method.getBody(); + if (body == null || method == constructor && isStrictSignatureSearch) { + continue; + } + PsiStatement[] statements = body.getStatements(); + if (statements.length != 0) { + PsiStatement statement = statements[0]; + if (statement instanceof PsiExpressionStatement) { + PsiExpression expr = ((PsiExpressionStatement)statement).getExpression(); + if (expr instanceof PsiMethodCallExpression) { + PsiReferenceExpression refExpr = ((PsiMethodCallExpression)expr).getMethodExpression(); + if (PsiSearchScopeUtil.isInScope(searchScope, refExpr)) { + if (refExpr.textMatches(superOrThisKeyword)) { + PsiElement referencedElement = refExpr.resolve(); + if (referencedElement instanceof PsiMethod) { + PsiMethod constructor1 = (PsiMethod)referencedElement; + boolean match = isStrictSignatureSearch + ? myManager.areElementsEquivalent(constructor1, constructor) + : myManager.areElementsEquivalent( + constructor.getContainingClass(), + constructor1.getContainingClass() + ); + if (match && !processor.process(refExpr)) { + return false; + } + } + //as long as we've encountered super/this keyword, no implicit ctr calls are possible here + continue; + } + } + } + } + } + if (constructorCanBeCalledImplicitly) { + if (!processImplicitConstructorCall(method, processor, constructor, project, inheritor)) { return false; - } } - //as long as we've encountered super/this keyword, no implicit ctr calls are possible here - continue; - } } - } - } - } - if (constructorCanBeCalledImplicitly) { - if (!processImplicitConstructorCall(method, processor, constructor, project, inheritor)) { - return false; } - } - } - - return true; - } - private boolean processImplicitConstructorCall(@Nonnull final PsiMember usage, - @Nonnull final Processor processor, - @Nonnull final PsiMethod constructor, - @Nonnull final Project project, - @Nonnull final PsiClass containingClass) { - if (containingClass instanceof PsiAnonymousClass) { - return true; + return true; } - PsiClass ctrClass = constructor.getContainingClass(); - if (ctrClass == null) { - return true; - } + private boolean processImplicitConstructorCall( + @Nonnull final PsiMember usage, + @Nonnull final Processor processor, + @Nonnull final PsiMethod constructor, + @Nonnull final Project project, + @Nonnull final PsiClass containingClass + ) { + if (containingClass instanceof PsiAnonymousClass) { + return true; + } - boolean isImplicitSuper = DumbService.getInstance(project).runReadActionInSmartMode( - () -> myManager.areElementsEquivalent(ctrClass, containingClass.getSuperClass())); - if (!isImplicitSuper) { - return true; - } + PsiClass ctrClass = constructor.getContainingClass(); + if (ctrClass == null) { + return true; + } - PsiElement resolved = JavaResolveUtil.resolveImaginarySuperCallInThisPlace(usage, project, ctrClass); + boolean isImplicitSuper = DumbService.getInstance(project).runReadActionInSmartMode( + () -> myManager.areElementsEquivalent(ctrClass, containingClass.getSuperClass())); + if (!isImplicitSuper) { + return true; + } - boolean resolvesToThisConstructor = DumbService.getInstance(project).runReadActionInSmartMode( - () -> myManager.areElementsEquivalent(constructor, resolved)); + PsiElement resolved = JavaResolveUtil.resolveImaginarySuperCallInThisPlace(usage, project, ctrClass); - if (!resolvesToThisConstructor) { - return true; - } + boolean resolvesToThisConstructor = DumbService.getInstance(project).runReadActionInSmartMode( + () -> myManager.areElementsEquivalent(constructor, resolved)); - return processor.process(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) { - @Nonnull - @Override - public PsiElement getElement() { - return usage; - } + if (!resolvesToThisConstructor) { + return true; + } - @Nonnull - @Override - @RequiredReadAction - public TextRange getRangeInElement() { - if (usage instanceof PsiNameIdentifierOwner) { - PsiElement identifier = ((PsiNameIdentifierOwner) usage).getNameIdentifier(); - if (identifier != null) { - final int startOffsetInParent = identifier.getStartOffsetInParent(); - if (startOffsetInParent >= 0) { // -1 for light elements generated e.g. by lombok - return TextRange.from(startOffsetInParent, identifier.getTextLength()); - } else { - return new UnfairTextRange(-1, -1); + return processor.process(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) { + @Nonnull + @Override + public PsiElement getElement() { + return usage; } - } - } - return super.getRangeInElement(); - } - }); - } + + @Nonnull + @Override + @RequiredReadAction + public TextRange getRangeInElement() { + if (usage instanceof PsiNameIdentifierOwner) { + PsiElement identifier = ((PsiNameIdentifierOwner)usage).getNameIdentifier(); + if (identifier != null) { + final int startOffsetInParent = identifier.getStartOffsetInParent(); + if (startOffsetInParent >= 0) { // -1 for light elements generated e.g. by lombok + return TextRange.from(startOffsetInParent, identifier.getTextLength()); + } + else { + return new UnfairTextRange(-1, -1); + } + } + } + return super.getRangeInElement(); + } + }); + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearcher.java index 5b90ebdfd..00d1ba499 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearcher.java @@ -20,41 +20,43 @@ */ @ExtensionImpl public class ConstructorReferencesSearcher extends QueryExecutorBase implements ReferencesSearchQueryExecutor { - @Override - public void processQuery(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull Processor consumer) { - final PsiElement element = p.getElementToSearch(); - if (!(element instanceof PsiMethod)) { - return; - } - final PsiMethod method = (PsiMethod)element; - final PsiManager[] manager = new PsiManager[1]; - PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiClass compute() { - if (!method.isConstructor()) { - return null; + @Override + public void processQuery(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull Processor consumer) { + final PsiElement element = p.getElementToSearch(); + if (!(element instanceof PsiMethod)) { + return; + } + final PsiMethod method = (PsiMethod)element; + final PsiManager[] manager = new PsiManager[1]; + PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiClass compute() { + if (!method.isConstructor()) { + return null; + } + PsiClass aClass = method.getContainingClass(); + manager[0] = aClass == null ? null : aClass.getManager(); + return aClass; + } + }); + if (manager[0] == null) { + return; } - PsiClass aClass = method.getContainingClass(); - manager[0] = aClass == null ? null : aClass.getManager(); - return aClass; - } - }); - if (manager[0] == null) { - return; + SearchScope scope = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public SearchScope compute() { + return p.getEffectiveSearchScope(); + } + }); + new ConstructorReferencesSearchHelper(manager[0]).processConstructorReferences( + consumer, + method, + aClass, + scope, + p.getProject(), + p.isIgnoreAccessScope(), + true, + p.getOptimizer() + ); } - SearchScope scope = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public SearchScope compute() { - return p.getEffectiveSearchScope(); - } - }); - new ConstructorReferencesSearchHelper(manager[0]).processConstructorReferences(consumer, - method, - aClass, - scope, - p.getProject(), - p.isIgnoreAccessScope(), - true, - p.getOptimizer()); - } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaAllOverridingMethodsSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaAllOverridingMethodsSearcher.java index a1c43af2c..948715097 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaAllOverridingMethodsSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaAllOverridingMethodsSearcher.java @@ -38,78 +38,81 @@ */ @ExtensionImpl public class JavaAllOverridingMethodsSearcher implements AllOverridingMethodsSearchExecutor { - @Override - public boolean execute(@Nonnull final AllOverridingMethodsSearch.SearchParameters p, - @Nonnull final Processor> consumer) { - final PsiClass psiClass = p.getPsiClass(); + @Override + public boolean execute( + @Nonnull final AllOverridingMethodsSearch.SearchParameters p, + @Nonnull final Processor> consumer + ) { + final PsiClass psiClass = p.getPsiClass(); - final MultiMap methods = - ApplicationManager.getApplication().runReadAction(new Computable>() { - @Override - public MultiMap compute() { - final MultiMap methods = MultiMap.create(); - for (PsiMethod method : psiClass.getMethods()) { - if (PsiUtil.canBeOverriden(method)) { - methods.putValue(method.getName(), method); - } - } - return methods; - } - }); + final MultiMap methods = + ApplicationManager.getApplication().runReadAction(new Computable>() { + @Override + public MultiMap compute() { + final MultiMap methods = MultiMap.create(); + for (PsiMethod method : psiClass.getMethods()) { + if (PsiUtil.canBeOverriden(method)) { + methods.putValue(method.getName(), method); + } + } + return methods; + } + }); - final SearchScope scope = p.getScope(); + final SearchScope scope = p.getScope(); - Processor inheritorsProcessor = new Processor() { - @Override - public boolean process(PsiClass inheritor) { - PsiSubstitutor substitutor = null; + Processor inheritorsProcessor = new Processor() { + @Override + public boolean process(PsiClass inheritor) { + PsiSubstitutor substitutor = null; - for (String name : methods.keySet()) { - if (inheritor.findMethodsByName(name, true).length == 0) { - continue; - } + for (String name : methods.keySet()) { + if (inheritor.findMethodsByName(name, true).length == 0) { + continue; + } - for (PsiMethod method : methods.get(name)) { - if (method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && !JavaPsiFacade.getInstance(inheritor.getProject()) - .arePackagesTheSame(psiClass, inheritor)) { - continue; - } + for (PsiMethod method : methods.get(name)) { + if (method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && !JavaPsiFacade.getInstance(inheritor.getProject()) + .arePackagesTheSame(psiClass, inheritor)) { + continue; + } - if (substitutor == null) { - //could be null if not java inheritor, TODO only JavaClassInheritors are needed - substitutor = TypeConversionUtil.getClassSubstitutor(psiClass, inheritor, PsiSubstitutor.EMPTY); - if (substitutor == null) { - return true; - } - } + if (substitutor == null) { + //could be null if not java inheritor, TODO only JavaClassInheritors are needed + substitutor = TypeConversionUtil.getClassSubstitutor(psiClass, inheritor, PsiSubstitutor.EMPTY); + if (substitutor == null) { + return true; + } + } - MethodSignature signature = method.getSignature(substitutor); - PsiMethod inInheritor = MethodSignatureUtil.findMethodBySuperSignature(inheritor, signature, false); - if (inInheritor != null && !inInheritor.hasModifierProperty(PsiModifier.STATIC)) { - if (!consumer.process(Pair.create(method, inInheritor))) { - return false; - } - } + MethodSignature signature = method.getSignature(substitutor); + PsiMethod inInheritor = MethodSignatureUtil.findMethodBySuperSignature(inheritor, signature, false); + if (inInheritor != null && !inInheritor.hasModifierProperty(PsiModifier.STATIC)) { + if (!consumer.process(Pair.create(method, inInheritor))) { + return false; + } + } - if (psiClass.isInterface() && !inheritor.isInterface()) { //check for sibling implementation - final PsiClass superClass = inheritor.getSuperClass(); - if (superClass != null && !superClass.isInheritor(psiClass, true)) { - inInheritor = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(inheritor, superClass, signature, true); - if (inInheritor != null && !inInheritor.hasModifierProperty(PsiModifier.STATIC)) { - if (!consumer.process(Pair.create(method, inInheritor))) { - return false; - } + if (psiClass.isInterface() && !inheritor.isInterface()) { //check for sibling implementation + final PsiClass superClass = inheritor.getSuperClass(); + if (superClass != null && !superClass.isInheritor(psiClass, true)) { + inInheritor = + MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(inheritor, superClass, signature, true); + if (inInheritor != null && !inInheritor.hasModifierProperty(PsiModifier.STATIC)) { + if (!consumer.process(Pair.create(method, inInheritor))) { + return false; + } + } + } + } + } } - } - } - } - } - return true; - } - }; + return true; + } + }; - return ClassInheritorsSearch.search(psiClass, scope, true).forEach(inheritorsProcessor); - } + return ClassInheritorsSearch.search(psiClass, scope, true).forEach(inheritorsProcessor); + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaClassInheritorsSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaClassInheritorsSearcher.java index 30b3cdcc7..9de9fc7a6 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaClassInheritorsSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaClassInheritorsSearcher.java @@ -44,136 +44,143 @@ import consulo.util.lang.ref.Ref; import jakarta.annotation.Nonnull; + import java.util.HashSet; import java.util.Set; @ExtensionImpl public class JavaClassInheritorsSearcher extends QueryExecutorBase implements ClassInheritorsSearchExecutor { - private static final Logger LOG = Logger.getInstance(JavaClassInheritorsSearcher.class); - - @Override - public void processQuery(@Nonnull ClassInheritorsSearch.SearchParameters parameters, @Nonnull Processor consumer) { - final PsiClass baseClass = parameters.getClassToProcess(); - final SearchScope searchScope = parameters.getScope(); - - LOG.assertTrue(searchScope != null); - - ProgressIndicator progress = ProgressIndicatorProvider.getGlobalProgressIndicator(); - if (progress != null) { - progress.pushState(); - String className = ApplicationManager.getApplication().runReadAction((Computable) () -> baseClass.getName()); - progress.setText(className != null ? PsiBundle.message("psi.search.inheritors.of.class.progress", className) : PsiBundle.message("psi.search.inheritors.progress")); - } - - processInheritors(consumer, baseClass, searchScope, parameters); + private static final Logger LOG = Logger.getInstance(JavaClassInheritorsSearcher.class); + + @Override + public void processQuery(@Nonnull ClassInheritorsSearch.SearchParameters parameters, @Nonnull Processor consumer) { + final PsiClass baseClass = parameters.getClassToProcess(); + final SearchScope searchScope = parameters.getScope(); + + LOG.assertTrue(searchScope != null); + + ProgressIndicator progress = ProgressIndicatorProvider.getGlobalProgressIndicator(); + if (progress != null) { + progress.pushState(); + String className = ApplicationManager.getApplication().runReadAction((Computable)() -> baseClass.getName()); + progress.setText( + className != null + ? PsiBundle.message("psi.search.inheritors.of.class.progress", className) + : PsiBundle.message("psi.search.inheritors.progress") + ); + } - if (progress != null) { - progress.popState(); - } - } - - private static void processInheritors(@Nonnull final Processor consumer, - @Nonnull final PsiClass baseClass, - @Nonnull final SearchScope searchScope, - @Nonnull final ClassInheritorsSearch.SearchParameters parameters) { - if (baseClass instanceof PsiAnonymousClass || isFinal(baseClass)) { - return; - } + processInheritors(consumer, baseClass, searchScope, parameters); - Project project = PsiUtilCore.getProjectInReadAction(baseClass); - if (isJavaLangObject(baseClass)) { - AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(new Processor() { - @Override - public boolean process(final PsiClass aClass) { - ProgressManager.checkCanceled(); - return isJavaLangObject(aClass) || consumer.process(aClass); + if (progress != null) { + progress.popState(); } - }); - return; } - final Ref currentBase = Ref.create(null); - final Stack stack = new Stack(); - final Set processed = new HashSet<>(); - - final Processor processor = new ReadActionProcessor() { - @Override - public boolean processInReadAction(PsiClass candidate) { - ProgressManager.checkCanceled(); - - if (parameters.isCheckInheritance() || parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass)) { - if (!candidate.isInheritor(currentBase.get(), false)) { - return true; - } + private static void processInheritors( + @Nonnull final Processor consumer, + @Nonnull final PsiClass baseClass, + @Nonnull final SearchScope searchScope, + @Nonnull final ClassInheritorsSearch.SearchParameters parameters + ) { + if (baseClass instanceof PsiAnonymousClass || isFinal(baseClass)) { + return; } - if (PsiSearchScopeUtil.isInScope(searchScope, candidate)) { - if (candidate instanceof PsiAnonymousClass) { - return consumer.process(candidate); - } - - final String name = candidate.getName(); - if (name != null && parameters.getNameCondition().value(name) && !consumer.process(candidate)) { - return false; - } + Project project = PsiUtilCore.getProjectInReadAction(baseClass); + if (isJavaLangObject(baseClass)) { + AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(new Processor() { + @Override + public boolean process(final PsiClass aClass) { + ProgressManager.checkCanceled(); + return isJavaLangObject(aClass) || consumer.process(aClass); + } + }); + return; } - if (parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass) && !isFinal(candidate)) { - stack.push(PsiAnchor.create(candidate)); - } - return true; - } - }; - - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - stack.push(PsiAnchor.create(baseClass)); - } - }); - final GlobalSearchScope projectScope = GlobalSearchScope.allScope(project); - - while (!stack.isEmpty()) { - ProgressManager.checkCanceled(); - - final PsiAnchor anchor = stack.pop(); - if (!processed.add(anchor)) { - continue; - } - - PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiClass compute() { - return (PsiClass) anchor.retrieve(); + final Ref currentBase = Ref.create(null); + final Stack stack = new Stack(); + final Set processed = new HashSet<>(); + + final Processor processor = new ReadActionProcessor() { + @Override + public boolean processInReadAction(PsiClass candidate) { + ProgressManager.checkCanceled(); + + if (parameters.isCheckInheritance() || parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass)) { + if (!candidate.isInheritor(currentBase.get(), false)) { + return true; + } + } + + if (PsiSearchScopeUtil.isInScope(searchScope, candidate)) { + if (candidate instanceof PsiAnonymousClass) { + return consumer.process(candidate); + } + + final String name = candidate.getName(); + if (name != null && parameters.getNameCondition().value(name) && !consumer.process(candidate)) { + return false; + } + } + + if (parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass) && !isFinal(candidate)) { + stack.push(PsiAnchor.create(candidate)); + } + return true; + } + }; + + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + stack.push(PsiAnchor.create(baseClass)); + } + }); + final GlobalSearchScope projectScope = GlobalSearchScope.allScope(project); + + while (!stack.isEmpty()) { + ProgressManager.checkCanceled(); + + final PsiAnchor anchor = stack.pop(); + if (!processed.add(anchor)) { + continue; + } + + PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiClass compute() { + return (PsiClass)anchor.retrieve(); + } + }); + if (psiClass == null) { + continue; + } + + currentBase.set(psiClass); + if (!DirectClassInheritorsSearch.search(psiClass, projectScope, parameters.isIncludeAnonymous(), false).forEach(processor)) { + return; + } } - }); - if (psiClass == null) { - continue; - } - - currentBase.set(psiClass); - if (!DirectClassInheritorsSearch.search(psiClass, projectScope, parameters.isIncludeAnonymous(), false).forEach(processor)) { - return; - } } - } - - private static boolean isJavaLangObject(@Nonnull final PsiClass baseClass) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - return baseClass.isValid() && JavaClassNames.JAVA_LANG_OBJECT.equals(baseClass.getQualifiedName()); - } - }); - } - - private static boolean isFinal(@Nonnull final PsiClass baseClass) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - return Boolean.valueOf(baseClass.hasModifierProperty(PsiModifier.FINAL)); - } - }).booleanValue(); - } + + private static boolean isJavaLangObject(@Nonnull final PsiClass baseClass) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public Boolean compute() { + return baseClass.isValid() && JavaClassNames.JAVA_LANG_OBJECT.equals(baseClass.getQualifiedName()); + } + }); + } + + private static boolean isFinal(@Nonnull final PsiClass baseClass) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public Boolean compute() { + return Boolean.valueOf(baseClass.hasModifierProperty(PsiModifier.FINAL)); + } + }).booleanValue(); + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaDirectInheritorsSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaDirectInheritorsSearcher.java index 572dc38bc..fda38a826 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaDirectInheritorsSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaDirectInheritorsSearcher.java @@ -40,6 +40,7 @@ import consulo.virtualFileSystem.VirtualFile; import jakarta.annotation.Nonnull; + import java.util.*; /** @@ -47,196 +48,213 @@ */ @ExtensionImpl public class JavaDirectInheritorsSearcher implements DirectClassInheritorsSearchExecutor { - @Override - public boolean execute(@Nonnull final DirectClassInheritorsSearch.SearchParameters p, @Nonnull final Processor consumer) { - final PsiClass aClass = p.getClassToProcess(); - - final SearchScope useScope = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public SearchScope compute() { - return aClass.getUseScope(); - } - }); - - final String qualifiedName = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - return aClass.getQualifiedName(); - } - }); - - final Project project = PsiUtilCore.getProjectInReadAction(aClass); - if (JavaClassNames.JAVA_LANG_OBJECT.equals(qualifiedName)) { - //[pasynkov]: WTF? - //final SearchScope scope = useScope.intersectWith(GlobalSearchScope.notScope(GlobalSearchScope.getScopeRestrictedByFileTypes( - // GlobalSearchScope.allScope(psiManager.getProject()), StdFileTypes.JSP, StdFileTypes.JSPX))); - - return AllClassesSearch.search(useScope, project).forEach(new Processor() { - @Override - public boolean process(final PsiClass psiClass) { - ProgressManager.checkCanceled(); - if (psiClass.isInterface()) { - return consumer.process(psiClass); - } - final PsiClass superClass = psiClass.getSuperClass(); - if (superClass != null && JavaClassNames.JAVA_LANG_OBJECT.equals(ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public boolean execute( + @Nonnull final DirectClassInheritorsSearch.SearchParameters p, + @Nonnull final Processor consumer + ) { + final PsiClass aClass = p.getClassToProcess(); + + final SearchScope useScope = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public SearchScope compute() { + return aClass.getUseScope(); + } + }); + + final String qualifiedName = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override public String compute() { - return superClass.getQualifiedName(); + return aClass.getQualifiedName(); } - }))) { - return consumer.process(psiClass); - } - return true; - } - }); - } + }); - final GlobalSearchScope scope = useScope instanceof GlobalSearchScope ? (GlobalSearchScope) useScope : new EverythingGlobalScope(project); - final String searchKey = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - return aClass.getName(); - } - }); - if (StringUtil.isEmpty(searchKey)) { - return true; - } + final Project project = PsiUtilCore.getProjectInReadAction(aClass); + if (JavaClassNames.JAVA_LANG_OBJECT.equals(qualifiedName)) { + //[pasynkov]: WTF? + //final SearchScope scope = useScope.intersectWith(GlobalSearchScope.notScope(GlobalSearchScope.getScopeRestrictedByFileTypes( + // GlobalSearchScope.allScope(psiManager.getProject()), StdFileTypes.JSP, StdFileTypes.JSPX))); - Collection candidates = MethodUsagesSearcher.resolveInReadAction(project, new Computable>() { - @Override - public Collection compute() { - return JavaSuperClassNameOccurenceIndex.getInstance().get(searchKey, project, scope); - } - }); - - Map> classes = new HashMap>(); - - for (final PsiReferenceList referenceList : candidates) { - ProgressManager.checkCanceled(); - final PsiClass candidate = (PsiClass) ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiElement compute() { - return referenceList.getParent(); - } - }); - if (!checkInheritance(p, aClass, candidate, project)) { - continue; - } - - String fqn = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - return candidate.getQualifiedName(); + return AllClassesSearch.search(useScope, project).forEach(new Processor() { + @Override + public boolean process(final PsiClass psiClass) { + ProgressManager.checkCanceled(); + if (psiClass.isInterface()) { + return consumer.process(psiClass); + } + final PsiClass superClass = psiClass.getSuperClass(); + if (superClass != null && JavaClassNames.JAVA_LANG_OBJECT.equals(ApplicationManager.getApplication() + .runReadAction(new Computable() { + public String compute() { + return superClass.getQualifiedName(); + } + }))) { + return consumer.process(psiClass); + } + return true; + } + }); } - }); - List list = classes.get(fqn); - if (list == null) { - list = new ArrayList(); - classes.put(fqn, list); - } - list.add(candidate); - } - if (!classes.isEmpty()) { - final VirtualFile jarFile = getArchiveFile(aClass); - for (List sameNamedClasses : classes.values()) { - ProgressManager.checkCanceled(); - if (!processSameNamedClasses(consumer, sameNamedClasses, jarFile)) { - return false; + final GlobalSearchScope scope = + useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : new EverythingGlobalScope(project); + final String searchKey = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public String compute() { + return aClass.getName(); + } + }); + if (StringUtil.isEmpty(searchKey)) { + return true; } - } - } - if (p.includeAnonymous()) { - Collection anonymousCandidates = MethodUsagesSearcher.resolveInReadAction(project, new Computable>() { - @Override - public Collection compute() { - return JavaAnonymousClassBaseRefOccurenceIndex.getInstance().get(searchKey, project, scope); - } - }); + Collection candidates = + MethodUsagesSearcher.resolveInReadAction(project, new Computable>() { + @Override + public Collection compute() { + return JavaSuperClassNameOccurenceIndex.getInstance().get(searchKey, project, scope); + } + }); - for (PsiAnonymousClass candidate : anonymousCandidates) { - ProgressManager.checkCanceled(); - if (!checkInheritance(p, aClass, candidate, project)) { - continue; - } + Map> classes = new HashMap>(); + + for (final PsiReferenceList referenceList : candidates) { + ProgressManager.checkCanceled(); + final PsiClass candidate = (PsiClass)ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiElement compute() { + return referenceList.getParent(); + } + }); + if (!checkInheritance(p, aClass, candidate, project)) { + continue; + } - if (!consumer.process(candidate)) { - return false; + String fqn = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public String compute() { + return candidate.getQualifiedName(); + } + }); + List list = classes.get(fqn); + if (list == null) { + list = new ArrayList(); + classes.put(fqn, list); + } + list.add(candidate); } - } - boolean isEnum = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - return aClass.isEnum(); + if (!classes.isEmpty()) { + final VirtualFile jarFile = getArchiveFile(aClass); + for (List sameNamedClasses : classes.values()) { + ProgressManager.checkCanceled(); + if (!processSameNamedClasses(consumer, sameNamedClasses, jarFile)) { + return false; + } + } } - }); - if (isEnum) { - // abstract enum can be subclassed in the body - PsiField[] fields = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiField[] compute() { - return aClass.getFields(); - } - }); - for (final PsiField field : fields) { - ProgressManager.checkCanceled(); - if (field instanceof PsiEnumConstant) { - PsiEnumConstantInitializer initializingClass = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiEnumConstantInitializer compute() { - return ((PsiEnumConstant) field).getInitializingClass(); - } + + if (p.includeAnonymous()) { + Collection anonymousCandidates = + MethodUsagesSearcher.resolveInReadAction(project, new Computable>() { + @Override + public Collection compute() { + return JavaAnonymousClassBaseRefOccurenceIndex.getInstance().get(searchKey, project, scope); + } + }); + + for (PsiAnonymousClass candidate : anonymousCandidates) { + ProgressManager.checkCanceled(); + if (!checkInheritance(p, aClass, candidate, project)) { + continue; + } + + if (!consumer.process(candidate)) { + return false; + } + } + + boolean isEnum = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public Boolean compute() { + return aClass.isEnum(); + } }); - if (initializingClass != null) { - if (!consumer.process(initializingClass)) { - return false; - } + if (isEnum) { + // abstract enum can be subclassed in the body + PsiField[] fields = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiField[] compute() { + return aClass.getFields(); + } + }); + for (final PsiField field : fields) { + ProgressManager.checkCanceled(); + if (field instanceof PsiEnumConstant) { + PsiEnumConstantInitializer initializingClass = + ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiEnumConstantInitializer compute() { + return ((PsiEnumConstant)field).getInitializingClass(); + } + }); + if (initializingClass != null) { + if (!consumer.process(initializingClass)) { + return false; + } + } + } + } } - } } - } + + return true; } - return true; - } - - private static boolean checkInheritance(final DirectClassInheritorsSearch.SearchParameters p, final PsiClass aClass, final PsiClass candidate, Project project) { - return MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public Boolean compute() { - return !p.isCheckInheritance() || candidate.isInheritor(aClass, false); - } - }); - } - - private static boolean processSameNamedClasses(Processor consumer, List sameNamedClasses, final VirtualFile jarFile) { - // if there is a class from the same jar, prefer it - boolean sameJarClassFound = false; - - if (jarFile != null && sameNamedClasses.size() > 1) { - for (PsiClass sameNamedClass : sameNamedClasses) { - ProgressManager.checkCanceled(); - boolean fromSameJar = Comparing.equal(getArchiveFile(sameNamedClass), jarFile); - if (fromSameJar) { - sameJarClassFound = true; - if (!consumer.process(sameNamedClass)) { - return false; - } + private static boolean checkInheritance( + final DirectClassInheritorsSearch.SearchParameters p, + final PsiClass aClass, + final PsiClass candidate, + Project project + ) { + return MethodUsagesSearcher.resolveInReadAction(project, new Computable() { + @Override + public Boolean compute() { + return !p.isCheckInheritance() || candidate.isInheritor(aClass, false); + } + }); + } + + private static boolean processSameNamedClasses( + Processor consumer, + List sameNamedClasses, + final VirtualFile jarFile + ) { + // if there is a class from the same jar, prefer it + boolean sameJarClassFound = false; + + if (jarFile != null && sameNamedClasses.size() > 1) { + for (PsiClass sameNamedClass : sameNamedClasses) { + ProgressManager.checkCanceled(); + boolean fromSameJar = Comparing.equal(getArchiveFile(sameNamedClass), jarFile); + if (fromSameJar) { + sameJarClassFound = true; + if (!consumer.process(sameNamedClass)) { + return false; + } + } + } } - } + + return sameJarClassFound || ContainerUtil.process(sameNamedClasses, consumer); } - return sameJarClassFound || ContainerUtil.process(sameNamedClasses, consumer); - } - - private static VirtualFile getArchiveFile(final PsiClass aClass) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public VirtualFile compute() { - return PsiUtil.getJarFile(aClass); - } - }); - } + private static VirtualFile getArchiveFile(final PsiClass aClass) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public VirtualFile compute() { + return PsiUtil.getJarFile(aClass); + } + }); + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaFunctionalExpressionSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaFunctionalExpressionSearcher.java index 6caa3a346..e162cc3b3 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaFunctionalExpressionSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaFunctionalExpressionSearcher.java @@ -55,385 +55,411 @@ import consulo.virtualFileSystem.VirtualFile; import jakarta.annotation.Nonnull; + import java.util.*; import static consulo.util.collection.ContainerUtil.addIfNotNull; import static consulo.util.collection.ContainerUtil.process; @ExtensionImpl -public class JavaFunctionalExpressionSearcher extends QueryExecutorBase implements FunctionalExpressionSearchExecutor { - private static record ClassLambdaInfo(Project project, GlobalSearchScope scope, int expectedFunExprParamsCount) { - } - - private static final Logger LOG = Logger.getInstance(JavaFunctionalExpressionSearcher.class); - /** - * The least number of candidate files with functional expressions that directly scanning them becomes expensive - * and more advanced ways of searching become necessary: e.g. first searching for methods where the functional interface class is used - * and then for their usages, - */ - public static final int SMART_SEARCH_THRESHOLD = 5; - - @Override - public void processQuery(@Nonnull FunctionalExpressionSearch.SearchParameters queryParameters, - @Nonnull Processor consumer) { - final PsiClass aClass = queryParameters.getElementToSearch(); - - ClassLambdaInfo classLambdaInfo = ReadAction.compute(() -> - { - if (!aClass.isValid() || !LambdaUtil.isFunctionalClass(aClass)) { - return null; - } - - Project project = aClass.getProject(); - final Set highLevelModules = getJava8Modules(project); - if (highLevelModules.isEmpty()) { - return null; - } - - GlobalSearchScope useScope = - convertToGlobalScope(project, queryParameters.getEffectiveSearchScope()); - - final MethodSignature functionalInterfaceMethod = LambdaUtil.getFunction(aClass); - LOG.assertTrue(functionalInterfaceMethod != null); - int expectedFunExprParamsCount = - functionalInterfaceMethod.getParameterTypes().length; - return new ClassLambdaInfo(project, useScope, expectedFunExprParamsCount); - }); - - if (classLambdaInfo == null) { - return; +public class JavaFunctionalExpressionSearcher + extends QueryExecutorBase + implements FunctionalExpressionSearchExecutor { + + private static record ClassLambdaInfo(Project project, GlobalSearchScope scope, int expectedFunExprParamsCount) { } - final Project project = classLambdaInfo.project(); - final GlobalSearchScope useScope = classLambdaInfo.scope(); - final int expectedFunExprParamsCount = classLambdaInfo.expectedFunExprParamsCount(); + private static final Logger LOG = Logger.getInstance(JavaFunctionalExpressionSearcher.class); + /** + * The least number of candidate files with functional expressions that directly scanning them becomes expensive + * and more advanced ways of searching become necessary: e.g. first searching for methods where the functional interface class is used + * and then for their usages, + */ + public static final int SMART_SEARCH_THRESHOLD = 5; - //collect all files with '::' and '->' in useScope - Set candidateFiles = getFilesWithFunctionalExpressionsScope(project, new JavaSourceFilterScope(useScope)); - if (candidateFiles.size() < SMART_SEARCH_THRESHOLD) { - searchInFiles(aClass, consumer, candidateFiles, expectedFunExprParamsCount); - return; - } + @Override + public void processQuery( + @Nonnull FunctionalExpressionSearch.SearchParameters queryParameters, + @Nonnull Processor consumer + ) { + final PsiClass aClass = queryParameters.getElementToSearch(); + + ClassLambdaInfo classLambdaInfo = ReadAction.compute(() -> + { + if (!aClass.isValid() || !LambdaUtil.isFunctionalClass(aClass)) { + return null; + } - final GlobalSearchScope candidateScope = GlobalSearchScope.filesScope(project, candidateFiles); + Project project = aClass.getProject(); + final Set highLevelModules = getJava8Modules(project); + if (highLevelModules.isEmpty()) { + return null; + } - //collect all methods with parameter of functional interface or free type parameter type - final Collection methodCandidates = - getCandidateMethodsWithSuitableParams(aClass, project, useScope, candidateFiles, candidateScope); + GlobalSearchScope useScope = + convertToGlobalScope(project, queryParameters.getEffectiveSearchScope()); - final LinkedHashSet filesToProcess = new LinkedHashSet(); - final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance(); + final MethodSignature functionalInterfaceMethod = LambdaUtil.getFunction(aClass); + LOG.assertTrue(functionalInterfaceMethod != null); + int expectedFunExprParamsCount = + functionalInterfaceMethod.getParameterTypes().length; + return new ClassLambdaInfo(project, useScope, expectedFunExprParamsCount); + }); - //find all usages of method candidates in files with functional expressions - for (final PsiMethod psiMethod : methodCandidates) { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - if (!psiMethod.isValid()) { + if (classLambdaInfo == null) { + return; + } + + final Project project = classLambdaInfo.project(); + final GlobalSearchScope useScope = classLambdaInfo.scope(); + final int expectedFunExprParamsCount = classLambdaInfo.expectedFunExprParamsCount(); + + //collect all files with '::' and '->' in useScope + Set candidateFiles = getFilesWithFunctionalExpressionsScope(project, new JavaSourceFilterScope(useScope)); + if (candidateFiles.size() < SMART_SEARCH_THRESHOLD) { + searchInFiles(aClass, consumer, candidateFiles, expectedFunExprParamsCount); return; - } - final int parametersCount = psiMethod.getParameterList().getParametersCount(); - final boolean varArgs = psiMethod.isVarArgs(); - final PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); - final GlobalSearchScope methodUseScope = convertToGlobalScope(project, psiMethod.getUseScope()); - final LinkedHashMap> holders = - new LinkedHashMap>(); - //functional expressions checker: number and type of parameters at call site should correspond to candidate method currently check - final SuitableFilesProcessor processor = - new SuitableFilesProcessor(holders, expectedFunExprParamsCount, parametersCount, varArgs, parameters); - fileBasedIndex.processValues(JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID, - psiMethod.getName(), - null, - processor, - useScope.intersectWith(methodUseScope)); - for (Map.Entry> entry : holders.entrySet()) { - for (JavaFunctionalExpressionIndex.IndexHolder holder : entry.getValue()) { - if (processor.canBeFunctional(holder)) { - filesToProcess.add(entry.getKey()); - break; - } + } + + final GlobalSearchScope candidateScope = GlobalSearchScope.filesScope(project, candidateFiles); + + //collect all methods with parameter of functional interface or free type parameter type + final Collection methodCandidates = + getCandidateMethodsWithSuitableParams(aClass, project, useScope, candidateFiles, candidateScope); + + final LinkedHashSet filesToProcess = new LinkedHashSet(); + final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance(); + + //find all usages of method candidates in files with functional expressions + for (final PsiMethod psiMethod : methodCandidates) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + if (!psiMethod.isValid()) { + return; + } + final int parametersCount = psiMethod.getParameterList().getParametersCount(); + final boolean varArgs = psiMethod.isVarArgs(); + final PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); + final GlobalSearchScope methodUseScope = convertToGlobalScope(project, psiMethod.getUseScope()); + final LinkedHashMap> holders = + new LinkedHashMap>(); + //functional expressions checker: number and type of parameters at call site should correspond to candidate method currently check + final SuitableFilesProcessor processor = + new SuitableFilesProcessor(holders, expectedFunExprParamsCount, parametersCount, varArgs, parameters); + fileBasedIndex.processValues( + JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID, + psiMethod.getName(), + null, + processor, + useScope.intersectWith(methodUseScope) + ); + for (Map.Entry> entry : holders.entrySet()) { + for (JavaFunctionalExpressionIndex.IndexHolder holder : entry.getValue()) { + if (processor.canBeFunctional(holder)) { + filesToProcess.add(entry.getKey()); + break; + } + } + } + } + }); + } + + //search for functional expressions in non-call contexts + collectFilesWithTypeOccurrencesAndFieldAssignments(aClass, candidateScope, filesToProcess); + + searchInFiles(aClass, consumer, filesToProcess, expectedFunExprParamsCount); + } + + @Nonnull + @RequiredReadAction + private static Set getJava8Modules(Project project) { + final Set highLevelModules = new HashSet(); + for (Module module : ModuleManager.getInstance(project).getModules()) { + JavaModuleExtension moduleExtension = ModuleUtilCore.getExtension(module, JavaModuleExtension.class); + if (moduleExtension != null && moduleExtension.getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_8)) { + highLevelModules.add(module); } - } } - }); + return highLevelModules; } - //search for functional expressions in non-call contexts - collectFilesWithTypeOccurrencesAndFieldAssignments(aClass, candidateScope, filesToProcess); - - searchInFiles(aClass, consumer, filesToProcess, expectedFunExprParamsCount); - } - - @Nonnull - @RequiredReadAction - private static Set getJava8Modules(Project project) { - final Set highLevelModules = new HashSet(); - for (Module module : ModuleManager.getInstance(project).getModules()) { - JavaModuleExtension moduleExtension = ModuleUtilCore.getExtension(module, JavaModuleExtension.class); - if (moduleExtension != null && moduleExtension.getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_8)) { - highLevelModules.add(module); - } + private static void searchInFiles( + final PsiClass aClass, + final Processor consumer, + Set filesToProcess, + final int expectedFunExprParamsCount + ) { + LOG.info("#usage files: " + filesToProcess.size()); + process(filesToProcess, new ReadActionProcessor() { + @RequiredReadAction + @Override + public boolean processInReadAction(VirtualFile file) { + //resolve functional expressions to ensure that functional expression type is appropriate + return processFileWithFunctionalInterfaces(aClass, expectedFunExprParamsCount, consumer, file); + } + }); } - return highLevelModules; - } - - private static void searchInFiles(final PsiClass aClass, - final Processor consumer, - Set filesToProcess, - final int expectedFunExprParamsCount) { - LOG.info("#usage files: " + filesToProcess.size()); - process(filesToProcess, new ReadActionProcessor() { - @RequiredReadAction - @Override - public boolean processInReadAction(VirtualFile file) { - //resolve functional expressions to ensure that functional expression type is appropriate - return processFileWithFunctionalInterfaces(aClass, expectedFunExprParamsCount, consumer, file); - } - }); - } - - private static Collection getCandidateMethodsWithSuitableParams(final PsiClass aClass, - final Project project, - final GlobalSearchScope useScope, - final Set candidateFiles, - final GlobalSearchScope candidateScope) { - return ApplicationManager.getApplication().runReadAction(new Computable>() { - @Override - public Collection compute() { - if (!aClass.isValid()) { - return Collections.emptyList(); - } - GlobalSearchScope visibleFromCandidates = combineResolveScopes(project, candidateFiles); - - final Set usedMethodNames = new HashSet<>(); - FileBasedIndex.getInstance() - .processAllKeys(JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID, - new CommonProcessors.CollectProcessor(usedMethodNames), - candidateScope, - null); - - final LinkedHashSet methods = new LinkedHashSet<>(); - Processor methodProcessor = new Processor() { - @Override - public boolean process(PsiMethod method) { - if (usedMethodNames.contains(method.getName())) { - methods.add(method); + private static Collection getCandidateMethodsWithSuitableParams( + final PsiClass aClass, + final Project project, + final GlobalSearchScope useScope, + final Set candidateFiles, + final GlobalSearchScope candidateScope + ) { + return ApplicationManager.getApplication().runReadAction(new Computable>() { + @Override + public Collection compute() { + if (!aClass.isValid()) { + return Collections.emptyList(); + } + + GlobalSearchScope visibleFromCandidates = combineResolveScopes(project, candidateFiles); + + final Set usedMethodNames = new HashSet<>(); + FileBasedIndex.getInstance().processAllKeys( + JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID, + new CommonProcessors.CollectProcessor(usedMethodNames), + candidateScope, + null + ); + + final LinkedHashSet methods = new LinkedHashSet<>(); + Processor methodProcessor = new Processor() { + @Override + public boolean process(PsiMethod method) { + if (usedMethodNames.contains(method.getName())) { + methods.add(method); + } + return true; + } + }; + + StubIndexKey key = JavaMethodParameterTypesIndex.getInstance().getKey(); + StubIndex index = StubIndex.getInstance(); + index.processElements( + key, + aClass.getName(), + project, + useScope.intersectWith(visibleFromCandidates), + PsiMethod.class, + methodProcessor + ); + //broken index.processElements(key, JavaMethodElementType.TYPE_PARAMETER_PSEUDO_NAME, project, visibleFromCandidates, PsiMethod.class, methodProcessor); + LOG.info("#methods: " + methods.size()); + return methods; } - return true; - } - }; - - StubIndexKey key = JavaMethodParameterTypesIndex.getInstance().getKey(); - StubIndex index = StubIndex.getInstance(); - index.processElements(key, - aClass.getName(), - project, - useScope.intersectWith(visibleFromCandidates), - PsiMethod.class, - methodProcessor); - //broken index.processElements(key, JavaMethodElementType.TYPE_PARAMETER_PSEUDO_NAME, project, visibleFromCandidates, PsiMethod.class, methodProcessor); - LOG.info("#methods: " + methods.size()); - return methods; - } - }); - } - - @Nonnull - private static GlobalSearchScope combineResolveScopes(Project project, Set candidateFiles) { - final PsiManager psiManager = PsiManager.getInstance(project); - LinkedHashSet resolveScopes = new LinkedHashSet<>(candidateFiles.stream().map(file -> { - PsiFile psiFile = file.isValid() ? psiManager.findFile(file) : null; - return psiFile == null ? null : psiFile.getResolveScope(); - }).filter(Objects::nonNull).toList()); - return GlobalSearchScope.union(resolveScopes.toArray(new GlobalSearchScope[resolveScopes.size()])); - } - - @Nonnull - private static Set getFilesWithFunctionalExpressionsScope(Project project, GlobalSearchScope useScope) { - final Set files = new LinkedHashSet<>(); - final PsiSearchHelper helper = PsiSearchHelper.getInstance(project); - final CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor(files); - helper.processFilesWithText(useScope, UsageSearchContext.IN_CODE, true, "::", processor); - helper.processFilesWithText(useScope, UsageSearchContext.IN_CODE, true, "->", processor); - return files; - } - - @Nonnull - private static GlobalSearchScope convertToGlobalScope(Project project, SearchScope useScope) { - final GlobalSearchScope scope; - if (useScope instanceof GlobalSearchScope) { - scope = (GlobalSearchScope)useScope; + }); } - else if (useScope instanceof LocalSearchScope) { - final Set files = new HashSet(); - ContainerUtil.addAllNotNull(files, - ContainerUtil.map(((LocalSearchScope)useScope).getScope(), - element -> PsiUtilCore.getVirtualFile(element))); - scope = GlobalSearchScope.filesScope(project, files); + + @Nonnull + private static GlobalSearchScope combineResolveScopes(Project project, Set candidateFiles) { + final PsiManager psiManager = PsiManager.getInstance(project); + LinkedHashSet resolveScopes = new LinkedHashSet<>(candidateFiles.stream().map(file -> { + PsiFile psiFile = file.isValid() ? psiManager.findFile(file) : null; + return psiFile == null ? null : psiFile.getResolveScope(); + }).filter(Objects::nonNull).toList()); + return GlobalSearchScope.union(resolveScopes.toArray(new GlobalSearchScope[resolveScopes.size()])); } - else { - scope = new EverythingGlobalScope(project); + + @Nonnull + private static Set getFilesWithFunctionalExpressionsScope(Project project, GlobalSearchScope useScope) { + final Set files = new LinkedHashSet<>(); + final PsiSearchHelper helper = PsiSearchHelper.getInstance(project); + final CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor(files); + helper.processFilesWithText(useScope, UsageSearchContext.IN_CODE, true, "::", processor); + helper.processFilesWithText(useScope, UsageSearchContext.IN_CODE, true, "->", processor); + return files; } - return scope; - } - - /** - * Collect files where: - * aClass is used, e.g. in type declaration or method return type; - * fields with type aClass are used on the left side of assignments. Should find Bar of the following example - *
-   * class Foo {
-   * Runnable myRunnable;
-   * }
-   * 

- * class Bar { - * void foo(Foo foo){ - * foo.myRunnable = () -> {}; - * } - * } - *

- */ - private static void collectFilesWithTypeOccurrencesAndFieldAssignments(PsiClass aClass, - GlobalSearchScope filesScope, - final LinkedHashSet usageFiles) { - final Set fields = new LinkedHashSet(); - for (final PsiReference reference : ReferencesSearch.search(aClass, filesScope)) { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - final PsiElement element = reference.getElement(); - if (element != null) { - addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(element)); - final PsiElement parent = element.getParent(); - if (parent instanceof PsiTypeElement) { - final PsiElement gParent = parent.getParent(); - if (gParent instanceof PsiField && - !((PsiField)gParent).hasModifierProperty(PsiModifier.PRIVATE) && - !((PsiField)gParent).hasModifierProperty(PsiModifier.FINAL)) { - fields.add((PsiField)gParent); - } - } - } + + @Nonnull + private static GlobalSearchScope convertToGlobalScope(Project project, SearchScope useScope) { + final GlobalSearchScope scope; + if (useScope instanceof GlobalSearchScope) { + scope = (GlobalSearchScope)useScope; + } + else if (useScope instanceof LocalSearchScope) { + final Set files = new HashSet(); + ContainerUtil.addAllNotNull( + files, + ContainerUtil.map( + ((LocalSearchScope)useScope).getScope(), + element -> PsiUtilCore.getVirtualFile(element) + ) + ); + scope = GlobalSearchScope.filesScope(project, files); + } + else { + scope = new EverythingGlobalScope(project); } - }); + return scope; } - for (PsiField field : fields) { - ReferencesSearch.search(field, filesScope).forEach(new ReadActionProcessor() { - @Override - public boolean processInReadAction(PsiReference fieldRef) { - final PsiElement fieldElement = fieldRef.getElement(); - final PsiAssignmentExpression varElementParent = PsiTreeUtil.getParentOfType(fieldElement, PsiAssignmentExpression.class); - if (varElementParent != null && PsiTreeUtil.isAncestor(varElementParent.getLExpression(), fieldElement, false)) { - addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(fieldElement)); - } - return true; + /** + * Collect files where: + * aClass is used, e.g. in type declaration or method return type; + * fields with type aClass are used on the left side of assignments. Should find Bar of the following example + *
+     * class Foo {
+     * Runnable myRunnable;
+     * }
+     * 

+ * class Bar { + * void foo(Foo foo){ + * foo.myRunnable = () -> {}; + * } + * } + *

+ */ + private static void collectFilesWithTypeOccurrencesAndFieldAssignments( + PsiClass aClass, + GlobalSearchScope filesScope, + final LinkedHashSet usageFiles + ) { + final Set fields = new LinkedHashSet(); + for (final PsiReference reference : ReferencesSearch.search(aClass, filesScope)) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + final PsiElement element = reference.getElement(); + if (element != null) { + addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(element)); + final PsiElement parent = element.getParent(); + if (parent instanceof PsiTypeElement) { + final PsiElement gParent = parent.getParent(); + if (gParent instanceof PsiField && + !((PsiField)gParent).hasModifierProperty(PsiModifier.PRIVATE) && + !((PsiField)gParent).hasModifierProperty(PsiModifier.FINAL)) { + fields.add((PsiField)gParent); + } + } + } + } + }); } - }); - } - } - - private static boolean processFileWithFunctionalInterfaces(final PsiClass aClass, - final int expectedParamCount, - final Processor consumer, - VirtualFile file) { - final PsiFile psiFile = aClass.getManager().findFile(file); - if (psiFile != null) { - final Ref ref = new Ref(true); - psiFile.accept(new JavaRecursiveElementWalkingVisitor() { - @Override - public void visitElement(PsiElement element) { - if (!ref.get()) { - return; - } - super.visitElement(element); + + for (PsiField field : fields) { + ReferencesSearch.search(field, filesScope).forEach(new ReadActionProcessor() { + @Override + public boolean processInReadAction(PsiReference fieldRef) { + final PsiElement fieldElement = fieldRef.getElement(); + final PsiAssignmentExpression varElementParent = + PsiTreeUtil.getParentOfType(fieldElement, PsiAssignmentExpression.class); + if (varElementParent != null && PsiTreeUtil.isAncestor(varElementParent.getLExpression(), fieldElement, false)) { + addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(fieldElement)); + } + return true; + } + }); } + } - private void visitFunctionalExpression(PsiFunctionalExpression expression) { - PsiType functionalInterfaceType = expression.getFunctionalInterfaceType(); - if (InheritanceUtil.isInheritorOrSelf(PsiUtil.resolveClassInType(functionalInterfaceType), aClass, true)) { - if (!consumer.process(expression)) { - ref.set(false); + private static boolean processFileWithFunctionalInterfaces( + final PsiClass aClass, + final int expectedParamCount, + final Processor consumer, + VirtualFile file + ) { + final PsiFile psiFile = aClass.getManager().findFile(file); + if (psiFile != null) { + final Ref ref = new Ref(true); + psiFile.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitElement(PsiElement element) { + if (!ref.get()) { + return; + } + super.visitElement(element); + } + + private void visitFunctionalExpression(PsiFunctionalExpression expression) { + PsiType functionalInterfaceType = expression.getFunctionalInterfaceType(); + if (InheritanceUtil.isInheritorOrSelf(PsiUtil.resolveClassInType(functionalInterfaceType), aClass, true)) { + if (!consumer.process(expression)) { + ref.set(false); + } + } + } + + @Override + public void visitLambdaExpression(PsiLambdaExpression expression) { + super.visitLambdaExpression(expression); + if (expression.getParameterList().getParametersCount() == expectedParamCount) { + visitFunctionalExpression(expression); + } + } + + @Override + public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) { + super.visitMethodReferenceExpression(expression); + visitFunctionalExpression(expression); + } + }); + if (!ref.get()) { + return false; } - } } + return true; + } - @Override - public void visitLambdaExpression(PsiLambdaExpression expression) { - super.visitLambdaExpression(expression); - if (expression.getParameterList().getParametersCount() == expectedParamCount) { - visitFunctionalExpression(expression); - } + private static class SuitableFilesProcessor + implements FileBasedIndex.ValueProcessor> { + private final Map> myHolders; + private final int myExpectedFunExprParamsCount; + private final int myParametersCount; + private final boolean myVarArgs; + private final PsiParameter[] myParameters; + + public SuitableFilesProcessor( + Map> holders, + int expectedFunExprParamsCount, + int parametersCount, + boolean varArgs, + PsiParameter[] parameters + ) { + myHolders = holders; + myExpectedFunExprParamsCount = expectedFunExprParamsCount; + myParametersCount = parametersCount; + myVarArgs = varArgs; + myParameters = parameters; } @Override - public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) { - super.visitMethodReferenceExpression(expression); - visitFunctionalExpression(expression); + public boolean process(VirtualFile file, Collection holders) { + Set savedHolders = myHolders.get(file); + for (JavaFunctionalExpressionIndex.IndexHolder holder : holders) { + final int lambdaParamsNumber = holder.getLambdaParamsNumber(); + if (lambdaParamsNumber == myExpectedFunExprParamsCount || lambdaParamsNumber == -1) { + final boolean suitableParamNumbers; + if (myVarArgs) { + suitableParamNumbers = holder.getMethodArgsLength() >= myParametersCount - 1; + } + else { + suitableParamNumbers = holder.getMethodArgsLength() == myParametersCount; + } + if (suitableParamNumbers) { + if (savedHolders == null) { + savedHolders = new LinkedHashSet(); + myHolders.put(file, savedHolders); + } + savedHolders.add(holder); + break; + } + } + } + return true; } - }); - if (!ref.get()) { - return false; - } - } - return true; - } - - private static class SuitableFilesProcessor implements FileBasedIndex.ValueProcessor> { - private final Map> myHolders; - private final int myExpectedFunExprParamsCount; - private final int myParametersCount; - private final boolean myVarArgs; - private final PsiParameter[] myParameters; - - public SuitableFilesProcessor(Map> holders, - int expectedFunExprParamsCount, - int parametersCount, - boolean varArgs, - PsiParameter[] parameters) { - myHolders = holders; - myExpectedFunExprParamsCount = expectedFunExprParamsCount; - myParametersCount = parametersCount; - myVarArgs = varArgs; - myParameters = parameters; - } - @Override - public boolean process(VirtualFile file, Collection holders) { - Set savedHolders = myHolders.get(file); - for (JavaFunctionalExpressionIndex.IndexHolder holder : holders) { - final int lambdaParamsNumber = holder.getLambdaParamsNumber(); - if (lambdaParamsNumber == myExpectedFunExprParamsCount || lambdaParamsNumber == -1) { - final boolean suitableParamNumbers; - if (myVarArgs) { - suitableParamNumbers = holder.getMethodArgsLength() >= myParametersCount - 1; - } - else { - suitableParamNumbers = holder.getMethodArgsLength() == myParametersCount; - } - if (suitableParamNumbers) { - if (savedHolders == null) { - savedHolders = new LinkedHashSet(); - myHolders.put(file, savedHolders); + private boolean canBeFunctional(JavaFunctionalExpressionIndex.IndexHolder holder) { + final int paramIdx = holder.getFunctionExpressionIndex(); + PsiType paramType = myParameters[paramIdx >= myParametersCount ? myParametersCount - 1 : paramIdx].getType(); + if (paramType instanceof PsiEllipsisType) { + paramType = ((PsiEllipsisType)paramType).getComponentType(); } - savedHolders.add(holder); - break; - } + final PsiClass functionalCandidate = PsiUtil.resolveClassInClassTypeOnly(paramType); + return functionalCandidate instanceof PsiTypeParameter || LambdaUtil.isFunctionalClass(functionalCandidate); } - } - return true; - } - - private boolean canBeFunctional(JavaFunctionalExpressionIndex.IndexHolder holder) { - final int paramIdx = holder.getFunctionExpressionIndex(); - PsiType paramType = myParameters[paramIdx >= myParametersCount ? myParametersCount - 1 : paramIdx].getType(); - if (paramType instanceof PsiEllipsisType) { - paramType = ((PsiEllipsisType)paramType).getComponentType(); - } - final PsiClass functionalCandidate = PsiUtil.resolveClassInClassTypeOnly(paramType); - return functionalCandidate instanceof PsiTypeParameter || LambdaUtil.isFunctionalClass(functionalCandidate); } - } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaOverridingMethodsSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaOverridingMethodsSearcher.java index 0867706f7..787b7f0e5 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaOverridingMethodsSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaOverridingMethodsSearcher.java @@ -21,72 +21,78 @@ */ @ExtensionImpl public class JavaOverridingMethodsSearcher implements OverridingMethodsSearchExecutor { - @Override - public boolean execute(@Nonnull final OverridingMethodsSearch.SearchParameters p, @Nonnull final Processor consumer) { - final PsiMethod method = p.getMethod(); - final SearchScope scope = p.getScope(); + @Override + public boolean execute( + @Nonnull final OverridingMethodsSearch.SearchParameters p, + @Nonnull final Processor consumer + ) { + final PsiMethod method = p.getMethod(); + final SearchScope scope = p.getScope(); - final PsiClass parentClass = ApplicationManager.getApplication().runReadAction(new Computable() { - @Nullable - @Override - public PsiClass compute() { - return method.getContainingClass(); - } - }); - assert parentClass != null; - Processor inheritorsProcessor = new Processor() { - @Override - public boolean process(final PsiClass inheritor) { - PsiMethod found = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - @Nullable - public PsiMethod compute() { - return findOverridingMethod(inheritor, method, parentClass); - } + final PsiClass parentClass = ApplicationManager.getApplication().runReadAction(new Computable() { + @Nullable + @Override + public PsiClass compute() { + return method.getContainingClass(); + } }); - return found == null || consumer.process(found) && p.isCheckDeep(); - } - }; + assert parentClass != null; + Processor inheritorsProcessor = new Processor() { + @Override + public boolean process(final PsiClass inheritor) { + PsiMethod found = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + @Nullable + public PsiMethod compute() { + return findOverridingMethod(inheritor, method, parentClass); + } + }); + return found == null || consumer.process(found) && p.isCheckDeep(); + } + }; - return ClassInheritorsSearch.search(parentClass, scope, true).forEach(inheritorsProcessor); - } - - @Nullable - public static PsiMethod findOverridingMethod(PsiClass inheritor, PsiMethod method, @Nonnull PsiClass methodContainingClass) { - String name = method.getName(); - if (inheritor.findMethodsByName(name, false).length > 0) { - PsiMethod found = - MethodSignatureUtil.findMethodBySuperSignature(inheritor, getSuperSignature(inheritor, methodContainingClass, method), false); - if (found != null && isAcceptable(found, method)) { - return found; - } + return ClassInheritorsSearch.search(parentClass, scope, true).forEach(inheritorsProcessor); } - if (methodContainingClass.isInterface() && !inheritor.isInterface()) { //check for sibling implementation - final PsiClass superClass = inheritor.getSuperClass(); - if (superClass != null && !superClass.isInheritor(methodContainingClass, true) && superClass.findMethodsByName(name, - true).length > 0) { - MethodSignature signature = getSuperSignature(inheritor, methodContainingClass, method); - PsiMethod derived = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(inheritor, superClass, signature, true); - if (derived != null && isAcceptable(derived, method)) { - return derived; + @Nullable + public static PsiMethod findOverridingMethod(PsiClass inheritor, PsiMethod method, @Nonnull PsiClass methodContainingClass) { + String name = method.getName(); + if (inheritor.findMethodsByName(name, false).length > 0) { + PsiMethod found = MethodSignatureUtil.findMethodBySuperSignature( + inheritor, + getSuperSignature(inheritor, methodContainingClass, method), + false + ); + if (found != null && isAcceptable(found, method)) { + return found; + } + } + + if (methodContainingClass.isInterface() && !inheritor.isInterface()) { //check for sibling implementation + final PsiClass superClass = inheritor.getSuperClass(); + if (superClass != null && !superClass.isInheritor(methodContainingClass, true) + && superClass.findMethodsByName(name, true).length > 0) { + MethodSignature signature = getSuperSignature(inheritor, methodContainingClass, method); + PsiMethod derived = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(inheritor, superClass, signature, true); + if (derived != null && isAcceptable(derived, method)) { + return derived; + } + } } - } + return null; } - return null; - } - @Nonnull - private static MethodSignature getSuperSignature(PsiClass inheritor, @Nonnull PsiClass parentClass, PsiMethod method) { - PsiSubstitutor substitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(parentClass, inheritor, PsiSubstitutor.EMPTY); - // if null, we have EJB custom inheritance here and still check overriding - return method.getSignature(substitutor != null ? substitutor : PsiSubstitutor.EMPTY); - } + @Nonnull + private static MethodSignature getSuperSignature(PsiClass inheritor, @Nonnull PsiClass parentClass, PsiMethod method) { + PsiSubstitutor substitutor = TypeConversionUtil.getMaybeSuperClassSubstitutor(parentClass, inheritor, PsiSubstitutor.EMPTY); + // if null, we have EJB custom inheritance here and still check overriding + return method.getSignature(substitutor != null ? substitutor : PsiSubstitutor.EMPTY); + } - private static boolean isAcceptable(final PsiMethod found, final PsiMethod method) { - return !found.hasModifierProperty(PsiModifier.STATIC) && (!method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) || JavaPsiFacade.getInstance( - found.getProject()).arePackagesTheSame(method - .getContainingClass(), found.getContainingClass())); - } + private static boolean isAcceptable(final PsiMethod found, final PsiMethod method) { + return !found.hasModifierProperty(PsiModifier.STATIC) && (!method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) || JavaPsiFacade.getInstance( + found.getProject()).arePackagesTheSame(method + .getContainingClass(), found.getContainingClass())); + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaRecordComponentSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaRecordComponentSearcher.java index 28c6e04c1..3c2d5ab4e 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaRecordComponentSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaRecordComponentSearcher.java @@ -22,73 +22,91 @@ @ExtensionImpl public final class JavaRecordComponentSearcher extends QueryExecutorBase implements ReferencesSearchQueryExecutor { - @Override - public void processQuery(@Nonnull ReferencesSearch.SearchParameters queryParameters, @Nonnull Processor consumer) { - PsiElement element = queryParameters.getElementToSearch(); - if (element instanceof PsiRecordComponent recordComponent) { - SearchScope scope = queryParameters.getEffectiveSearchScope(); - RecordNavigationInfo info = findNavigationInfo(recordComponent); - if (info != null) { - SearchRequestCollector optimizer = queryParameters.getOptimizer(); - optimizer.searchWord(info.myName, - ReadAction.compute(() -> info.myLightMethod.getUseScope().intersectWith(scope)), - true, - info.myLightMethod); + @Override + public void processQuery( + @Nonnull ReferencesSearch.SearchParameters queryParameters, + @Nonnull Processor consumer + ) { + PsiElement element = queryParameters.getElementToSearch(); + if (element instanceof PsiRecordComponent recordComponent) { + SearchScope scope = queryParameters.getEffectiveSearchScope(); + RecordNavigationInfo info = findNavigationInfo(recordComponent); + if (info != null) { + SearchRequestCollector optimizer = queryParameters.getOptimizer(); + optimizer.searchWord( + info.myName, + ReadAction.compute(() -> info.myLightMethod.getUseScope().intersectWith(scope)), + true, + info.myLightMethod + ); - optimizer.searchWord(info.myName, - ReadAction.compute(() -> info.myLightField.getUseScope().intersectWith(scope)), - true, - info.myLightField); + optimizer.searchWord( + info.myName, + ReadAction.compute(() -> info.myLightField.getUseScope().intersectWith(scope)), + true, + info.myLightField + ); - PsiParameter parameter = info.myLightCompactConstructorParameter; - if (parameter != null) { - optimizer.searchWord(info.myName, - ReadAction.compute(() -> new LocalSearchScope(parameter.getDeclarationScope())), - true, - parameter); + PsiParameter parameter = info.myLightCompactConstructorParameter; + if (parameter != null) { + optimizer.searchWord( + info.myName, + ReadAction.compute(() -> new LocalSearchScope(parameter.getDeclarationScope())), + true, + parameter + ); + } + } } - } } - } - private static RecordNavigationInfo findNavigationInfo(PsiRecordComponent recordComponent) { - return ReadAction.compute(() -> { - String name = recordComponent.getName(); - PsiClass containingClass = recordComponent.getContainingClass(); - if (containingClass == null) return null; + private static RecordNavigationInfo findNavigationInfo(PsiRecordComponent recordComponent) { + return ReadAction.compute(() -> { + String name = recordComponent.getName(); + PsiClass containingClass = recordComponent.getContainingClass(); + if (containingClass == null) { + return null; + } - List methods = ContainerUtil.filter(containingClass.findMethodsByName(name, false), m -> m.getParameterList().isEmpty()); - if (methods.size() != 1) return null; + List methods = + ContainerUtil.filter(containingClass.findMethodsByName(name, false), m -> m.getParameterList().isEmpty()); + if (methods.size() != 1) { + return null; + } - PsiField field = containingClass.findFieldByName(name, false); - if (field == null) return null; + PsiField field = containingClass.findFieldByName(name, false); + if (field == null) { + return null; + } - PsiMethod compactConstructor = ContainerUtil.find(containingClass.getConstructors(), JavaPsiRecordUtil::isCompactConstructor); - PsiParameter parameter = compactConstructor != null - ? ContainerUtil.find(compactConstructor.getParameterList().getParameters(), p -> name.equals(p.getName())) - : null; - return new RecordNavigationInfo(methods.get(0), field, parameter, name); - }); - } + PsiMethod compactConstructor = ContainerUtil.find(containingClass.getConstructors(), JavaPsiRecordUtil::isCompactConstructor); + PsiParameter parameter = compactConstructor != null + ? ContainerUtil.find(compactConstructor.getParameterList().getParameters(), p -> name.equals(p.getName())) + : null; + return new RecordNavigationInfo(methods.get(0), field, parameter, name); + }); + } - private static final class RecordNavigationInfo { - @Nonnull - final PsiMethod myLightMethod; - @Nonnull - final PsiField myLightField; - @Nullable - final PsiParameter myLightCompactConstructorParameter; - @Nonnull - final String myName; + private static final class RecordNavigationInfo { + @Nonnull + final PsiMethod myLightMethod; + @Nonnull + final PsiField myLightField; + @Nullable + final PsiParameter myLightCompactConstructorParameter; + @Nonnull + final String myName; - private RecordNavigationInfo(@Nonnull PsiMethod lightMethod, - @Nonnull PsiField lightField, - @Nullable PsiParameter parameter, - @Nonnull String name) { - myLightMethod = lightMethod; - myLightField = lightField; - myLightCompactConstructorParameter = parameter; - myName = name; + private RecordNavigationInfo( + @Nonnull PsiMethod lightMethod, + @Nonnull PsiField lightField, + @Nullable PsiParameter parameter, + @Nonnull String name + ) { + myLightMethod = lightMethod; + myLightField = lightField; + myLightCompactConstructorParameter = parameter; + myName = name; + } } - } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodDeepestSuperSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodDeepestSuperSearcher.java index bf6ef11f0..93471d6c3 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodDeepestSuperSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodDeepestSuperSearcher.java @@ -23,6 +23,7 @@ import consulo.application.util.function.Processor; import jakarta.annotation.Nonnull; + import java.util.HashSet; import java.util.Set; @@ -31,40 +32,45 @@ */ @ExtensionImpl public class MethodDeepestSuperSearcher implements DeepestSuperMethodsSearchExecutor { - @Override - public boolean execute(@Nonnull PsiMethod method, @Nonnull Processor consumer) { - return processDeepestSuperMethods(method, consumer); - } - - public static boolean processDeepestSuperMethods(PsiMethod method, Processor consumer) { - final Set methods = new HashSet(); - methods.add(method); - return findDeepestSuperOrSelfSignature(method, methods, null, consumer); - } - - private static boolean findDeepestSuperOrSelfSignature(final PsiMethod method, Set set, Set guard, Processor processor) { - if (guard != null && !guard.add(method)) { - return true; + @Override + public boolean execute(@Nonnull PsiMethod method, @Nonnull Processor consumer) { + return processDeepestSuperMethods(method, consumer); } - PsiMethod[] supers = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiMethod[] compute() { - return method.findSuperMethods(); - } - }); - if (supers.length == 0 && set.add(method) && !processor.process(method)) { - return false; + public static boolean processDeepestSuperMethods(PsiMethod method, Processor consumer) { + final Set methods = new HashSet(); + methods.add(method); + return findDeepestSuperOrSelfSignature(method, methods, null, consumer); } - for (PsiMethod superMethod : supers) { - if (guard == null) { - guard = new HashSet(); - guard.add(method); - } - if (!findDeepestSuperOrSelfSignature(superMethod, set, guard, processor)) { - return false; - } + + private static boolean findDeepestSuperOrSelfSignature( + final PsiMethod method, + Set set, + Set guard, + Processor processor + ) { + if (guard != null && !guard.add(method)) { + return true; + } + PsiMethod[] supers = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiMethod[] compute() { + return method.findSuperMethods(); + } + }); + + if (supers.length == 0 && set.add(method) && !processor.process(method)) { + return false; + } + for (PsiMethod superMethod : supers) { + if (guard == null) { + guard = new HashSet(); + guard.add(method); + } + if (!findDeepestSuperOrSelfSignature(superMethod, set, guard, processor)) { + return false; + } + } + return true; } - return true; - } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodSuperSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodSuperSearcher.java index d23f1e6d7..2ca963b1d 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodSuperSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodSuperSearcher.java @@ -28,84 +28,76 @@ import consulo.logging.Logger; import jakarta.annotation.Nonnull; + import java.util.List; /** * @author ven */ @ExtensionImpl -public class MethodSuperSearcher implements SuperMethodsSearchExecutor -{ - private static final Logger LOG = Logger.getInstance(MethodSuperSearcher.class); +public class MethodSuperSearcher implements SuperMethodsSearchExecutor { + private static final Logger LOG = Logger.getInstance(MethodSuperSearcher.class); - @Override - public boolean execute(@Nonnull final SuperMethodsSearch.SearchParameters queryParameters, @Nonnull final Processor consumer) - { - final PsiClass parentClass = queryParameters.getPsiClass(); - final PsiMethod method = queryParameters.getMethod(); - return ApplicationManager.getApplication().runReadAction(new Computable() - { - @Override - public Boolean compute() - { - HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature(); + @Override + public boolean execute( + @Nonnull final SuperMethodsSearch.SearchParameters queryParameters, + @Nonnull final Processor consumer + ) { + final PsiClass parentClass = queryParameters.getPsiClass(); + final PsiMethod method = queryParameters.getMethod(); + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public Boolean compute() { + HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature(); - final boolean checkBases = queryParameters.isCheckBases(); - final boolean allowStaticMethod = queryParameters.isAllowStaticMethod(); - final List supers = signature.getSuperSignatures(); - for(HierarchicalMethodSignature superSignature : supers) - { - if(MethodSignatureUtil.isSubsignature(superSignature, signature)) - { - if(!addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer)) - { - return false; - } - } - } + final boolean checkBases = queryParameters.isCheckBases(); + final boolean allowStaticMethod = queryParameters.isAllowStaticMethod(); + final List supers = signature.getSuperSignatures(); + for (HierarchicalMethodSignature superSignature : supers) { + if (MethodSignatureUtil.isSubsignature(superSignature, signature)) { + if (!addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer)) { + return false; + } + } + } - return true; - } - }); - } + return true; + } + }); + } - private static boolean addSuperMethods(final HierarchicalMethodSignature signature, - final PsiMethod method, - final PsiClass parentClass, - final boolean allowStaticMethod, - final boolean checkBases, - final Processor consumer) - { - PsiMethod signatureMethod = signature.getMethod(); - PsiClass hisClass = signatureMethod.getContainingClass(); - if(parentClass == null || InheritanceUtil.isInheritorOrSelf(parentClass, hisClass, true)) - { - if(isAcceptable(signatureMethod, method, allowStaticMethod)) - { - if(parentClass != null && !parentClass.equals(hisClass) && !checkBases) - { - return true; - } - LOG.assertTrue(signatureMethod != method, method); // method != method.getsuper() - return consumer.process(signature); //no need to check super classes - } - } - for(HierarchicalMethodSignature superSignature : signature.getSuperSignatures()) - { - if(MethodSignatureUtil.isSubsignature(superSignature, signature)) - { - addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer); - } - } + private static boolean addSuperMethods( + final HierarchicalMethodSignature signature, + final PsiMethod method, + final PsiClass parentClass, + final boolean allowStaticMethod, + final boolean checkBases, + final Processor consumer + ) { + PsiMethod signatureMethod = signature.getMethod(); + PsiClass hisClass = signatureMethod.getContainingClass(); + if (parentClass == null || InheritanceUtil.isInheritorOrSelf(parentClass, hisClass, true)) { + if (isAcceptable(signatureMethod, method, allowStaticMethod)) { + if (parentClass != null && !parentClass.equals(hisClass) && !checkBases) { + return true; + } + LOG.assertTrue(signatureMethod != method, method); // method != method.getsuper() + return consumer.process(signature); //no need to check super classes + } + } + for (HierarchicalMethodSignature superSignature : signature.getSuperSignatures()) { + if (MethodSignatureUtil.isSubsignature(superSignature, signature)) { + addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer); + } + } - return true; - } + return true; + } - private static boolean isAcceptable(final PsiMethod superMethod, final PsiMethod method, final boolean allowStaticMethod) - { - boolean hisStatic = superMethod.hasModifierProperty(PsiModifier.STATIC); - return hisStatic == method.hasModifierProperty(PsiModifier.STATIC) && - (allowStaticMethod || !hisStatic) && - JavaPsiFacade.getInstance(method.getProject()).getResolveHelper().isAccessible(superMethod, method, null); - } + private static boolean isAcceptable(final PsiMethod superMethod, final PsiMethod method, final boolean allowStaticMethod) { + boolean hisStatic = superMethod.hasModifierProperty(PsiModifier.STATIC); + return hisStatic == method.hasModifierProperty(PsiModifier.STATIC) + && (allowStaticMethod || !hisStatic) + && JavaPsiFacade.getInstance(method.getProject()).getResolveHelper().isAccessible(superMethod, method, null); + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodUsagesSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodUsagesSearcher.java index d3cd62e35..40459a278 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodUsagesSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodUsagesSearcher.java @@ -20,6 +20,7 @@ import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.util.PsiUtil; import consulo.annotation.component.ExtensionImpl; +import consulo.application.Application; import consulo.application.ApplicationManager; import consulo.application.util.function.Computable; import consulo.application.util.function.Processor; @@ -42,95 +43,123 @@ */ @ExtensionImpl public class MethodUsagesSearcher extends QueryExecutorBase implements MethodReferencesSearchExecutor { - @Override - public void processQuery(@Nonnull final MethodReferencesSearch.SearchParameters p, @Nonnull final Processor consumer) { - final PsiMethod method = p.getMethod(); - final boolean[] isConstructor = new boolean[1]; - final PsiManager[] psiManager = new PsiManager[1]; - final String[] methodName = new String[1]; - final boolean[] isValueAnnotation = new boolean[1]; - final boolean[] needStrictSignatureSearch = new boolean[1]; - final boolean strictSignatureSearch = p.isStrictSignatureSearch(); - - final PsiClass aClass = resolveInReadAction(p.getProject(), new Computable() { - @Override - public PsiClass compute() { - PsiClass aClass = method.getContainingClass(); + @Override + public void processQuery( + @Nonnull final MethodReferencesSearch.SearchParameters p, + @Nonnull final Processor consumer + ) { + final PsiMethod method = p.getMethod(); + final boolean[] isConstructor = new boolean[1]; + final PsiManager[] psiManager = new PsiManager[1]; + final String[] methodName = new String[1]; + final boolean[] isValueAnnotation = new boolean[1]; + final boolean[] needStrictSignatureSearch = new boolean[1]; + final boolean strictSignatureSearch = p.isStrictSignatureSearch(); + + final PsiClass aClass = resolveInReadAction(p.getProject(), new Computable() { + @Override + public PsiClass compute() { + PsiClass aClass = method.getContainingClass(); + if (aClass == null) { + return null; + } + isConstructor[0] = method.isConstructor(); + psiManager[0] = aClass.getManager(); + methodName[0] = method.getName(); + isValueAnnotation[0] = PsiUtil.isAnnotationMethod(method) + && PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(methodName[0]) + && method.getParameterList().getParametersCount() == 0; + needStrictSignatureSearch[0] = strictSignatureSearch + && (aClass instanceof PsiAnonymousClass || aClass.hasModifierProperty(PsiModifier.FINAL) + || method.hasModifierProperty(PsiModifier.STATIC) || method.hasModifierProperty(PsiModifier.FINAL) + || method.hasModifierProperty(PsiModifier.PRIVATE)); + return aClass; + } + }); if (aClass == null) { - return null; + return; } - isConstructor[0] = method.isConstructor(); - psiManager[0] = aClass.getManager(); - methodName[0] = method.getName(); - isValueAnnotation[0] = PsiUtil.isAnnotationMethod(method) && - PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(methodName[0]) && - method.getParameterList().getParametersCount() == 0; - needStrictSignatureSearch[0] = strictSignatureSearch && (aClass instanceof PsiAnonymousClass || aClass.hasModifierProperty(PsiModifier.FINAL) || method.hasModifierProperty - (PsiModifier.STATIC) || method.hasModifierProperty(PsiModifier.FINAL) || method.hasModifierProperty(PsiModifier.PRIVATE)); - return aClass; - } - }); - if (aClass == null) { - return; - } - - final SearchRequestCollector collector = p.getOptimizer(); - - final SearchScope searchScope = resolveInReadAction(p.getProject(), new Computable() { - @Override - public SearchScope compute() { - return p.getEffectiveSearchScope(); - } - }); - if (searchScope == GlobalSearchScope.EMPTY_SCOPE) { - return; - } - if (isConstructor[0]) { - new ConstructorReferencesSearchHelper(psiManager[0]). - processConstructorReferences(consumer, method, aClass, searchScope, p.getProject(), false, strictSignatureSearch, collector); - } - - if (isValueAnnotation[0]) { - Processor refProcessor = PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer(consumer); - ReferencesSearch.search(aClass, searchScope).forEach(refProcessor); - } + final SearchRequestCollector collector = p.getOptimizer(); - if (needStrictSignatureSearch[0]) { - ReferencesSearch.searchOptimized(method, searchScope, false, collector, consumer); - return; - } + final SearchScope searchScope = resolveInReadAction(p.getProject(), new Computable() { + @Override + public SearchScope compute() { + return p.getEffectiveSearchScope(); + } + }); + if (searchScope == GlobalSearchScope.EMPTY_SCOPE) { + return; + } - if (StringUtil.isEmpty(methodName[0])) { - return; - } + if (isConstructor[0]) { + new ConstructorReferencesSearchHelper(psiManager[0]).processConstructorReferences( + consumer, + method, + aClass, + searchScope, + p.getProject(), + false, + strictSignatureSearch, + collector + ); + } - resolveInReadAction(p.getProject(), new Computable() { - @Override - public Void compute() { - final PsiMethod[] methods = strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(methodName[0], false); - SearchScope accessScope = methods[0].getUseScope(); - for (int i = 1; i < methods.length; i++) { - PsiMethod method1 = methods[i]; - accessScope = accessScope.union(method1.getUseScope()); + if (isValueAnnotation[0]) { + Processor refProcessor = + PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer(consumer); + ReferencesSearch.search(aClass, searchScope).forEach(refProcessor); } - SearchScope restrictedByAccessScope = searchScope.intersectWith(accessScope); + if (needStrictSignatureSearch[0]) { + ReferencesSearch.searchOptimized(method, searchScope, false, collector, consumer); + return; + } - short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES; - collector.searchWord(methodName[0], restrictedByAccessScope, searchContext, true, method, getTextOccurrenceProcessor(methods, aClass, strictSignatureSearch)); + if (StringUtil.isEmpty(methodName[0])) { + return; + } - SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccessScope, collector); - return null; - } - }); - } + resolveInReadAction(p.getProject(), new Computable() { + @Override + public Void compute() { + final PsiMethod[] methods = + strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(methodName[0], false); + SearchScope accessScope = methods[0].getUseScope(); + for (int i = 1; i < methods.length; i++) { + PsiMethod method1 = methods[i]; + accessScope = accessScope.union(method1.getUseScope()); + } + + SearchScope restrictedByAccessScope = searchScope.intersectWith(accessScope); + + short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES; + collector.searchWord( + methodName[0], + restrictedByAccessScope, + searchContext, + true, + method, + getTextOccurrenceProcessor(methods, aClass, strictSignatureSearch) + ); + + SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccessScope, collector); + return null; + } + }); + } - static T resolveInReadAction(@Nonnull Project p, @Nonnull Computable computable) { - return ApplicationManager.getApplication().isReadAccessAllowed() ? computable.compute() : DumbService.getInstance(p).runReadActionInSmartMode(computable); - } + static T resolveInReadAction(@Nonnull Project p, @Nonnull Computable computable) { + return Application.get().isReadAccessAllowed() + ? computable.compute() + : DumbService.getInstance(p).runReadActionInSmartMode(computable); + } - protected MethodTextOccurrenceProcessor getTextOccurrenceProcessor(PsiMethod[] methods, PsiClass aClass, boolean strictSignatureSearch) { - return new MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, methods); - } + protected MethodTextOccurrenceProcessor getTextOccurrenceProcessor( + PsiMethod[] methods, + PsiClass aClass, + boolean strictSignatureSearch + ) { + return new MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, methods); + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/PsiAnnotationMethodReferencesSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/PsiAnnotationMethodReferencesSearcher.java index 78a3484c2..0733b329b 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/PsiAnnotationMethodReferencesSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/PsiAnnotationMethodReferencesSearcher.java @@ -21,36 +21,42 @@ */ @ExtensionImpl public class PsiAnnotationMethodReferencesSearcher implements ReferencesSearchQueryExecutor { - @Override - public boolean execute(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull final Processor consumer) { - final PsiElement refElement = p.getElementToSearch(); - if (PsiUtil.isAnnotationMethod(refElement)) { - PsiMethod method = (PsiMethod)refElement; - if (PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) && method.getParameterList().getParametersCount() == 0) { - final Query query = ReferencesSearch.search(method.getContainingClass(), p.getScope(), p.isIgnoreAccessScope()); - return query.forEach(createImplicitDefaultAnnotationMethodConsumer(consumer)); - } - } - - return true; - } - - public static ReadActionProcessor createImplicitDefaultAnnotationMethodConsumer(final Processor consumer) { - return new ReadActionProcessor() { - @Override - public boolean processInReadAction(final PsiReference reference) { - if (reference instanceof PsiJavaCodeReferenceElement) { - PsiJavaCodeReferenceElement javaReference = (PsiJavaCodeReferenceElement)reference; - if (javaReference.getParent() instanceof PsiAnnotation) { - PsiNameValuePair[] members = ((PsiAnnotation)javaReference.getParent()).getParameterList().getAttributes(); - if (members.length == 1 && members[0].getNameIdentifier() == null) { - PsiReference t = members[0].getReference(); - if (t != null && !consumer.process(t)) return false; + @Override + public boolean execute(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull final Processor consumer) { + final PsiElement refElement = p.getElementToSearch(); + if (PsiUtil.isAnnotationMethod(refElement)) { + PsiMethod method = (PsiMethod)refElement; + if (PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) + && method.getParameterList().getParametersCount() == 0) { + final Query query = + ReferencesSearch.search(method.getContainingClass(), p.getScope(), p.isIgnoreAccessScope()); + return query.forEach(createImplicitDefaultAnnotationMethodConsumer(consumer)); } - } } + return true; - } - }; - } + } + + public static ReadActionProcessor createImplicitDefaultAnnotationMethodConsumer( + final Processor consumer + ) { + return new ReadActionProcessor() { + @Override + public boolean processInReadAction(final PsiReference reference) { + if (reference instanceof PsiJavaCodeReferenceElement) { + PsiJavaCodeReferenceElement javaReference = (PsiJavaCodeReferenceElement)reference; + if (javaReference.getParent() instanceof PsiAnnotation) { + PsiNameValuePair[] members = ((PsiAnnotation)javaReference.getParent()).getParameterList().getAttributes(); + if (members.length == 1 && members[0].getNameIdentifier() == null) { + PsiReference t = members[0].getReference(); + if (t != null && !consumer.process(t)) { + return false; + } + } + } + } + return true; + } + }; + } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SPIReferencesSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SPIReferencesSearcher.java index 001ae525d..f86a0a258 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SPIReferencesSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SPIReferencesSearcher.java @@ -36,58 +36,58 @@ @ExtensionImpl public class SPIReferencesSearcher extends QueryExecutorBase implements ReferencesSearchQueryExecutor { - public SPIReferencesSearcher() { - super(true); - } - - @Override - public void processQuery(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull final Processor consumer) { - final PsiElement element = p.getElementToSearch(); - if (!element.isValid()) { - return; + public SPIReferencesSearcher() { + super(true); } - final SearchScope scope = p.getEffectiveSearchScope(); - if (!(scope instanceof GlobalSearchScope)) { - return; - } + @Override + public void processQuery(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull final Processor consumer) { + final PsiElement element = p.getElementToSearch(); + if (!element.isValid()) { + return; + } + + final SearchScope scope = p.getEffectiveSearchScope(); + if (!(scope instanceof GlobalSearchScope)) { + return; + } - if (element instanceof PsiClass) { - final PsiClass aClass = (PsiClass)element; - final String jvmClassName = ClassUtil.getJVMClassName(aClass); + if (element instanceof PsiClass) { + final PsiClass aClass = (PsiClass)element; + final String jvmClassName = ClassUtil.getJVMClassName(aClass); - if (jvmClassName == null) { - return; - } - final PsiFile[] files = FilenameIndex.getFilesByName(aClass.getProject(), jvmClassName, (GlobalSearchScope)scope); - for (PsiFile file : files) { - if (file.getLanguage() == SPILanguage.INSTANCE) { - final PsiReference reference = file.getReference(); - if (reference != null) { - consumer.process(reference); - } + if (jvmClassName == null) { + return; + } + final PsiFile[] files = FilenameIndex.getFilesByName(aClass.getProject(), jvmClassName, (GlobalSearchScope)scope); + for (PsiFile file : files) { + if (file.getLanguage() == SPILanguage.INSTANCE) { + final PsiReference reference = file.getReference(); + if (reference != null) { + consumer.process(reference); + } + } + } } - } - } - else if (element instanceof PsiPackage) { - final String qualifiedName = ((PsiPackage)element).getQualifiedName(); - final Project project = element.getProject(); - final String[] filenames = FilenameIndex.getAllFilenames(project); - for (final String filename : filenames) { - if (filename.startsWith(qualifiedName + ".")) { - final PsiFile[] files = FilenameIndex.getFilesByName(project, filename, (GlobalSearchScope)scope); - for (PsiFile file : files) { - if (file.getLanguage() == SPILanguage.INSTANCE) { - final PsiReference[] references = file.getReferences(); - for (final PsiReference reference : references) { - if (reference.getCanonicalText().equals(qualifiedName)) { - consumer.process(reference); + else if (element instanceof PsiPackage) { + final String qualifiedName = ((PsiPackage)element).getQualifiedName(); + final Project project = element.getProject(); + final String[] filenames = FilenameIndex.getAllFilenames(project); + for (final String filename : filenames) { + if (filename.startsWith(qualifiedName + ".")) { + final PsiFile[] files = FilenameIndex.getFilesByName(project, filename, (GlobalSearchScope)scope); + for (PsiFile file : files) { + if (file.getLanguage() == SPILanguage.INSTANCE) { + final PsiReference[] references = file.getReferences(); + for (final PsiReference reference : references) { + if (reference.getCanonicalText().equals(qualifiedName)) { + consumer.process(reference); + } + } + } + } } - } } - } } - } } - } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SimpleAccessorReferenceSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SimpleAccessorReferenceSearcher.java index 9303e2218..d7d48f53c 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SimpleAccessorReferenceSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SimpleAccessorReferenceSearcher.java @@ -37,29 +37,33 @@ */ @ExtensionImpl public class SimpleAccessorReferenceSearcher extends QueryExecutorBase implements ReferencesSearchQueryExecutor { + public SimpleAccessorReferenceSearcher() { + super(true); + } - public SimpleAccessorReferenceSearcher() { - super(true); - } - - @Override - public void processQuery(@Nonnull ReferencesSearch.SearchParameters queryParameters, @Nonnull Processor consumer) { - PsiElement refElement = queryParameters.getElementToSearch(); - if (!(refElement instanceof PsiMethod)) return; + @Override + public void processQuery( + @Nonnull ReferencesSearch.SearchParameters queryParameters, + @Nonnull Processor consumer + ) { + PsiElement refElement = queryParameters.getElementToSearch(); + if (!(refElement instanceof PsiMethod)) { + return; + } - addPropertyAccessUsages((PsiMethod)refElement, queryParameters.getEffectiveSearchScope(), queryParameters.getOptimizer()); - } + addPropertyAccessUsages((PsiMethod)refElement, queryParameters.getEffectiveSearchScope(), queryParameters.getOptimizer()); + } - static void addPropertyAccessUsages(PsiMethod method, SearchScope scope, SearchRequestCollector collector) { - final String propertyName = PropertyUtil.getPropertyName(method); - if (StringUtil.isNotEmpty(propertyName)) { - SearchScope additional = GlobalSearchScope.EMPTY_SCOPE; - for (CustomPropertyScopeProvider provider : CustomPropertyScopeProvider.EP_NAME.getExtensionList()) { - additional = additional.union(provider.getScope(method.getProject())); - } - assert propertyName != null; - final SearchScope propScope = scope.intersectWith(method.getUseScope()).intersectWith(additional); - collector.searchWord(propertyName, propScope, UsageSearchContext.IN_FOREIGN_LANGUAGES, true, method); + static void addPropertyAccessUsages(PsiMethod method, SearchScope scope, SearchRequestCollector collector) { + final String propertyName = PropertyUtil.getPropertyName(method); + if (StringUtil.isNotEmpty(propertyName)) { + SearchScope additional = GlobalSearchScope.EMPTY_SCOPE; + for (CustomPropertyScopeProvider provider : CustomPropertyScopeProvider.EP_NAME.getExtensionList()) { + additional = additional.union(provider.getScope(method.getProject())); + } + assert propertyName != null; + final SearchScope propScope = scope.intersectWith(method.getUseScope()).intersectWith(additional); + collector.searchWord(propertyName, propScope, UsageSearchContext.IN_FOREIGN_LANGUAGES, true, method); + } } - } } diff --git a/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNameProvider.java b/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNameProvider.java index 7279eea51..97cfa82fc 100644 --- a/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNameProvider.java +++ b/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNameProvider.java @@ -24,139 +24,154 @@ */ @ExtensionAPI(ComponentScope.PROJECT) public interface PsiShortNameProvider { - /** - * Returns the list of files with the specified name. - * - * @param name the name of the files to find. - * @return the list of files in the project which have the specified name. - */ - @Nonnull - default PsiFile[] getFilesByName(@Nonnull String name) { - return PsiFile.EMPTY_ARRAY; - } - - /** - * Returns the list of names of all files in the project. - * - * @return the list of all file names in the project. - */ - @Nonnull - default String[] getAllFileNames() { - return ArrayUtil.EMPTY_STRING_ARRAY; - } - - /** - * Returns the list of all classes with the specified name in the specified scope. - * - * @param name the non-qualified name of the classes to find. - * @param scope the scope in which classes are searched. - * @return the list of found classes. - */ - @Nonnull - public abstract PsiClass[] getClassesByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); - - /** - * Returns the list of names of all classes in the project and - * (optionally) libraries. - * - * @return the list of all class names. - */ - @Nonnull - public abstract String[] getAllClassNames(); - - default boolean processAllClassNames(Processor processor) { - return ContainerUtil.process(getAllClassNames(), processor); - } - - default boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - return ContainerUtil.process(getAllClassNames(), processor); - } - - /** - * Adds the names of all classes in the project and (optionally) libraries - * to the specified set. - * - * @param dest the set to add the names to. - */ - public abstract void getAllClassNames(@Nonnull HashSet dest); - - /** - * Returns the list of all methods with the specified name in the specified scope. - * - * @param name the name of the methods to find. - * @param scope the scope in which methods are searched. - * @return the list of found methods. - */ - @Nonnull - public abstract PsiMethod[] getMethodsByName(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope); - - @Nonnull - public abstract PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); - - @Nonnull - public abstract PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); - - public abstract boolean processMethodsWithName(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, - @Nonnull Processor processor); - - public abstract boolean processMethodsWithName(@NonNls @Nonnull String name, @Nonnull Processor processor, - @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter); - - default boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - return ContainerUtil.process(getAllFieldNames(), processor); - } - - default boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - return ContainerUtil.process(getAllFieldNames(), processor); - } - - /** - * Returns the list of names of all methods in the project and - * (optionally) libraries. - * - * @return the list of all method names. - */ - @Nonnull - public abstract String[] getAllMethodNames(); - - /** - * Adds the names of all methods in the project and (optionally) libraries - * to the specified set. - * - * @param set the set to add the names to. - */ - public abstract void getAllMethodNames(@Nonnull HashSet set); - - /** - * Returns the list of all fields with the specified name in the specified scope. - * - * @param name the name of the fields to find. - * @param scope the scope in which fields are searched. - * @return the list of found fields. - */ - @Nonnull - public abstract PsiField[] getFieldsByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); - - /** - * Returns the list of names of all fields in the project and - * (optionally) libraries. - * - * @return the list of all field names. - */ - @Nonnull - public abstract String[] getAllFieldNames(); - - /** - * Adds the names of all methods in the project and (optionally) libraries - * to the specified set. - * - * @param set the set to add the names to. - */ - public abstract void getAllFieldNames(@Nonnull HashSet set); - - public abstract boolean processFieldsWithName(@Nonnull String name, @Nonnull Processor processor, - @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter); - - public abstract boolean processClassesWithName(@Nonnull String name, @Nonnull Processor processor, - @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter); + /** + * Returns the list of files with the specified name. + * + * @param name the name of the files to find. + * @return the list of files in the project which have the specified name. + */ + @Nonnull + default PsiFile[] getFilesByName(@Nonnull String name) { + return PsiFile.EMPTY_ARRAY; + } + + /** + * Returns the list of names of all files in the project. + * + * @return the list of all file names in the project. + */ + @Nonnull + default String[] getAllFileNames() { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + + /** + * Returns the list of all classes with the specified name in the specified scope. + * + * @param name the non-qualified name of the classes to find. + * @param scope the scope in which classes are searched. + * @return the list of found classes. + */ + @Nonnull + public abstract PsiClass[] getClassesByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); + + /** + * Returns the list of names of all classes in the project and + * (optionally) libraries. + * + * @return the list of all class names. + */ + @Nonnull + public abstract String[] getAllClassNames(); + + default boolean processAllClassNames(Processor processor) { + return ContainerUtil.process(getAllClassNames(), processor); + } + + default boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + return ContainerUtil.process(getAllClassNames(), processor); + } + + /** + * Adds the names of all classes in the project and (optionally) libraries + * to the specified set. + * + * @param dest the set to add the names to. + */ + public abstract void getAllClassNames(@Nonnull HashSet dest); + + /** + * Returns the list of all methods with the specified name in the specified scope. + * + * @param name the name of the methods to find. + * @param scope the scope in which methods are searched. + * @return the list of found methods. + */ + @Nonnull + public abstract PsiMethod[] getMethodsByName(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope); + + @Nonnull + public abstract PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); + + @Nonnull + public abstract PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); + + public abstract boolean processMethodsWithName( + @NonNls @Nonnull String name, + @Nonnull GlobalSearchScope scope, + @Nonnull Processor processor + ); + + public abstract boolean processMethodsWithName( + @NonNls @Nonnull String name, + @Nonnull Processor processor, + @Nonnull GlobalSearchScope scope, + @Nullable IdFilter filter + ); + + default boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + return ContainerUtil.process(getAllFieldNames(), processor); + } + + default boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + return ContainerUtil.process(getAllFieldNames(), processor); + } + + /** + * Returns the list of names of all methods in the project and + * (optionally) libraries. + * + * @return the list of all method names. + */ + @Nonnull + public abstract String[] getAllMethodNames(); + + /** + * Adds the names of all methods in the project and (optionally) libraries + * to the specified set. + * + * @param set the set to add the names to. + */ + public abstract void getAllMethodNames(@Nonnull HashSet set); + + /** + * Returns the list of all fields with the specified name in the specified scope. + * + * @param name the name of the fields to find. + * @param scope the scope in which fields are searched. + * @return the list of found fields. + */ + @Nonnull + public abstract PsiField[] getFieldsByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); + + /** + * Returns the list of names of all fields in the project and + * (optionally) libraries. + * + * @return the list of all field names. + */ + @Nonnull + public abstract String[] getAllFieldNames(); + + /** + * Adds the names of all methods in the project and (optionally) libraries + * to the specified set. + * + * @param set the set to add the names to. + */ + public abstract void getAllFieldNames(@Nonnull HashSet set); + + public abstract boolean processFieldsWithName( + @Nonnull String name, + @Nonnull Processor processor, + @Nonnull GlobalSearchScope scope, + @Nullable IdFilter filter + ); + + public abstract boolean processClassesWithName( + @Nonnull String name, + @Nonnull Processor processor, + @Nonnull GlobalSearchScope scope, + @Nullable IdFilter filter + ); } diff --git a/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNamesCache.java b/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNamesCache.java index d39b6bd08..f3311f4e6 100644 --- a/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNamesCache.java +++ b/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNamesCache.java @@ -32,6 +32,7 @@ import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.util.HashSet; /** @@ -40,150 +41,158 @@ */ @ServiceAPI(ComponentScope.PROJECT) public abstract class PsiShortNamesCache { - /** - * Return the composite short names cache, uniting all short name cache instances registered via extensions. - * - * @param project the project to return the cache for. - * @return the cache instance. - */ - - public static PsiShortNamesCache getInstance(Project project) { - return ServiceManager.getService(project, PsiShortNamesCache.class); - } - - /** - * Returns the list of files with the specified name. - * - * @param name the name of the files to find. - * @return the list of files in the project which have the specified name. - */ - @Nonnull - public PsiFile[] getFilesByName(@Nonnull String name) { - return PsiFile.EMPTY_ARRAY; - } - - /** - * Returns the list of names of all files in the project. - * - * @return the list of all file names in the project. - */ - @Nonnull - public String[] getAllFileNames() { - return ArrayUtil.EMPTY_STRING_ARRAY; - } - - /** - * Returns the list of all classes with the specified name in the specified scope. - * - * @param name the non-qualified name of the classes to find. - * @param scope the scope in which classes are searched. - * @return the list of found classes. - */ - @Nonnull - public abstract PsiClass[] getClassesByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); - - /** - * Returns the list of names of all classes in the project and - * (optionally) libraries. - * - * @return the list of all class names. - */ - @Nonnull - public abstract String[] getAllClassNames(); - - public boolean processAllClassNames(Processor processor) { - return ContainerUtil.process(getAllClassNames(), processor); - } - - public boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - return ContainerUtil.process(getAllClassNames(), processor); - } - - /** - * Adds the names of all classes in the project and (optionally) libraries - * to the specified set. - * - * @param dest the set to add the names to. - */ - public abstract void getAllClassNames(@Nonnull HashSet dest); - - /** - * Returns the list of all methods with the specified name in the specified scope. - * - * @param name the name of the methods to find. - * @param scope the scope in which methods are searched. - * @return the list of found methods. - */ - @Nonnull - public abstract PsiMethod[] getMethodsByName(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope); - - @Nonnull - public abstract PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); - - @Nonnull - public abstract PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); - - public abstract boolean processMethodsWithName(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, - @Nonnull Processor processor); - - public abstract boolean processMethodsWithName(@NonNls @Nonnull String name, @Nonnull Processor processor, - @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter); - - public boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - return ContainerUtil.process(getAllFieldNames(), processor); - } - - public boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { - return ContainerUtil.process(getAllFieldNames(), processor); - } - - /** - * Returns the list of names of all methods in the project and - * (optionally) libraries. - * - * @return the list of all method names. - */ - @Nonnull - public abstract String[] getAllMethodNames(); - - /** - * Adds the names of all methods in the project and (optionally) libraries - * to the specified set. - * - * @param set the set to add the names to. - */ - public abstract void getAllMethodNames(@Nonnull HashSet set); - - /** - * Returns the list of all fields with the specified name in the specified scope. - * - * @param name the name of the fields to find. - * @param scope the scope in which fields are searched. - * @return the list of found fields. - */ - @Nonnull - public abstract PsiField[] getFieldsByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); - - /** - * Returns the list of names of all fields in the project and - * (optionally) libraries. - * - * @return the list of all field names. - */ - @Nonnull - public abstract String[] getAllFieldNames(); - - /** - * Adds the names of all methods in the project and (optionally) libraries - * to the specified set. - * - * @param set the set to add the names to. - */ - public abstract void getAllFieldNames(@Nonnull HashSet set); - - public abstract boolean processFieldsWithName(@Nonnull String name, @Nonnull Processor processor, - @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter); - - public abstract boolean processClassesWithName(@Nonnull String name, @Nonnull Processor processor, - @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter); + /** + * Return the composite short names cache, uniting all short name cache instances registered via extensions. + * + * @param project the project to return the cache for. + * @return the cache instance. + */ + + public static PsiShortNamesCache getInstance(Project project) { + return ServiceManager.getService(project, PsiShortNamesCache.class); + } + + /** + * Returns the list of files with the specified name. + * + * @param name the name of the files to find. + * @return the list of files in the project which have the specified name. + */ + @Nonnull + public PsiFile[] getFilesByName(@Nonnull String name) { + return PsiFile.EMPTY_ARRAY; + } + + /** + * Returns the list of names of all files in the project. + * + * @return the list of all file names in the project. + */ + @Nonnull + public String[] getAllFileNames() { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + + /** + * Returns the list of all classes with the specified name in the specified scope. + * + * @param name the non-qualified name of the classes to find. + * @param scope the scope in which classes are searched. + * @return the list of found classes. + */ + @Nonnull + public abstract PsiClass[] getClassesByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); + + /** + * Returns the list of names of all classes in the project and + * (optionally) libraries. + * + * @return the list of all class names. + */ + @Nonnull + public abstract String[] getAllClassNames(); + + public boolean processAllClassNames(Processor processor) { + return ContainerUtil.process(getAllClassNames(), processor); + } + + public boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + return ContainerUtil.process(getAllClassNames(), processor); + } + + /** + * Adds the names of all classes in the project and (optionally) libraries + * to the specified set. + * + * @param dest the set to add the names to. + */ + public abstract void getAllClassNames(@Nonnull HashSet dest); + + /** + * Returns the list of all methods with the specified name in the specified scope. + * + * @param name the name of the methods to find. + * @param scope the scope in which methods are searched. + * @return the list of found methods. + */ + @Nonnull + public abstract PsiMethod[] getMethodsByName(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope); + + @Nonnull + public abstract PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); + + @Nonnull + public abstract PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); + + public abstract boolean processMethodsWithName( + @NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, + @Nonnull Processor processor + ); + + public abstract boolean processMethodsWithName( + @NonNls @Nonnull String name, @Nonnull Processor processor, + @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter + ); + + public boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + return ContainerUtil.process(getAllFieldNames(), processor); + } + + public boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + return ContainerUtil.process(getAllFieldNames(), processor); + } + + /** + * Returns the list of names of all methods in the project and + * (optionally) libraries. + * + * @return the list of all method names. + */ + @Nonnull + public abstract String[] getAllMethodNames(); + + /** + * Adds the names of all methods in the project and (optionally) libraries + * to the specified set. + * + * @param set the set to add the names to. + */ + public abstract void getAllMethodNames(@Nonnull HashSet set); + + /** + * Returns the list of all fields with the specified name in the specified scope. + * + * @param name the name of the fields to find. + * @param scope the scope in which fields are searched. + * @return the list of found fields. + */ + @Nonnull + public abstract PsiField[] getFieldsByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); + + /** + * Returns the list of names of all fields in the project and + * (optionally) libraries. + * + * @return the list of all field names. + */ + @Nonnull + public abstract String[] getAllFieldNames(); + + /** + * Adds the names of all methods in the project and (optionally) libraries + * to the specified set. + * + * @param set the set to add the names to. + */ + public abstract void getAllFieldNames(@Nonnull HashSet set); + + public abstract boolean processFieldsWithName( + @Nonnull String name, @Nonnull Processor processor, + @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter + ); + + public abstract boolean processClassesWithName( + @Nonnull String name, @Nonnull Processor processor, + @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter + ); } diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInspection/inferNullity/InferNullityAnnotationsAction.java b/plugin/src/main/java/com/intellij/java/impl/codeInspection/inferNullity/InferNullityAnnotationsAction.java index a2bc32163..30e7944b0 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInspection/inferNullity/InferNullityAnnotationsAction.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInspection/inferNullity/InferNullityAnnotationsAction.java @@ -75,119 +75,127 @@ @ActionImpl(id = "InferNullity", parents = @ActionParentRef(value = @ActionRef(id = IdeActions.ACTION_CODE_MENU), relatedToAction = @ActionRef(id = "AnalyzeStacktrace"), anchor = ActionRefAnchor.AFTER)) public class InferNullityAnnotationsAction extends BaseAnalysisAction { - private static final String INFER_NULLITY_ANNOTATIONS = "Infer Nullity Annotations"; - private static final String ANNOTATE_LOCAL_VARIABLES = "annotate.local.variables"; + private static final String INFER_NULLITY_ANNOTATIONS = "Infer Nullity Annotations"; + private static final String ANNOTATE_LOCAL_VARIABLES = "annotate.local.variables"; - private CheckBox myAnnotateLocalVariablesCb; + private CheckBox myAnnotateLocalVariablesCb; - public InferNullityAnnotationsAction() { - super("Infer Nullity", INFER_NULLITY_ANNOTATIONS); - } + public InferNullityAnnotationsAction() { + super("Infer Nullity", INFER_NULLITY_ANNOTATIONS); + } - @Override - @RequiredUIAccess - protected void analyze(@Nonnull final Project project, @Nonnull final AnalysisScope scope) { - boolean annotateLocaVars = myAnnotateLocalVariablesCb.getValueOrError(); - PropertiesComponent.getInstance().setValue(ANNOTATE_LOCAL_VARIABLES, annotateLocaVars); - myAnnotateLocalVariablesCb = null; + @Override + @RequiredUIAccess + protected void analyze(@Nonnull final Project project, @Nonnull final AnalysisScope scope) { + boolean annotateLocaVars = myAnnotateLocalVariablesCb.getValueOrError(); + PropertiesComponent.getInstance().setValue(ANNOTATE_LOCAL_VARIABLES, annotateLocaVars); + myAnnotateLocalVariablesCb = null; - final ProgressManager progressManager = ProgressManager.getInstance(); - final Set modulesWithoutAnnotations = new HashSet<>(); - final Set modulesWithLL = new HashSet<>(); - final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); - final String defaultNullable = NullableNotNullManager.getInstance(project).getDefaultNullable(); - final int[] fileCount = new int[]{0}; - if (!progressManager.runProcessWithProgressSynchronously(() -> scope.accept(new PsiElementVisitor() { - final private Set processed = new HashSet<>(); + final ProgressManager progressManager = ProgressManager.getInstance(); + final Set modulesWithoutAnnotations = new HashSet<>(); + final Set modulesWithLL = new HashSet<>(); + final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); + final String defaultNullable = NullableNotNullManager.getInstance(project).getDefaultNullable(); + final int[] fileCount = new int[]{0}; + if (!progressManager.runProcessWithProgressSynchronously(() -> scope.accept(new PsiElementVisitor() { + final private Set processed = new HashSet<>(); - @Override - @RequiredReadAction - public void visitFile(PsiFile file) { - fileCount[0]++; - final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); - if (progressIndicator != null) { - final VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile != null) { - progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project)); - } - progressIndicator.setTextValue(AnalysisScopeLocalize.scanningScopeProgressTitle()); + @Override + @RequiredReadAction + public void visitFile(PsiFile file) { + fileCount[0]++; + final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + if (progressIndicator != null) { + final VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile != null) { + progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project)); + } + progressIndicator.setTextValue(AnalysisScopeLocalize.scanningScopeProgressTitle()); + } + if (!(file instanceof PsiJavaFile)) { + return; + } + final Module module = file.getModule(); + if (module != null && processed.add(module)) { + if (PsiUtil.getLanguageLevel(file).compareTo(LanguageLevel.JDK_1_5) < 0) { + modulesWithLL.add(module); + } + else if (javaPsiFacade.findClass( + defaultNullable, + GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) + ) == null) { + modulesWithoutAnnotations.add(module); + } + } + } + }), "Check Applicability...", true, project)) { + return; } - if (!(file instanceof PsiJavaFile)) { - return; + if (!modulesWithLL.isEmpty()) { + Messages.showErrorDialog( + project, + "Infer Nullity Annotations requires the project language level be set to 1.5 or greater.", + INFER_NULLITY_ANNOTATIONS + ); + return; } - final Module module = file.getModule(); - if (module != null && processed.add(module)) { - if (PsiUtil.getLanguageLevel(file).compareTo(LanguageLevel.JDK_1_5) < 0) { - modulesWithLL.add(module); - } - else if (javaPsiFacade.findClass(defaultNullable, GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module)) == null) { - modulesWithoutAnnotations.add(module); - } + if (!modulesWithoutAnnotations.isEmpty()) { + if (addAnnotationsDependency(project, modulesWithoutAnnotations, defaultNullable, INFER_NULLITY_ANNOTATIONS)) { + restartAnalysis(project, scope); + } + return; + } + PsiDocumentManager.getInstance(project).commitAllDocuments(); + final UsageInfo[] usageInfos = findUsages(annotateLocaVars, project, scope, fileCount[0]); + if (usageInfos == null) { + return; } - } - }), "Check Applicability...", true, project)) { - return; - } - if (!modulesWithLL.isEmpty()) { - Messages.showErrorDialog( - project, - "Infer Nullity Annotations requires the project language level be set to 1.5 or greater.", - INFER_NULLITY_ANNOTATIONS - ); - return; - } - if (!modulesWithoutAnnotations.isEmpty()) { - if (addAnnotationsDependency(project, modulesWithoutAnnotations, defaultNullable, INFER_NULLITY_ANNOTATIONS)) { - restartAnalysis(project, scope); - } - return; - } - PsiDocumentManager.getInstance(project).commitAllDocuments(); - final UsageInfo[] usageInfos = findUsages(annotateLocaVars, project, scope, fileCount[0]); - if (usageInfos == null) { - return; - } - - processUsages(annotateLocaVars, project, scope, usageInfos); - } - protected void processUsages(boolean annotateLocaVars, @Nonnull Project project, @Nonnull AnalysisScope scope, @Nonnull UsageInfo[] usageInfos) { - if (usageInfos.length < 5) { - applyRunnable(project, () -> usageInfos).run(); - } - else { - showUsageView(annotateLocaVars, project, usageInfos, scope); + processUsages(annotateLocaVars, project, scope, usageInfos); } - } - @RequiredUIAccess - public static boolean addAnnotationsDependency( - @Nonnull final Project project, - @Nonnull final Set modulesWithoutAnnotations, - @Nonnull String annoFQN, - final String title - ) { - final Library annotationsLib = LibraryUtil.findLibraryByClass(annoFQN, project); - if (annotationsLib != null) { - @NonNls - String message = "Module" + (modulesWithoutAnnotations.size() == 1 ? " " : "s "); - message += StringUtil.join(modulesWithoutAnnotations, Module::getName, ", "); - message += (modulesWithoutAnnotations.size() == 1 ? " doesn't" : " don't"); - message += " refer to the existing '" + annotationsLib.getName() + "' library" + - " with Consulo nullity annotations. Would you like to add the dependenc"; - message += (modulesWithoutAnnotations.size() == 1 ? "y" : "ies") + " now?"; - if (Messages.showOkCancelDialog(project, message, title, UIUtil.getErrorIcon()) == Messages.OK) { - project.getApplication().runWriteAction(() -> - { - for (Module module : modulesWithoutAnnotations) { - ModuleRootModificationUtil.addDependency(module, annotationsLib); - } - }); - return true; - } - return false; + protected void processUsages( + boolean annotateLocaVars, + @Nonnull Project project, + @Nonnull AnalysisScope scope, + @Nonnull UsageInfo[] usageInfos + ) { + if (usageInfos.length < 5) { + applyRunnable(project, () -> usageInfos).run(); + } + else { + showUsageView(annotateLocaVars, project, usageInfos, scope); + } } + @RequiredUIAccess + public static boolean addAnnotationsDependency( + @Nonnull final Project project, + @Nonnull final Set modulesWithoutAnnotations, + @Nonnull String annoFQN, + final String title + ) { + final Library annotationsLib = LibraryUtil.findLibraryByClass(annoFQN, project); + if (annotationsLib != null) { + @NonNls + String message = "Module" + (modulesWithoutAnnotations.size() == 1 ? " " : "s "); + message += StringUtil.join(modulesWithoutAnnotations, Module::getName, ", "); + message += (modulesWithoutAnnotations.size() == 1 ? " doesn't" : " don't"); + message += " refer to the existing '" + annotationsLib.getName() + "' library" + + " with Consulo nullity annotations. Would you like to add the dependenc"; + message += (modulesWithoutAnnotations.size() == 1 ? "y" : "ies") + " now?"; + if (Messages.showOkCancelDialog(project, message, title, UIUtil.getErrorIcon()) == Messages.OK) { + project.getApplication().runWriteAction(() -> + { + for (Module module : modulesWithoutAnnotations) { + ModuleRootModificationUtil.addDependency(module, annotationsLib); + } + }); + return true; + } + return false; + } + /*if (Messages.showOkCancelDialog(project, "It is required that JetBrains annotations" + " be available in all your project sources.\n\nYou will need to add annotations.jar as a library. " + "It is possible to configure custom JAR\nin e.g. Constant Conditions & Exceptions inspection or use JetBrains annotations available in installation. " + "\nIntelliJ IDEA nullity " + "annotations are freely usable and redistributable under the Apache 2.0 license.\nWould you like to do it now?", title, Messages.getErrorIcon()) == Messages.OK) @@ -197,168 +205,191 @@ public static boolean addAnnotationsDependency( , DependencyScope.COMPILE); return true; } */ - return false; - } + return false; + } - @Nullable - protected UsageInfo[] findUsages(boolean annotateLocaVars, @Nonnull final Project project, @Nonnull final AnalysisScope scope, final int fileCount) { - final NullityInferrer inferrer = new NullityInferrer(annotateLocaVars, project); - final PsiManager psiManager = PsiManager.getInstance(project); - final Runnable searchForUsages = () -> scope.accept(new PsiElementVisitor() { - int myFileCount; + @Nullable + protected UsageInfo[] findUsages( + boolean annotateLocaVars, + @Nonnull final Project project, + @Nonnull final AnalysisScope scope, + final int fileCount + ) { + final NullityInferrer inferrer = new NullityInferrer(annotateLocaVars, project); + final PsiManager psiManager = PsiManager.getInstance(project); + final Runnable searchForUsages = () -> scope.accept(new PsiElementVisitor() { + int myFileCount; - @Override - public void visitFile(final PsiFile file) { - myFileCount++; - final VirtualFile virtualFile = file.getVirtualFile(); - final FileViewProvider viewProvider = psiManager.findViewProvider(virtualFile); - final Document document = viewProvider == null ? null : viewProvider.getDocument(); - if (document == null || virtualFile.getFileType().isBinary()) { - return; //do not inspect binary files - } - final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); - if (progressIndicator != null) { - progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project)); - progressIndicator.setFraction(((double)myFileCount) / fileCount); + @Override + public void visitFile(final PsiFile file) { + myFileCount++; + final VirtualFile virtualFile = file.getVirtualFile(); + final FileViewProvider viewProvider = psiManager.findViewProvider(virtualFile); + final Document document = viewProvider == null ? null : viewProvider.getDocument(); + if (document == null || virtualFile.getFileType().isBinary()) { + return; //do not inspect binary files + } + final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + if (progressIndicator != null) { + progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project)); + progressIndicator.setFraction(((double)myFileCount) / fileCount); + } + if (file instanceof PsiJavaFile) { + inferrer.collect(file); + } + } + }); + if (project.getApplication().isDispatchThread()) { + if (!ProgressManager.getInstance() + .runProcessWithProgressSynchronously(searchForUsages, INFER_NULLITY_ANNOTATIONS, true, project)) { + return null; + } } - if (file instanceof PsiJavaFile) { - inferrer.collect(file); + else { + searchForUsages.run(); } - } - }); - if (project.getApplication().isDispatchThread()) { - if (!ProgressManager.getInstance() - .runProcessWithProgressSynchronously(searchForUsages, INFER_NULLITY_ANNOTATIONS, true, project)) { - return null; - } - } - else { - searchForUsages.run(); + + final List usages = new ArrayList<>(); + inferrer.collect(usages); + return usages.toArray(new UsageInfo[usages.size()]); } - final List usages = new ArrayList<>(); - inferrer.collect(usages); - return usages.toArray(new UsageInfo[usages.size()]); - } + private static Runnable applyRunnable(final Project project, final Computable computable) { + return () -> + { + final LocalHistoryAction action = LocalHistory.getInstance().startAction(INFER_NULLITY_ANNOTATIONS); + try { + new WriteCommandAction(project, INFER_NULLITY_ANNOTATIONS) { + @Override + protected void run(@Nonnull Result result) throws Throwable { + final UsageInfo[] infos = computable.compute(); + if (infos.length > 0) { - private static Runnable applyRunnable(final Project project, final Computable computable) { - return () -> - { - final LocalHistoryAction action = LocalHistory.getInstance().startAction(INFER_NULLITY_ANNOTATIONS); - try { - new WriteCommandAction(project, INFER_NULLITY_ANNOTATIONS) { - @Override - protected void run(@Nonnull Result result) throws Throwable { - final UsageInfo[] infos = computable.compute(); - if (infos.length > 0) { + final Set elements = new LinkedHashSet<>(); + for (UsageInfo info : infos) { + final PsiElement element = info.getElement(); + if (element != null) { + ContainerUtil.addIfNotNull(elements, element.getContainingFile()); + } + } + if (!FileModificationService.getInstance().preparePsiElementsForWrite(elements)) { + return; + } - final Set elements = new LinkedHashSet<>(); - for (UsageInfo info : infos) { - final PsiElement element = info.getElement(); - if (element != null) { - ContainerUtil.addIfNotNull(elements, element.getContainingFile()); - } - } - if (!FileModificationService.getInstance().preparePsiElementsForWrite(elements)) { - return; - } + final SequentialModalProgressTask progressTask = + new SequentialModalProgressTask(project, INFER_NULLITY_ANNOTATIONS, false); + progressTask.setMinIterationTime(200); + progressTask.setTask(new AnnotateTask(project, progressTask, infos)); + ProgressManager.getInstance().run(progressTask); + } + else { + NullityInferrer.nothingFoundMessage(project); + } + } + }.execute(); + } + finally { + action.finish(); + } + }; + } - final SequentialModalProgressTask progressTask = new SequentialModalProgressTask(project, INFER_NULLITY_ANNOTATIONS, false); - progressTask.setMinIterationTime(200); - progressTask.setTask(new AnnotateTask(project, progressTask, infos)); - ProgressManager.getInstance().run(progressTask); + @RequiredUIAccess + protected void restartAnalysis(final Project project, final AnalysisScope scope) { + DumbService.getInstance(project).smartInvokeLater(() -> { + if (DumbService.isDumb(project)) { + restartAnalysis(project, scope); } else { - NullityInferrer.nothingFoundMessage(project); + analyze(project, scope); } - } - }.execute(); - } - finally { - action.finish(); - } - }; - } - - @RequiredUIAccess - protected void restartAnalysis(final Project project, final AnalysisScope scope) { - DumbService.getInstance(project).smartInvokeLater(() -> { - if (DumbService.isDumb(project)) { - restartAnalysis(project, scope); - } - else { - analyze(project, scope); - } - }); - } - - private void showUsageView(boolean annotateLocaVars, @Nonnull Project project, final UsageInfo[] usageInfos, @Nonnull AnalysisScope scope) { - final UsageTarget[] targets = UsageTarget.EMPTY_ARRAY; - final Ref convertUsagesRef = new Ref<>(); - if (!ProgressManager.getInstance().runProcessWithProgressSynchronously( - () -> project.getApplication().runReadAction(() -> convertUsagesRef.set(UsageInfo2UsageAdapter.convert(usageInfos))), - "Preprocess Usages", - true, - project - )) { - return; + }); } - if (convertUsagesRef.isNull()) { - return; - } - final Usage[] usages = convertUsagesRef.get(); + private void showUsageView( + boolean annotateLocaVars, + @Nonnull Project project, + final UsageInfo[] usageInfos, + @Nonnull AnalysisScope scope + ) { + final UsageTarget[] targets = UsageTarget.EMPTY_ARRAY; + final Ref convertUsagesRef = new Ref<>(); + if (!ProgressManager.getInstance().runProcessWithProgressSynchronously( + () -> project.getApplication().runReadAction(() -> convertUsagesRef.set(UsageInfo2UsageAdapter.convert(usageInfos))), + "Preprocess Usages", + true, + project + )) { + return; + } - final UsageViewPresentation presentation = new UsageViewPresentation(); - presentation.setTabText("Infer Nullity Preview"); - presentation.setShowReadOnlyStatusAsRed(true); - presentation.setShowCancelButton(true); - presentation.setUsagesString(RefactoringLocalize.usageviewUsagestext().get()); + if (convertUsagesRef.isNull()) { + return; + } + final Usage[] usages = convertUsagesRef.get(); - final UsageView usageView = - UsageViewManager.getInstance(project).showUsages(targets, usages, presentation, rerunFactory(annotateLocaVars, project, scope)); + final UsageViewPresentation presentation = new UsageViewPresentation(); + presentation.setTabText("Infer Nullity Preview"); + presentation.setShowReadOnlyStatusAsRed(true); + presentation.setShowCancelButton(true); + presentation.setUsagesString(RefactoringLocalize.usageviewUsagestext().get()); - final Runnable refactoringRunnable = applyRunnable(project, () -> - { - final Set infos = UsageViewUtil.getNotExcludedUsageInfos(usageView); - return infos.toArray(new UsageInfo[infos.size()]); - }); + final UsageView usageView = + UsageViewManager.getInstance(project).showUsages(targets, usages, presentation, rerunFactory(annotateLocaVars, project, scope)); - String canNotMakeString = - "Cannot perform operation.\nThere were changes in code after usages have been found.\nPlease perform operation search again."; + final Runnable refactoringRunnable = applyRunnable(project, () -> + { + final Set infos = UsageViewUtil.getNotExcludedUsageInfos(usageView); + return infos.toArray(new UsageInfo[infos.size()]); + }); - usageView.addPerformOperationAction(refactoringRunnable, INFER_NULLITY_ANNOTATIONS, canNotMakeString, INFER_NULLITY_ANNOTATIONS, false); - } + String canNotMakeString = + "Cannot perform operation.\nThere were changes in code after usages have been found.\nPlease perform operation search again."; + + usageView.addPerformOperationAction( + refactoringRunnable, + INFER_NULLITY_ANNOTATIONS, + canNotMakeString, + INFER_NULLITY_ANNOTATIONS, + false + ); + } - @Nonnull - private Supplier rerunFactory(boolean annotateLocaVars, @Nonnull final Project project, @Nonnull final AnalysisScope scope) { - return () -> new UsageInfoSearcherAdapter() { - @Nonnull - @Override - protected UsageInfo[] findUsages() { - return ObjectUtil.notNull(InferNullityAnnotationsAction.this.findUsages(annotateLocaVars, project, scope, scope.getFileCount()), - UsageInfo.EMPTY_ARRAY); - } + @Nonnull + private Supplier rerunFactory( + boolean annotateLocaVars, + @Nonnull final Project project, + @Nonnull final AnalysisScope scope + ) { + return () -> new UsageInfoSearcherAdapter() { + @Nonnull + @Override + protected UsageInfo[] findUsages() { + return ObjectUtil.notNull( + InferNullityAnnotationsAction.this.findUsages(annotateLocaVars, project, scope, scope.getFileCount()), + UsageInfo.EMPTY_ARRAY + ); + } - @Override - public void generate(@Nonnull Processor processor) { - processUsages(processor, project); - } - }; - } + @Override + public void generate(@Nonnull Processor processor) { + processUsages(processor, project); + } + }; + } - @RequiredUIAccess - @Override - protected void extendMainLayout(BaseAnalysisActionDialog dialog, VerticalLayout layout, Project project) { - myAnnotateLocalVariablesCb = - CheckBox.create(LocalizeValue.localizeTODO("Annotate local variables")); - myAnnotateLocalVariablesCb.setValue(PropertiesComponent.getInstance().getBoolean(ANNOTATE_LOCAL_VARIABLES)); - layout.add(myAnnotateLocalVariablesCb); - } + @RequiredUIAccess + @Override + protected void extendMainLayout(BaseAnalysisActionDialog dialog, VerticalLayout layout, Project project) { + myAnnotateLocalVariablesCb = + CheckBox.create(LocalizeValue.localizeTODO("Annotate local variables")); + myAnnotateLocalVariablesCb.setValue(PropertiesComponent.getInstance().getBoolean(ANNOTATE_LOCAL_VARIABLES)); + layout.add(myAnnotateLocalVariablesCb); + } - @Override - protected void canceled() { - super.canceled(); - myAnnotateLocalVariablesCb = null; - } + @Override + protected void canceled() { + super.canceled(); + myAnnotateLocalVariablesCb = null; + } } diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInspection/nullable/NullableStuffInspection.java b/plugin/src/main/java/com/intellij/java/impl/codeInspection/nullable/NullableStuffInspection.java index 670d0ea84..87f01e701 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInspection/nullable/NullableStuffInspection.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInspection/nullable/NullableStuffInspection.java @@ -37,68 +37,73 @@ @ExtensionImpl public class NullableStuffInspection extends NullableStuffInspectionBase { - @Override - protected LocalQuickFix createNavigateToNullParameterUsagesFix(PsiParameter parameter) { - return new NavigateToNullLiteralArguments(parameter); - } - - @Override - public boolean isEnabledByDefault() { - return true; - } - - public static class NavigateToNullLiteralArguments extends LocalQuickFixOnPsiElement { - public NavigateToNullLiteralArguments(@Nonnull PsiParameter element) { - super(element); - } - - @Nonnull @Override - public String getText() { - return getFamilyName(); + protected LocalQuickFix createNavigateToNullParameterUsagesFix(PsiParameter parameter) { + return new NavigateToNullLiteralArguments(parameter); } - @Nls - @Nonnull @Override - public String getFamilyName() { - return JavaInspectionsLocalize.nullableStuffInspectionNavigateNullArgumentUsagesFixFamilyName().get(); + public boolean isEnabledByDefault() { + return true; } - @Override - public void invoke(@Nonnull Project project, @Nonnull PsiFile file, @Nonnull PsiElement startElement, @Nonnull PsiElement endElement) { - PsiParameter p = (PsiParameter)startElement; - final PsiMethod method = PsiTreeUtil.getParentOfType(p, PsiMethod.class); - if (method == null) { - return; - } - final int parameterIdx = ArrayUtil.find(method.getParameterList().getParameters(), p); - if (parameterIdx < 0) { - return; - } + public static class NavigateToNullLiteralArguments extends LocalQuickFixOnPsiElement { + public NavigateToNullLiteralArguments(@Nonnull PsiParameter element) { + super(element); + } - UsageViewPresentation presentation = new UsageViewPresentation(); - String title = JavaInspectionsLocalize.nullableStuffInspectionNavigateNullArgumentUsagesViewName(p.getName()).get(); - presentation.setUsagesString(title); - presentation.setTabName(title); - presentation.setTabText(title); - UsageViewManager.getInstance(project).searchAndShowUsages( - new UsageTarget[]{new PsiElement2UsageTargetAdapter(method.getParameterList().getParameters()[parameterIdx])}, - () -> processor -> ReadAction.run(() -> JavaNullMethodArgumentUtil.searchNullArgument( - method, - parameterIdx, - (arg) -> processor.process(new UsageInfo2UsageAdapter(new UsageInfo(arg))) - )), - false, - false, - presentation, - null - ); - } + @Nonnull + @Override + public String getText() { + return getFamilyName(); + } - @Override - public boolean startInWriteAction() { - return false; + @Nls + @Nonnull + @Override + public String getFamilyName() { + return JavaInspectionsLocalize.nullableStuffInspectionNavigateNullArgumentUsagesFixFamilyName().get(); + } + + @Override + public void invoke( + @Nonnull Project project, + @Nonnull PsiFile file, + @Nonnull PsiElement startElement, + @Nonnull PsiElement endElement + ) { + PsiParameter p = (PsiParameter)startElement; + final PsiMethod method = PsiTreeUtil.getParentOfType(p, PsiMethod.class); + if (method == null) { + return; + } + final int parameterIdx = ArrayUtil.find(method.getParameterList().getParameters(), p); + if (parameterIdx < 0) { + return; + } + + UsageViewPresentation presentation = new UsageViewPresentation(); + String title = JavaInspectionsLocalize.nullableStuffInspectionNavigateNullArgumentUsagesViewName(p.getName()).get(); + presentation.setUsagesString(title); + presentation.setTabName(title); + presentation.setTabText(title); + UsageViewManager.getInstance(project).searchAndShowUsages( + new UsageTarget[]{new PsiElement2UsageTargetAdapter(method.getParameterList().getParameters()[parameterIdx])}, + () -> processor -> ReadAction.run(() -> JavaNullMethodArgumentUtil.searchNullArgument( + method, + parameterIdx, + (arg) -> processor.process(new UsageInfo2UsageAdapter(new UsageInfo(arg))) + )), + false, + false, + presentation, + null + ); + } + + @Override + public boolean startInWriteAction() { + return false; + } } - } } diff --git a/plugin/src/main/java/com/intellij/java/impl/javadoc/actions/GenerateJavadocAction.java b/plugin/src/main/java/com/intellij/java/impl/javadoc/actions/GenerateJavadocAction.java index 3dd85e324..53f789883 100644 --- a/plugin/src/main/java/com/intellij/java/impl/javadoc/actions/GenerateJavadocAction.java +++ b/plugin/src/main/java/com/intellij/java/impl/javadoc/actions/GenerateJavadocAction.java @@ -32,55 +32,55 @@ import javax.swing.event.DocumentEvent; public final class GenerateJavadocAction extends BaseAnalysisAction { - private JavadocConfigurable myConfigurable; + private JavadocConfigurable myConfigurable; - public GenerateJavadocAction() { - super(JavadocBundle.message("javadoc.generate.title"), JavadocBundle.message("javadoc.generate.title")); - } + public GenerateJavadocAction() { + super(JavadocBundle.message("javadoc.generate.title"), JavadocBundle.message("javadoc.generate.title")); + } - @Override - protected void analyze(@Nonnull Project project, AnalysisScope scope) { - myConfigurable.apply(); - JavadocGenerationManager.getInstance(project).generateJavadoc(scope); - dispose(); - } + @Override + protected void analyze(@Nonnull Project project, AnalysisScope scope) { + myConfigurable.apply(); + JavadocGenerationManager.getInstance(project).generateJavadoc(scope); + dispose(); + } - @RequiredUIAccess - @Override - protected void extendMainLayout(BaseAnalysisActionDialog dialog, VerticalLayout layout, Project project) { - myConfigurable = new JavadocConfigurable(JavadocGenerationManager.getInstance(project).getConfiguration()); - final JComponent component = myConfigurable.createComponent(); - myConfigurable.reset(); - myConfigurable.getOutputDirField().getDocument().addDocumentListener(new DocumentAdapter() { - @Override - protected void textChanged(DocumentEvent e) { + @RequiredUIAccess + @Override + protected void extendMainLayout(BaseAnalysisActionDialog dialog, VerticalLayout layout, Project project) { + myConfigurable = new JavadocConfigurable(JavadocGenerationManager.getInstance(project).getConfiguration()); + final JComponent component = myConfigurable.createComponent(); + myConfigurable.reset(); + myConfigurable.getOutputDirField().getDocument().addDocumentListener(new DocumentAdapter() { + @Override + protected void textChanged(DocumentEvent e) { + updateAvailability(dialog); + } + }); updateAvailability(dialog); - } - }); - updateAvailability(dialog); - layout.add(TargetAWT.wrap(component)); - } + layout.add(TargetAWT.wrap(component)); + } - private void updateAvailability(BaseAnalysisActionDialog dialog) { - dialog.setOKActionEnabled(!myConfigurable.getOutputDir().isEmpty()); - } + private void updateAvailability(BaseAnalysisActionDialog dialog) { + dialog.setOKActionEnabled(!myConfigurable.getOutputDir().isEmpty()); + } - @Override - protected void canceled() { - super.canceled(); - dispose(); - } + @Override + protected void canceled() { + super.canceled(); + dispose(); + } - private void dispose() { - if (myConfigurable != null) { - myConfigurable.disposeUIResources(); - myConfigurable = null; + private void dispose() { + if (myConfigurable != null) { + myConfigurable.disposeUIResources(); + myConfigurable = null; + } } - } - @Override - protected String getHelpTopic() { - return "reference.dialogs.generate.javadoc"; - } + @Override + protected String getHelpTopic() { + return "reference.dialogs.generate.javadoc"; + } } diff --git a/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/AnnotatedPackagesSearcher.java b/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/AnnotatedPackagesSearcher.java index cac47ade0..1405eb5ec 100644 --- a/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/AnnotatedPackagesSearcher.java +++ b/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/AnnotatedPackagesSearcher.java @@ -37,103 +37,125 @@ import consulo.virtualFileSystem.VirtualFile; import jakarta.annotation.Nonnull; + import java.util.Collection; @ExtensionImpl public class AnnotatedPackagesSearcher implements AnnotatedPackagesSearchExecutor { - private static final Logger LOG = Logger.getInstance(AnnotatedPackagesSearcher.class); - - @Override - public boolean execute(@Nonnull final AnnotatedPackagesSearch.Parameters p, @Nonnull final Processor consumer) { - final PsiClass annClass = p.getAnnotationClass(); - assert annClass.isAnnotationType() : "Annotation type should be passed to annotated packages search"; - - final String annotationFQN = annClass.getQualifiedName(); - assert annotationFQN != null; - - final PsiManager psiManager = annClass.getManager(); - final SearchScope useScope = p.getScope(); - - final String annotationShortName = annClass.getName(); - assert annotationShortName != null; - - final GlobalSearchScope scope = useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : null; - - final Collection annotations = JavaAnnotationIndex.getInstance().get(annotationShortName, psiManager.getProject(), scope); - for (PsiAnnotation annotation : annotations) { - PsiModifierList modlist = (PsiModifierList)annotation.getParent(); - final PsiElement owner = modlist.getParent(); - if (!(owner instanceof PsiClass)) continue; - PsiClass candidate = (PsiClass)owner; - if (!"package-info".equals(candidate.getName())) continue; - - LOG.assertTrue(candidate.isValid()); - - final PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement(); - if (ref == null) continue; - - if (!psiManager.areElementsEquivalent(ref.resolve(), annClass)) continue; - if (useScope instanceof GlobalSearchScope && - !((GlobalSearchScope)useScope).contains(candidate.getContainingFile().getVirtualFile())) { - continue; - } - final String qname = candidate.getQualifiedName(); - if (qname != null && !consumer.process(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage( - qname.substring(0, qname.lastIndexOf('.'))))) { - return false; - } - } - - PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(psiManager.getProject()); - final GlobalSearchScope infoFilesFilter = new PackageInfoFilesOnly(); - - GlobalSearchScope infoFiles = - useScope instanceof GlobalSearchScope ? ((GlobalSearchScope)useScope).intersectWith(infoFilesFilter) : infoFilesFilter; - - final boolean[] wantmore = new boolean[]{true}; - helper.processAllFilesWithWord(annotationShortName, infoFiles, new Processor() { - @Override - public boolean process(final PsiFile psiFile) { - PsiPackageStatement stmt = PsiTreeUtil.getChildOfType(psiFile, PsiPackageStatement.class); - if (stmt == null) return true; - - final PsiModifierList annotations = stmt.getAnnotationList(); - if (annotations == null) return true; - final PsiAnnotation ann = annotations.findAnnotation(annotationFQN); - if (ann == null) return true; - - final PsiJavaCodeReferenceElement ref = ann.getNameReferenceElement(); - if (ref == null) return true; - - if (!psiManager.areElementsEquivalent(ref.resolve(), annClass)) return true; - - wantmore[0] = consumer.process(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(stmt.getPackageName())); - return wantmore[0]; - } - }, true); - - return wantmore[0]; - } + private static final Logger LOG = Logger.getInstance(AnnotatedPackagesSearcher.class); - private static class PackageInfoFilesOnly extends GlobalSearchScope { @Override - public int compare(final VirtualFile file1, final VirtualFile file2) { - return 0; - } + public boolean execute(@Nonnull final AnnotatedPackagesSearch.Parameters p, @Nonnull final Processor consumer) { + final PsiClass annClass = p.getAnnotationClass(); + assert annClass.isAnnotationType() : "Annotation type should be passed to annotated packages search"; + + final String annotationFQN = annClass.getQualifiedName(); + assert annotationFQN != null; + + final PsiManager psiManager = annClass.getManager(); + final SearchScope useScope = p.getScope(); + + final String annotationShortName = annClass.getName(); + assert annotationShortName != null; + + final GlobalSearchScope scope = useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : null; + + final Collection annotations = + JavaAnnotationIndex.getInstance().get(annotationShortName, psiManager.getProject(), scope); + for (PsiAnnotation annotation : annotations) { + PsiModifierList modlist = (PsiModifierList)annotation.getParent(); + final PsiElement owner = modlist.getParent(); + if (!(owner instanceof PsiClass)) { + continue; + } + PsiClass candidate = (PsiClass)owner; + if (!"package-info".equals(candidate.getName())) { + continue; + } + + LOG.assertTrue(candidate.isValid()); + + final PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement(); + if (ref == null) { + continue; + } + + if (!psiManager.areElementsEquivalent(ref.resolve(), annClass)) { + continue; + } + if (useScope instanceof GlobalSearchScope && + !((GlobalSearchScope)useScope).contains(candidate.getContainingFile().getVirtualFile())) { + continue; + } + final String qname = candidate.getQualifiedName(); + if (qname != null && !consumer.process(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage( + qname.substring(0, qname.lastIndexOf('.'))))) { + return false; + } + } + + PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(psiManager.getProject()); + final GlobalSearchScope infoFilesFilter = new PackageInfoFilesOnly(); + + GlobalSearchScope infoFiles = + useScope instanceof GlobalSearchScope ? ((GlobalSearchScope)useScope).intersectWith(infoFilesFilter) : infoFilesFilter; + + final boolean[] wantmore = new boolean[]{true}; + helper.processAllFilesWithWord(annotationShortName, infoFiles, new Processor() { + @Override + public boolean process(final PsiFile psiFile) { + PsiPackageStatement stmt = PsiTreeUtil.getChildOfType(psiFile, PsiPackageStatement.class); + if (stmt == null) { + return true; + } + + final PsiModifierList annotations = stmt.getAnnotationList(); + if (annotations == null) { + return true; + } + final PsiAnnotation ann = annotations.findAnnotation(annotationFQN); + if (ann == null) { + return true; + } + + final PsiJavaCodeReferenceElement ref = ann.getNameReferenceElement(); + if (ref == null) { + return true; + } + + if (!psiManager.areElementsEquivalent(ref.resolve(), annClass)) { + return true; + } + + wantmore[0] = consumer.process(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(stmt.getPackageName())); + return wantmore[0]; + } + }, + true + ); - @Override - public boolean contains(final VirtualFile file) { - return "package-info.java".equals(file.getName()); - } - - @Override - public boolean isSearchInLibraries() { - return false; + return wantmore[0]; } - @Override - public boolean isSearchInModuleContent(@Nonnull final Module aModule) { - return true; + private static class PackageInfoFilesOnly extends GlobalSearchScope { + @Override + public int compare(final VirtualFile file1, final VirtualFile file2) { + return 0; + } + + @Override + public boolean contains(final VirtualFile file) { + return "package-info.java".equals(file.getName()); + } + + @Override + public boolean isSearchInLibraries() { + return false; + } + + @Override + public boolean isSearchInModuleContent(@Nonnull final Module aModule) { + return true; + } } - } } \ No newline at end of file diff --git a/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/VariableInIncompleteCodeSearcher.java b/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/VariableInIncompleteCodeSearcher.java index 9213ae7d8..9ee095460 100644 --- a/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/VariableInIncompleteCodeSearcher.java +++ b/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/VariableInIncompleteCodeSearcher.java @@ -39,42 +39,50 @@ */ @ExtensionImpl public class VariableInIncompleteCodeSearcher extends QueryExecutorBase implements ReferencesSearchQueryExecutor { - public VariableInIncompleteCodeSearcher() { - super(true); - } - - @Override - public void processQuery(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull final Processor consumer) { - final PsiElement refElement = p.getElementToSearch(); - if (!refElement.isValid() || !(refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter)) return; + public VariableInIncompleteCodeSearcher() { + super(true); + } - final String name = ((PsiVariable)refElement).getName(); - if (name == null) return; + @Override + public void processQuery(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull final Processor consumer) { + final PsiElement refElement = p.getElementToSearch(); + if (!refElement.isValid() || !(refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter)) { + return; + } - final SearchScope scope = p.getEffectiveSearchScope(); - if (!(scope instanceof LocalSearchScope)) return; + final String name = ((PsiVariable)refElement).getName(); + if (name == null) { + return; + } - PsiElement[] elements = ((LocalSearchScope)scope).getScope(); - if (elements == null || elements.length == 0) return; + final SearchScope scope = p.getEffectiveSearchScope(); + if (!(scope instanceof LocalSearchScope)) { + return; + } - PsiElementProcessor processor = new PsiElementProcessor() { - @Override - public boolean execute(@Nonnull final PsiElement element) { - if (element instanceof PsiJavaCodeReferenceElement) { - final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)element; - if (!ref.isQualified() && name.equals(ref.getText()) && - ref.resolve() == null && ref.advancedResolve(true).getElement() == refElement) { - consumer.process(ref); - } + PsiElement[] elements = ((LocalSearchScope)scope).getScope(); + if (elements == null || elements.length == 0) { + return; } - return true; - } - }; - for (PsiElement element : elements) { - if (element.getLanguage().isKindOf(JavaLanguage.INSTANCE)) { - PsiTreeUtil.processElements(element, processor); - } + PsiElementProcessor processor = new PsiElementProcessor() { + @Override + public boolean execute(@Nonnull final PsiElement element) { + if (element instanceof PsiJavaCodeReferenceElement) { + final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)element; + if (!ref.isQualified() && name.equals(ref.getText()) && + ref.resolve() == null && ref.advancedResolve(true).getElement() == refElement) { + consumer.process(ref); + } + } + return true; + } + }; + + for (PsiElement element : elements) { + if (element.getLanguage().isKindOf(JavaLanguage.INSTANCE)) { + PsiTreeUtil.processElements(element, processor); + } + } } - } } From 8f5d194b28d052ab096c12fcd5ca7703c450f483 Mon Sep 17 00:00:00 2001 From: UNV Date: Sat, 12 Apr 2025 20:07:13 +0300 Subject: [PATCH 2/2] Refactoring of query executors. --- .../find/findUsages/JavaFindUsagesHelper.java | 986 ++++++++++-------- .../impl/psi/impl/search/ThrowSearchUtil.java | 90 +- .../search/searches/AllClassesSearch.java | 14 +- .../searches/AllClassesSearchExecutor.java | 2 +- .../AllOverridingMethodsSearchExecutor.java | 2 +- .../AnnotatedElementsSearchExecutor.java | 2 +- .../searches/ClassInheritorsSearch.java | 186 ++-- .../ClassInheritorsSearchExecutor.java | 2 +- ...sesWithAnnotatedMembersSearchExecutor.java | 2 +- .../DirectClassInheritorsSearchExecutor.java | 2 +- .../FunctionalExpressionSearchExecutor.java | 2 +- .../MethodReferencesSearchExecutor.java | 2 +- .../OverridingMethodsSearchExecutor.java | 2 +- .../impl/ClassImplementationsSearch.java | 32 +- .../impl/CompositeShortNamesCache.java | 42 +- .../impl/MethodImplementationsSearch.java | 33 +- .../indexing/impl/PsiShortNamesCacheImpl.java | 75 +- .../impl/search/AllClassesSearchExecutor.java | 123 ++- .../search/AnnotatedElementsSearcher.java | 93 +- .../ClassesWithAnnotatedMembersSearcher.java | 17 +- .../ConstructorReferencesSearchHelper.java | 248 ++--- .../search/ConstructorReferencesSearcher.java | 38 +- .../JavaAllOverridingMethodsSearcher.java | 99 +- .../search/JavaClassInheritorsSearcher.java | 108 +- .../search/JavaDirectInheritorsSearcher.java | 173 +-- .../JavaFunctionalExpressionSearcher.java | 285 +++-- .../search/JavaOverridingMethodsSearcher.java | 44 +- .../search/JavaRecordComponentSearcher.java | 17 +- .../search/MethodDeepestSuperSearcher.java | 28 +- .../impl/search/MethodSuperSearcher.java | 67 +- .../impl/search/MethodUsagesSearcher.java | 81 +- ...PsiAnnotationMethodReferencesSearcher.java | 35 +- .../impl/search/SPIReferencesSearcher.java | 42 +- .../SimpleAccessorReferenceSearcher.java | 17 +- .../psi/search/PsiShortNameProvider.java | 38 +- .../psi/search/PsiShortNamesCache.java | 45 +- .../DeepestSuperMethodsSearchExecutor.java | 2 +- .../searches/SuperMethodsSearchExecutor.java | 2 +- .../java/impl/analysis/AnalysisScopeRule.java | 7 +- .../analysis/BaseClassesAnalysisAction.java | 36 +- .../InferNullityAnnotationsAction.java | 102 +- .../nullable/NullableStuffInspection.java | 12 +- .../findUsages/JavaFindUsagesHandler.java | 77 +- .../actions/GenerateJavadocAction.java | 10 +- .../search/AnnotatedPackagesSearcher.java | 109 +- .../VariableInIncompleteCodeSearcher.java | 35 +- .../AnnotatedPackagesSearchExecutor.java | 2 +- 47 files changed, 1680 insertions(+), 1788 deletions(-) diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/find/findUsages/JavaFindUsagesHelper.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/find/findUsages/JavaFindUsagesHelper.java index 9c6464c12..afc23669b 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/find/findUsages/JavaFindUsagesHelper.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/find/findUsages/JavaFindUsagesHelper.java @@ -25,18 +25,17 @@ import com.intellij.java.language.psi.targets.AliasingPsiTargetMapper; import com.intellij.java.language.psi.util.MethodSignature; import com.intellij.java.language.psi.util.PsiUtil; -import consulo.application.ApplicationManager; -import consulo.application.ReadAction; +import consulo.annotation.access.RequiredReadAction; +import consulo.application.AccessRule; +import consulo.application.Application; import consulo.application.progress.ProgressIndicator; import consulo.application.progress.ProgressManager; import consulo.application.util.ReadActionProcessor; -import consulo.application.util.function.Processor; -import consulo.component.extension.Extensions; import consulo.content.scope.SearchScope; import consulo.document.util.TextRange; -import consulo.find.FindBundle; import consulo.find.FindUsagesHelper; import consulo.find.FindUsagesOptions; +import consulo.find.localize.FindLocalize; import consulo.language.inject.InjectedLanguageManager; import consulo.language.pom.PomService; import consulo.language.pom.PomTarget; @@ -51,516 +50,599 @@ import consulo.usage.UsageInfo; import consulo.util.collection.ContainerUtil; import consulo.util.lang.Comparing; +import consulo.util.lang.function.ThrowableSupplier; import consulo.xml.psi.xml.XmlAttributeValue; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; + import java.util.*; +import java.util.function.Predicate; import java.util.function.Supplier; public class JavaFindUsagesHelper { - private static final Logger LOG = Logger.getInstance(JavaFindUsagesHelper.class); + private static final Logger LOG = Logger.getInstance(JavaFindUsagesHelper.class); + + @Nonnull + public static Set getElementNames(@Nonnull PsiElement element) { + if (element instanceof PsiDirectory directory) { // normalize a directory to a corresponding package + PsiPackage aPackage = AccessRule.read(() -> JavaDirectoryService.getInstance().getPackage(directory)); + return aPackage == null ? Collections.emptySet() : getElementNames(aPackage); + } + + Set result = new HashSet<>(); + + Application.get().runReadAction(() -> { + if (element instanceof PsiPackage psiPackage) { + ContainerUtil.addIfNotNull(result, psiPackage.getQualifiedName()); + } + else if (element instanceof PsiClass psiClass) { + String qname = psiClass.getQualifiedName(); + if (qname != null) { + result.add(qname); + PsiClass topLevelClass = PsiUtil.getTopLevelClass(element); + if (topLevelClass != null && !(topLevelClass instanceof PsiSyntheticClass)) { + String topName = topLevelClass.getQualifiedName(); + assert topName != null : "topLevelClass : " + topLevelClass + ";" + + " element: " + element + " (" + qname + ")" + + " top level file: " + InjectedLanguageManager.getInstance(element.getProject()).getTopLevelFile(element); + if (qname.length() > topName.length()) { + result.add(topName + qname.substring(topName.length()).replace('.', '$')); + } + } + } + } + else if (element instanceof PsiMethod method) { + ContainerUtil.addIfNotNull(result, method.getName()); + } + else if (element instanceof PsiVariable variable) { + ContainerUtil.addIfNotNull(result, variable.getName()); + } + else if (element instanceof PsiMetaOwner metaOwner) { + PsiMetaData metaData = metaOwner.getMetaData(); + if (metaData != null) { + ContainerUtil.addIfNotNull(result, metaData.getName()); + } + } + else if (element instanceof PsiNamedElement namedElement) { + ContainerUtil.addIfNotNull(result, namedElement.getName()); + } + else if (element instanceof XmlAttributeValue xmlAttrValue) { + ContainerUtil.addIfNotNull(result, xmlAttrValue.getValue()); + } + else { + LOG.error("Unknown element type: " + element); + } + }); - @Nonnull - public static Set getElementNames(@Nonnull final PsiElement element) { - if (element instanceof PsiDirectory) { // normalize a directory to a corresponding package - PsiPackage aPackage = ReadAction.compute(() -> JavaDirectoryService.getInstance().getPackage((PsiDirectory) element)); - return aPackage == null ? Collections.emptySet() : getElementNames(aPackage); + return result; } - final Set result = new HashSet<>(); - - ApplicationManager.getApplication().runReadAction(() -> - { - if (element instanceof PsiPackage) { - ContainerUtil.addIfNotNull(result, ((PsiPackage) element).getQualifiedName()); - } else if (element instanceof PsiClass) { - final String qname = ((PsiClass) element).getQualifiedName(); - if (qname != null) { - result.add(qname); - PsiClass topLevelClass = PsiUtil.getTopLevelClass(element); - if (topLevelClass != null && !(topLevelClass instanceof PsiSyntheticClass)) { - String topName = topLevelClass.getQualifiedName(); - assert topName != null : "topLevelClass : " + topLevelClass + "; element: " + element + " (" + qname + ") top level file: " + InjectedLanguageManager.getInstance(element - .getProject()).getTopLevelFile(element); - if (qname.length() > topName.length()) { - result.add(topName + qname.substring(topName.length()).replace('.', '$')); - } - } - } - } else if (element instanceof PsiMethod) { - ContainerUtil.addIfNotNull(result, ((PsiMethod) element).getName()); - } else if (element instanceof PsiVariable) { - ContainerUtil.addIfNotNull(result, ((PsiVariable) element).getName()); - } else if (element instanceof PsiMetaOwner) { - final PsiMetaData metaData = ((PsiMetaOwner) element).getMetaData(); - if (metaData != null) { - ContainerUtil.addIfNotNull(result, metaData.getName()); + public static boolean processElementUsages( + @Nonnull PsiElement element, + @Nonnull FindUsagesOptions options, + @Nonnull Predicate processor + ) { + if (options instanceof JavaVariableFindUsagesOptions varOptions) { + if (varOptions.isReadAccess || varOptions.isWriteAccess) { + if (varOptions.isReadAccess && varOptions.isWriteAccess) { + if (!addElementUsages(element, options, processor)) { + return false; + } + } + else { + if (!addElementUsages( + element, + varOptions, + info -> { + boolean isWrite = info.getElement() instanceof PsiExpression expression + && PsiUtil.isAccessedForWriting(expression); + return isWrite != varOptions.isWriteAccess || processor.test(info); + } + )) { + return false; + } + } + } } - } else if (element instanceof PsiNamedElement) { - ContainerUtil.addIfNotNull(result, ((PsiNamedElement) element).getName()); - } else if (element instanceof XmlAttributeValue) { - ContainerUtil.addIfNotNull(result, ((XmlAttributeValue) element).getValue()); - } else { - LOG.error("Unknown element type: " + element); - } - }); - - return result; - } - - public static boolean processElementUsages(@Nonnull final PsiElement element, @Nonnull final FindUsagesOptions options, @Nonnull final Processor processor) { - if (options instanceof JavaVariableFindUsagesOptions) { - final JavaVariableFindUsagesOptions varOptions = (JavaVariableFindUsagesOptions) options; - if (varOptions.isReadAccess || varOptions.isWriteAccess) { - if (varOptions.isReadAccess && varOptions.isWriteAccess) { - if (!addElementUsages(element, options, processor)) { - return false; - } - } else { - if (!addElementUsages(element, varOptions, info -> - { - final PsiElement element1 = info.getElement(); - boolean isWrite = element1 instanceof PsiExpression && PsiUtil.isAccessedForWriting((PsiExpression) element1); - if (isWrite == varOptions.isWriteAccess) { - if (!processor.process(info)) { + else if (options.isUsages) { + if (!addElementUsages(element, options, processor)) { return false; - } + } + } + + boolean success = AccessRule.read(() -> { + if (ThrowSearchUtil.isSearchable(element) + && options instanceof JavaThrowFindUsagesOptions throwOptions + && options.isUsages) { + ThrowSearchUtil.Root root = throwOptions.getRoot(); + if (root == null) { + ThrowSearchUtil.Root[] roots = ThrowSearchUtil.getSearchRoots(element); + if (roots != null && roots.length > 0) { + root = roots[0]; + } + } + if (root != null) { + return ThrowSearchUtil.addThrowUsages(processor, root, options); + } } return true; - })) { + }); + if (!success) { return false; - } } - } - } else if (options.isUsages) { - if (!addElementUsages(element, options, processor)) { - return false; - } - } - boolean success = ReadAction.compute(() -> - { - if (ThrowSearchUtil.isSearchable(element) && options instanceof JavaThrowFindUsagesOptions && options.isUsages) { - ThrowSearchUtil.Root root = ((JavaThrowFindUsagesOptions) options).getRoot(); - if (root == null) { - final ThrowSearchUtil.Root[] roots = ThrowSearchUtil.getSearchRoots(element); - if (roots != null && roots.length > 0) { - root = roots[0]; - } - } - if (root != null) { - return ThrowSearchUtil.addThrowUsages(processor, root, options); + if (options instanceof JavaPackageFindUsagesOptions packageOptions && packageOptions.isClassesUsages + && !addClassesUsages((PsiPackage)element, packageOptions, processor)) { + return false; } - } - return true; - }); - if (!success) { - return false; - } - - if (options instanceof JavaPackageFindUsagesOptions && ((JavaPackageFindUsagesOptions) options).isClassesUsages) { - if (!addClassesUsages((PsiPackage) element, (JavaPackageFindUsagesOptions) options, processor)) { - return false; - } - } - if (options instanceof JavaClassFindUsagesOptions) { - final JavaClassFindUsagesOptions classOptions = (JavaClassFindUsagesOptions) options; - final PsiClass psiClass = (PsiClass) element; - PsiManager manager = ReadAction.compute(psiClass::getManager); - if (classOptions.isMethodsUsages) { - if (!addMethodsUsages(psiClass, manager, classOptions, processor)) { - return false; - } - } - if (classOptions.isFieldsUsages) { - if (!addFieldsUsages(psiClass, manager, classOptions, processor)) { - return false; + if (options instanceof JavaClassFindUsagesOptions classOptions) { + PsiClass psiClass = (PsiClass)element; + PsiManager manager = AccessRule.read(psiClass::getManager); + if (classOptions.isMethodsUsages && !addMethodsUsages(psiClass, manager, classOptions, processor)) { + return false; + } + if (classOptions.isFieldsUsages && !addFieldsUsages(psiClass, manager, classOptions, processor)) { + return false; + } + if (AccessRule.read(psiClass::isInterface)) { + if (classOptions.isDerivedInterfaces) { + if (classOptions.isImplementingClasses) { + if (!addInheritors(psiClass, classOptions, processor)) { + return false; + } + } + else if (!addDerivedInterfaces(psiClass, classOptions, processor)) { + return false; + } + } + else if (classOptions.isImplementingClasses && !addImplementingClasses(psiClass, classOptions, processor)) { + return false; + } + + if (classOptions.isImplementingClasses) { + FunctionalExpressionSearch.search(psiClass, classOptions.searchScope) + .forEach(new PsiElementProcessorAdapter<>(expression -> addResult(expression, options, processor))); + } + } + else if (classOptions.isDerivedClasses && !addInheritors(psiClass, classOptions, processor)) { + return false; + } } - } - if (ReadAction.compute(psiClass::isInterface)) { - if (classOptions.isDerivedInterfaces) { - if (classOptions.isImplementingClasses) { - if (!addInheritors(psiClass, classOptions, processor)) { - return false; - } - } else { - if (!addDerivedInterfaces(psiClass, classOptions, processor)) { - return false; - } - } - } else if (classOptions.isImplementingClasses) { - if (!addImplementingClasses(psiClass, classOptions, processor)) { - return false; - } + + if (options instanceof JavaMethodFindUsagesOptions methodOptions) { + PsiMethod psiMethod = (PsiMethod)element; + boolean isAbstract = AccessRule.read(psiMethod::isAbstract); + if (isAbstract && methodOptions.isImplementingMethods || methodOptions.isOverridingMethods) { + if (!processOverridingMethods(psiMethod, processor, methodOptions)) { + return false; + } + FunctionalExpressionSearch.search(psiMethod, methodOptions.searchScope) + .forEach(new PsiElementProcessorAdapter<>(expression -> addResult(expression, options, processor))); + } } - if (classOptions.isImplementingClasses) { - FunctionalExpressionSearch.search(psiClass, classOptions.searchScope).forEach(new PsiElementProcessorAdapter<>(expression -> addResult(expression, options, processor))); + if (element instanceof PomTarget pomTarget && !addAliasingUsages(pomTarget, options, processor)) { + return false; } - } else if (classOptions.isDerivedClasses) { - if (!addInheritors(psiClass, classOptions, processor)) { - return false; + Boolean isSearchable = AccessRule.read(() -> ThrowSearchUtil.isSearchable(element)); + if (!isSearchable && options.isSearchForTextOccurrences && options.searchScope instanceof GlobalSearchScope globalSearchScope) { + Collection stringsToSearch = + Application.get().runReadAction((Supplier>)() -> getElementNames(element)); + // todo add to fastTrack + if (!FindUsagesHelper.processUsagesInText(element, stringsToSearch, globalSearchScope, processor)) { + return false; + } } - } + return true; } - if (options instanceof JavaMethodFindUsagesOptions) { - final PsiMethod psiMethod = (PsiMethod) element; - boolean isAbstract = ReadAction.compute(() -> psiMethod.hasModifierProperty(PsiModifier.ABSTRACT)); - final JavaMethodFindUsagesOptions methodOptions = (JavaMethodFindUsagesOptions) options; - if (isAbstract && methodOptions.isImplementingMethods || methodOptions.isOverridingMethods) { - if (!processOverridingMethods(psiMethod, processor, methodOptions)) { - return false; + private static boolean addAliasingUsages( + @Nonnull PomTarget pomTarget, + @Nonnull FindUsagesOptions options, + @Nonnull Predicate processor + ) { + for (AliasingPsiTargetMapper aliasingPsiTargetMapper : AliasingPsiTargetMapper.EP_NAME.getExtensionList()) { + for (AliasingPsiTarget psiTarget : aliasingPsiTargetMapper.getTargets(pomTarget)) { + boolean success = ReferencesSearch.search(new ReferencesSearch.SearchParameters( + AccessRule.read(() -> PomService.convertToPsi(psiTarget)), + options.searchScope, + false, + options.fastTrack + )) + .forEach(new ReadActionProcessor<>() { + @Override + @RequiredReadAction + public boolean processInReadAction(PsiReference reference) { + return addResult(reference, options, processor); + } + }); + if (!success) { + return false; + } + } } - FunctionalExpressionSearch.search(psiMethod, methodOptions.searchScope).forEach(new PsiElementProcessorAdapter<>(expression -> addResult(expression, options, processor))); - } + return true; } - if (element instanceof PomTarget) { - if (!addAliasingUsages((PomTarget) element, options, processor)) { - return false; - } - } - final Boolean isSearchable = ReadAction.compute(() -> ThrowSearchUtil.isSearchable(element)); - if (!isSearchable && options.isSearchForTextOccurrences && options.searchScope instanceof GlobalSearchScope) { - Collection stringsToSearch = ApplicationManager.getApplication().runReadAction((Supplier>) () -> getElementNames(element)); - // todo add to fastTrack - if (!FindUsagesHelper.processUsagesInText(element, stringsToSearch, (GlobalSearchScope) options.searchScope, processor)) { - return false; - } - } - return true; - } - - private static boolean addAliasingUsages(@Nonnull PomTarget pomTarget, @Nonnull final FindUsagesOptions options, @Nonnull final Processor processor) { - for (AliasingPsiTargetMapper aliasingPsiTargetMapper : Extensions.getExtensions(AliasingPsiTargetMapper.EP_NAME)) { - for (final AliasingPsiTarget psiTarget : aliasingPsiTargetMapper.getTargets(pomTarget)) { - boolean success = ReferencesSearch.search(new ReferencesSearch.SearchParameters(ReadAction.compute(() -> PomService.convertToPsi(psiTarget)), options.searchScope, false, options - .fastTrack)).forEach(new ReadActionProcessor() { - @Override - public boolean processInReadAction(final PsiReference reference) { - return addResult(reference, options, processor); - } - }); - if (!success) { - return false; - } - } - } - return true; - } - - private static boolean processOverridingMethods(@Nonnull PsiMethod psiMethod, @Nonnull final Processor processor, @Nonnull final JavaMethodFindUsagesOptions options) { - return OverridingMethodsSearch.search(psiMethod, options.searchScope, options.isCheckDeepInheritance).forEach(new PsiElementProcessorAdapter<>(element -> addResult(element - .getNavigationElement(), options, processor))); - } - - private static boolean addClassesUsages(@Nonnull PsiPackage aPackage, @Nonnull final JavaPackageFindUsagesOptions options, @Nonnull final Processor processor) { - ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); - if (progress != null) { - progress.pushState(); + private static boolean processOverridingMethods( + @Nonnull PsiMethod psiMethod, + @Nonnull Predicate processor, + @Nonnull JavaMethodFindUsagesOptions options + ) { + return OverridingMethodsSearch.search(psiMethod, options.searchScope, options.isCheckDeepInheritance) + .forEach(new PsiElementProcessorAdapter<>( + element -> addResult(element.getNavigationElement(), options, processor) + )); } - try { - List classes = new ArrayList<>(); - addClassesInPackage(aPackage, options.isIncludeSubpackages, classes); - for (final PsiClass aClass : classes) { + private static boolean addClassesUsages( + @Nonnull PsiPackage aPackage, + @Nonnull JavaPackageFindUsagesOptions options, + @Nonnull Predicate processor + ) { + ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator(); if (progress != null) { - String name = ReadAction.compute(aClass::getName); - progress.setText(FindBundle.message("find.searching.for.references.to.class.progress", name)); + progress.pushState(); } - ProgressManager.checkCanceled(); - boolean success = ReferencesSearch.search(new ReferencesSearch.SearchParameters(aClass, options.searchScope, false, options.fastTrack)).forEach(new ReadActionProcessor() { - @Override - public boolean processInReadAction(final PsiReference psiReference) { - return addResult(psiReference, options, processor); - } - }); - if (!success) { - return false; - } - } - } finally { - if (progress != null) { - progress.popState(); - } - } - return true; - } + try { + List classes = new ArrayList<>(); + addClassesInPackage(aPackage, options.isIncludeSubpackages, classes); + for (PsiClass aClass : classes) { + if (progress != null) { + String name = AccessRule.read(aClass::getName); + progress.setTextValue(FindLocalize.findSearchingForReferencesToClassProgress(name)); + } + ProgressManager.checkCanceled(); + boolean success = ReferencesSearch.search( + new ReferencesSearch.SearchParameters(aClass, options.searchScope, false, options.fastTrack) + ) + .forEach(new ReadActionProcessor<>() { + @Override + @RequiredReadAction + public boolean processInReadAction(PsiReference psiReference) { + return addResult(psiReference, options, processor); + } + }); + if (!success) { + return false; + } + } + } + finally { + if (progress != null) { + progress.popState(); + } + } - private static void addClassesInPackage(@Nonnull final PsiPackage aPackage, boolean includeSubpackages, @Nonnull List array) { - PsiDirectory[] dirs = ReadAction.compute(aPackage::getDirectories); - for (PsiDirectory dir : dirs) { - addClassesInDirectory(dir, includeSubpackages, array); + return true; } - } - - private static void addClassesInDirectory(@Nonnull final PsiDirectory dir, final boolean includeSubdirs, @Nonnull final List array) { - ApplicationManager.getApplication().runReadAction(() -> - { - PsiClass[] classes = JavaDirectoryService.getInstance().getClasses(dir); - ContainerUtil.addAll(array, classes); - if (includeSubdirs) { - PsiDirectory[] dirs = dir.getSubdirectories(); - for (PsiDirectory directory : dirs) { - addClassesInDirectory(directory, true, array); + + private static void addClassesInPackage(@Nonnull PsiPackage aPackage, boolean includeSubpackages, @Nonnull List array) { + PsiDirectory[] dirs = AccessRule.read((ThrowableSupplier)aPackage::getDirectories); + for (PsiDirectory dir : dirs) { + addClassesInDirectory(dir, includeSubpackages, array); } - } - }); - } - - private static boolean addMethodsUsages(@Nonnull final PsiClass aClass, - @Nonnull final PsiManager manager, - @Nonnull final JavaClassFindUsagesOptions options, - @Nonnull final Processor processor) { - if (options.isIncludeInherited) { - final PsiMethod[] methods = ReadAction.compute(aClass::getAllMethods); - for (int i = 0; i < methods.length; i++) { - final PsiMethod method = methods[i]; - // filter overridden methods - final int finalI = i; - final PsiClass methodClass = ReadAction.compute(() -> - { - MethodSignature methodSignature = method.getSignature(PsiSubstitutor.EMPTY); - for (int j = 0; j < finalI; j++) { - if (methodSignature.equals(methods[j].getSignature(PsiSubstitutor.EMPTY))) { - return null; - } - } - return method.getContainingClass(); + } + + private static void addClassesInDirectory( + @Nonnull PsiDirectory dir, + boolean includeSubdirs, + @Nonnull List array + ) { + Application.get().runReadAction(() -> { + PsiClass[] classes = JavaDirectoryService.getInstance().getClasses(dir); + ContainerUtil.addAll(array, classes); + if (includeSubdirs) { + PsiDirectory[] dirs = dir.getSubdirectories(); + for (PsiDirectory directory : dirs) { + addClassesInDirectory(directory, true, array); + } + } }); - if (methodClass == null) { - continue; - } - boolean equivalent = ReadAction.compute(() -> manager.areElementsEquivalent(methodClass, aClass)); - if (equivalent) { - if (!addElementUsages(method, options, processor)) { - return false; - } - } else { - MethodReferencesSearch.SearchParameters parameters = new MethodReferencesSearch.SearchParameters(method, options.searchScope, true, options.fastTrack); - boolean success = MethodReferencesSearch.search(parameters).forEach(new PsiReferenceProcessorAdapter(reference -> - { - addResultFromReference(reference, methodClass, manager, aClass, options, processor); - return true; - })); - if (!success) { - return false; - } + } + + private static boolean addMethodsUsages( + @Nonnull PsiClass aClass, + @Nonnull PsiManager manager, + @Nonnull JavaClassFindUsagesOptions options, + @Nonnull Predicate processor + ) { + if (options.isIncludeInherited) { + PsiMethod[] methods = AccessRule.read(aClass::getAllMethods); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + // filter overridden methods + int finalI = i; + PsiClass methodClass = AccessRule.read(() -> { + MethodSignature methodSignature = method.getSignature(PsiSubstitutor.EMPTY); + for (int j = 0; j < finalI; j++) { + if (methodSignature.equals(methods[j].getSignature(PsiSubstitutor.EMPTY))) { + return null; + } + } + return method.getContainingClass(); + }); + if (methodClass == null) { + continue; + } + boolean equivalent = AccessRule.read(() -> manager.areElementsEquivalent(methodClass, aClass)); + if (equivalent) { + if (!addElementUsages(method, options, processor)) { + return false; + } + } + else { + MethodReferencesSearch.SearchParameters parameters = + new MethodReferencesSearch.SearchParameters(method, options.searchScope, true, options.fastTrack); + boolean success = MethodReferencesSearch.search(parameters).forEach(new PsiReferenceProcessorAdapter(reference -> { + addResultFromReference(reference, methodClass, manager, aClass, options, processor); + return true; + })); + if (!success) { + return false; + } + } + } } - } - } else { - PsiMethod[] methods = ReadAction.compute(aClass::getMethods); - for (PsiMethod method : methods) { - if (!addElementUsages(method, options, processor)) { - return false; + else { + PsiMethod[] methods = AccessRule.read(aClass::getMethods); + for (PsiMethod method : methods) { + if (!addElementUsages(method, options, processor)) { + return false; + } + } } - } + return true; } - return true; - } - - private static boolean addFieldsUsages(@Nonnull final PsiClass aClass, - @Nonnull final PsiManager manager, - @Nonnull final JavaClassFindUsagesOptions options, - @Nonnull final Processor processor) { - if (options.isIncludeInherited) { - final PsiField[] fields = ReadAction.compute(aClass::getAllFields); - for (int i = 0; i < fields.length; i++) { - final PsiField field = fields[i]; - // filter hidden fields - final int finalI = i; - final PsiClass fieldClass = ReadAction.compute(() -> - { - for (int j = 0; j < finalI; j++) { - if (Comparing.strEqual(field.getName(), fields[j].getName())) { - return null; - } - } - return field.getContainingClass(); - }); - if (fieldClass == null) { - continue; - } - boolean equivalent = ReadAction.compute(() -> manager.areElementsEquivalent(fieldClass, aClass)); - if (equivalent) { - if (!addElementUsages(fields[i], options, processor)) { - return false; - } - } else { - boolean success = ReferencesSearch.search(new ReferencesSearch.SearchParameters(field, options.searchScope, false, options.fastTrack)).forEach(new - ReadActionProcessor() { - @Override - public boolean processInReadAction(final PsiReference reference) { - return addResultFromReference(reference, fieldClass, manager, aClass, options, processor); - } - }); - if (!success) { - return false; - } + + private static boolean addFieldsUsages( + @Nonnull PsiClass aClass, + @Nonnull PsiManager manager, + @Nonnull JavaClassFindUsagesOptions options, + @Nonnull Predicate processor + ) { + if (options.isIncludeInherited) { + PsiField[] fields = AccessRule.read(aClass::getAllFields); + for (int i = 0; i < fields.length; i++) { + PsiField field = fields[i]; + // filter hidden fields + int finalI = i; + ThrowableSupplier action = () -> { + for (int j = 0; j < finalI; j++) { + if (Comparing.strEqual(field.getName(), fields[j].getName())) { + return null; + } + } + return field.getContainingClass(); + }; + PsiClass fieldClass = AccessRule.read(action); + if (fieldClass == null) { + continue; + } + boolean equivalent = AccessRule.read(() -> manager.areElementsEquivalent(fieldClass, aClass)); + if (equivalent) { + if (!addElementUsages(fields[i], options, processor)) { + return false; + } + } + else { + boolean success = ReferencesSearch.search( + new ReferencesSearch.SearchParameters(field, options.searchScope, false, options.fastTrack) + ) + .forEach(new ReadActionProcessor<>() { + @Override + @RequiredReadAction + public boolean processInReadAction(PsiReference reference) { + return addResultFromReference(reference, fieldClass, manager, aClass, options, processor); + } + }); + if (!success) { + return false; + } + } + } } - } - } else { - PsiField[] fields = ReadAction.compute(aClass::getFields); - for (PsiField field : fields) { - if (!addElementUsages(field, options, processor)) { - return false; + else { + for (PsiField field : AccessRule.read(aClass::getFields)) { + if (!addElementUsages(field, options, processor)) { + return false; + } + } } - } + return true; } - return true; - } - - @Nullable - private static PsiClass getFieldOrMethodAccessedClass(@Nonnull PsiReferenceExpression ref, @Nonnull PsiClass fieldOrMethodClass) { - PsiElement[] children = ref.getChildren(); - if (children.length > 1 && children[0] instanceof PsiExpression) { - PsiExpression expr = (PsiExpression) children[0]; - PsiType type = expr.getType(); - if (type != null) { - if (!(type instanceof PsiClassType)) { - return null; + + @Nullable + @RequiredReadAction + private static PsiClass getFieldOrMethodAccessedClass(@Nonnull PsiReferenceExpression ref, @Nonnull PsiClass fieldOrMethodClass) { + PsiElement[] children = ref.getChildren(); + if (children.length > 1 && children[0] instanceof PsiExpression expr) { + PsiType type = expr.getType(); + if (type != null) { + return type instanceof PsiClassType ? PsiUtil.resolveClassInType(type) : null; + } + else { + if (expr instanceof PsiReferenceExpression refExpr && refExpr.resolve() instanceof PsiClass psiClass) { + return psiClass; + } + return null; + } } - return PsiUtil.resolveClassInType(type); - } else { - if (expr instanceof PsiReferenceExpression) { - PsiElement refElement = ((PsiReferenceExpression) expr).resolve(); - if (refElement instanceof PsiClass) { - return (PsiClass) refElement; - } + PsiManager manager = ref.getManager(); + for (PsiElement parent = ref; parent != null; parent = parent.getParent()) { + if (parent instanceof PsiClass psiClass && (manager.areElementsEquivalent(parent, fieldOrMethodClass) + || psiClass.isInheritor(fieldOrMethodClass, true))) { + return psiClass; + } } return null; - } } - PsiManager manager = ref.getManager(); - for (PsiElement parent = ref; parent != null; parent = parent.getParent()) { - if (parent instanceof PsiClass && (manager.areElementsEquivalent(parent, fieldOrMethodClass) || ((PsiClass) parent).isInheritor(fieldOrMethodClass, true))) { - return (PsiClass) parent; - } + + private static boolean addInheritors( + @Nonnull PsiClass aClass, + @Nonnull JavaClassFindUsagesOptions options, + @Nonnull Predicate processor + ) { + return ClassInheritorsSearch.search(aClass, options.searchScope, options.isCheckDeepInheritance) + .forEach(new PsiElementProcessorAdapter<>(element -> addResult(element, options, processor))); } - return null; - } - - private static boolean addInheritors(@Nonnull PsiClass aClass, @Nonnull final JavaClassFindUsagesOptions options, @Nonnull final Processor processor) { - return ClassInheritorsSearch.search(aClass, options.searchScope, options.isCheckDeepInheritance).forEach(new PsiElementProcessorAdapter<>(element -> addResult(element, options, processor))); - } - - private static boolean addDerivedInterfaces(@Nonnull PsiClass anInterface, @Nonnull final JavaClassFindUsagesOptions options, @Nonnull final Processor processor) { - return ClassInheritorsSearch.search(anInterface, options.searchScope, options.isCheckDeepInheritance).forEach(new PsiElementProcessorAdapter<>(inheritor -> !inheritor.isInterface() || - addResult(inheritor, options, processor))); - } - - private static boolean addImplementingClasses(@Nonnull PsiClass anInterface, @Nonnull final JavaClassFindUsagesOptions options, @Nonnull final Processor processor) { - return ClassInheritorsSearch.search(anInterface, options.searchScope, options.isCheckDeepInheritance).forEach(new PsiElementProcessorAdapter<>(inheritor -> inheritor.isInterface() || - addResult(inheritor, options, processor))); - } - - private static boolean addResultFromReference(@Nonnull PsiReference reference, - @Nonnull PsiClass methodClass, - @Nonnull PsiManager manager, - @Nonnull PsiClass aClass, - @Nonnull FindUsagesOptions options, - @Nonnull Processor processor) { - PsiElement refElement = reference.getElement(); - if (refElement instanceof PsiReferenceExpression) { - PsiClass usedClass = getFieldOrMethodAccessedClass((PsiReferenceExpression) refElement, methodClass); - if (usedClass != null) { - if (manager.areElementsEquivalent(usedClass, aClass) || usedClass.isInheritor(aClass, true)) { - if (!addResult(refElement, options, processor)) { - return false; - } - } - } + + private static boolean addDerivedInterfaces( + @Nonnull PsiClass anInterface, + @Nonnull JavaClassFindUsagesOptions options, + @Nonnull Predicate processor + ) { + return ClassInheritorsSearch.search(anInterface, options.searchScope, options.isCheckDeepInheritance).forEach( + new PsiElementProcessorAdapter<>(inheritor -> !inheritor.isInterface() || addResult(inheritor, options, processor)) + ); } - return true; - } - - private static boolean addElementUsages(@Nonnull final PsiElement element, @Nonnull final FindUsagesOptions options, @Nonnull final Processor processor) { - final SearchScope searchScope = options.searchScope; - final PsiClass[] parentClass = new PsiClass[1]; - if (element instanceof PsiMethod && ReadAction.compute(() -> - { - PsiMethod method = (PsiMethod) element; - parentClass[0] = method.getContainingClass(); - return method.isConstructor(); - })) { - PsiMethod method = (PsiMethod) element; - - if (parentClass[0] != null) { - boolean strictSignatureSearch = !(options instanceof JavaMethodFindUsagesOptions) || !((JavaMethodFindUsagesOptions) options).isIncludeOverloadUsages; - return MethodReferencesSearch.search(new MethodReferencesSearch.SearchParameters(method, searchScope, strictSignatureSearch, options.fastTrack)).forEach(new - ReadActionProcessor() { - @Override - public boolean processInReadAction(final PsiReference ref) { - return addResult(ref, options, processor); - } - }); - } - return true; + + private static boolean addImplementingClasses( + @Nonnull PsiClass anInterface, + @Nonnull JavaClassFindUsagesOptions options, + @Nonnull Predicate processor + ) { + return ClassInheritorsSearch.search(anInterface, options.searchScope, options.isCheckDeepInheritance).forEach( + new PsiElementProcessorAdapter<>(inheritor -> inheritor.isInterface() || addResult(inheritor, options, processor)) + ); } - final ReadActionProcessor consumer = new ReadActionProcessor() { - @Override - public boolean processInReadAction(final PsiReference ref) { - return addResult(ref, options, processor); - } - }; - - if (element instanceof PsiMethod) { - final boolean strictSignatureSearch = !(options instanceof JavaMethodFindUsagesOptions) || // field with getter - !((JavaMethodFindUsagesOptions) options).isIncludeOverloadUsages; - return MethodReferencesSearch.search(new MethodReferencesSearch.SearchParameters((PsiMethod) element, searchScope, strictSignatureSearch, options.fastTrack)).forEach(consumer); + @RequiredReadAction + private static boolean addResultFromReference( + @Nonnull PsiReference reference, + @Nonnull PsiClass methodClass, + @Nonnull PsiManager manager, + @Nonnull PsiClass aClass, + @Nonnull FindUsagesOptions options, + @Nonnull Predicate processor + ) { + PsiElement refElement = reference.getElement(); + if (refElement instanceof PsiReferenceExpression refExpr) { + PsiClass usedClass = getFieldOrMethodAccessedClass(refExpr, methodClass); + if (usedClass != null && (manager.areElementsEquivalent(usedClass, aClass) || usedClass.isInheritor(aClass, true))) { + if (!addResult(refElement, options, processor)) { + return false; + } + } + } + return true; } - return ReferencesSearch.search(new ReferencesSearch.SearchParameters(element, searchScope, false, options.fastTrack)).forEach(consumer); - } - private static boolean addResult(@Nonnull PsiElement element, @Nonnull FindUsagesOptions options, @Nonnull Processor processor) { - return !filterUsage(element, options) || processor.process(new UsageInfo(element)); - } + private static boolean addElementUsages( + @Nonnull PsiElement element, + @Nonnull FindUsagesOptions options, + @Nonnull Predicate processor + ) { + SearchScope searchScope = options.searchScope; + PsiClass[] parentClass = new PsiClass[1]; + if (element instanceof PsiMethod method && AccessRule.read(() -> { + parentClass[0] = method.getContainingClass(); + return method.isConstructor(); + })) { + if (parentClass[0] != null) { + boolean strictSignatureSearch = + !(options instanceof JavaMethodFindUsagesOptions methodOptions) || !methodOptions.isIncludeOverloadUsages; + return MethodReferencesSearch.search(new MethodReferencesSearch.SearchParameters( + method, + searchScope, + strictSignatureSearch, + options.fastTrack + )).forEach(new ReadActionProcessor<>() { + @Override + @RequiredReadAction + public boolean processInReadAction(PsiReference ref) { + return addResult(ref, options, processor); + } + }); + } + return true; + } - private static boolean addResult(@Nonnull PsiReference ref, @Nonnull FindUsagesOptions options, @Nonnull Processor processor) { - if (filterUsage(ref.getElement(), options)) { - TextRange rangeInElement = ref.getRangeInElement(); - return processor.process(new UsageInfo(ref.getElement(), rangeInElement.getStartOffset(), rangeInElement.getEndOffset(), false)); + ReadActionProcessor consumer = new ReadActionProcessor<>() { + @Override + @RequiredReadAction + public boolean processInReadAction(PsiReference ref) { + return addResult(ref, options, processor); + } + }; + + if (element instanceof PsiMethod method) { + boolean strictSignatureSearch = !(options instanceof JavaMethodFindUsagesOptions methodOptions) || // field with getter + !methodOptions.isIncludeOverloadUsages; + return MethodReferencesSearch.search(new MethodReferencesSearch.SearchParameters( + method, + searchScope, + strictSignatureSearch, + options.fastTrack + )).forEach(consumer); + } + return ReferencesSearch.search(new ReferencesSearch.SearchParameters(element, searchScope, false, options.fastTrack)) + .forEach(consumer); } - return true; - } - private static boolean filterUsage(PsiElement usage, @Nonnull FindUsagesOptions options) { - if (!(usage instanceof PsiJavaCodeReferenceElement)) { - return true; + @RequiredReadAction + private static boolean addResult( + @Nonnull PsiElement element, + @Nonnull FindUsagesOptions options, + @Nonnull Predicate processor + ) { + return !filterUsage(element, options) || processor.test(new UsageInfo(element)); } - if (options instanceof JavaPackageFindUsagesOptions && !((JavaPackageFindUsagesOptions) options).isIncludeSubpackages && ((PsiReference) usage).resolve() instanceof PsiPackage) { - PsiElement parent = usage.getParent(); - if (parent instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement) parent).resolve() instanceof PsiPackage) { - return false; - } + + @RequiredReadAction + private static boolean addResult( + @Nonnull PsiReference ref, + @Nonnull FindUsagesOptions options, + @Nonnull Predicate processor + ) { + if (filterUsage(ref.getElement(), options)) { + TextRange rangeInElement = ref.getRangeInElement(); + return processor.test(new UsageInfo( + ref.getElement(), + rangeInElement.getStartOffset(), + rangeInElement.getEndOffset(), + false + )); + } + return true; } - if (!(usage instanceof PsiReferenceExpression)) { - if (options instanceof JavaFindUsagesOptions && ((JavaFindUsagesOptions) options).isSkipImportStatements) { - PsiElement parent = usage.getParent(); - while (parent instanceof PsiJavaCodeReferenceElement) { - parent = parent.getParent(); + @RequiredReadAction + private static boolean filterUsage(PsiElement usage, @Nonnull FindUsagesOptions options) { + if (!(usage instanceof PsiJavaCodeReferenceElement)) { + return true; } - if (parent instanceof PsiImportStatement) { - return false; + if (options instanceof JavaPackageFindUsagesOptions packageOptions + && !packageOptions.isIncludeSubpackages + && ((PsiReference)usage).resolve() instanceof PsiPackage + && usage.getParent() instanceof PsiJavaCodeReferenceElement codeRef + && codeRef.resolve() instanceof PsiPackage) { + return false; } - } - if (options instanceof JavaPackageFindUsagesOptions && ((JavaPackageFindUsagesOptions) options).isSkipPackageStatements) { - PsiElement parent = usage.getParent(); - while (parent instanceof PsiJavaCodeReferenceElement) { - parent = parent.getParent(); - } - if (parent instanceof PsiPackageStatement) { - return false; + if (!(usage instanceof PsiReferenceExpression)) { + if (options instanceof JavaFindUsagesOptions javaOptions && javaOptions.isSkipImportStatements) { + PsiElement parent = usage.getParent(); + while (parent instanceof PsiJavaCodeReferenceElement) { + parent = parent.getParent(); + } + if (parent instanceof PsiImportStatement) { + return false; + } + } + + if (options instanceof JavaPackageFindUsagesOptions packageOptions && packageOptions.isSkipPackageStatements) { + PsiElement parent = usage.getParent(); + while (parent instanceof PsiJavaCodeReferenceElement) { + parent = parent.getParent(); + } + if (parent instanceof PsiPackageStatement) { + return false; + } + } } - } + return true; } - return true; - } } diff --git a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/psi/impl/search/ThrowSearchUtil.java b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/psi/impl/search/ThrowSearchUtil.java index 65f195ca0..1c296e46b 100644 --- a/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/psi/impl/search/ThrowSearchUtil.java +++ b/java-analysis-impl/src/main/java/com/intellij/java/analysis/impl/psi/impl/search/ThrowSearchUtil.java @@ -19,19 +19,20 @@ import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.util.PsiFormatUtil; import com.intellij.java.language.psi.util.PsiFormatUtilBase; -import consulo.application.util.function.Processor; +import consulo.annotation.access.RequiredReadAction; import consulo.find.FindUsagesOptions; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiReference; import consulo.logging.Logger; import consulo.usage.UsageInfo; import consulo.util.dataholder.Key; - +import consulo.util.lang.ObjectUtil; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; import java.util.HashSet; import java.util.Set; +import java.util.function.Predicate; /** * Author: msk @@ -44,16 +45,17 @@ private ThrowSearchUtil() { } public static class Root { - final PsiElement myElement; - final PsiType myType; - final boolean isExact; + PsiElement myElement; + PsiType myType; + boolean isExact; - public Root(final PsiElement root, final PsiType type, final boolean exact) { + public Root(PsiElement root, PsiType type, boolean exact) { myElement = root; myType = type; isExact = exact; } + @Override public String toString() { return PsiFormatUtil.formatType(myType, PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES, PsiSubstitutor.EMPTY); } @@ -67,34 +69,34 @@ public String toString() { * @param root * @return true, if we should continue processing */ - private static boolean processExn(@Nonnull PsiParameter aCatch, @Nonnull Processor processor, @Nonnull Root root) { - final PsiType type = aCatch.getType(); + private static boolean processExn(@Nonnull PsiParameter aCatch, @Nonnull Predicate processor, @Nonnull Root root) { + PsiType type = aCatch.getType(); if (type.isAssignableFrom(root.myType)) { - processor.process(new UsageInfo(aCatch)); + processor.test(new UsageInfo(aCatch)); return false; } if (!root.isExact && root.myType.isAssignableFrom(type)) { - processor.process(new UsageInfo(aCatch)); + processor.test(new UsageInfo(aCatch)); return true; } return true; } + @RequiredReadAction private static boolean scanCatches( @Nonnull PsiElement elem, - @Nonnull Processor processor, + @Nonnull Predicate processor, @Nonnull Root root, @Nonnull FindUsagesOptions options, @Nonnull Set processed ) { while (elem != null) { - final PsiElement parent = elem.getParent(); - if (elem instanceof PsiMethod) { - final PsiMethod deepestSuperMethod = ((PsiMethod)elem).findDeepestSuperMethod(); - final PsiMethod method = deepestSuperMethod != null ? deepestSuperMethod : (PsiMethod)elem; + PsiElement parent = elem.getParent(); + if (elem instanceof PsiMethod m) { + PsiMethod method = ObjectUtil.chooseNotNull(m.findDeepestSuperMethod(), m); if (!processed.contains(method)) { processed.add(method); - final PsiReference[] refs = + PsiReference[] refs = MethodReferencesSearch.search(method, options.searchScope, true).toArray(PsiReference.EMPTY_ARRAY); for (int i = 0; i != refs.length; ++i) { if (!scanCatches(refs[i].getElement(), processor, root, options, processed)) { @@ -104,17 +106,15 @@ private static boolean scanCatches( } return true; } - if (elem instanceof PsiTryStatement) { - final PsiTryStatement aTry = (PsiTryStatement)elem; - final PsiParameter[] catches = aTry.getCatchBlockParameters(); + if (elem instanceof PsiTryStatement tryStmt) { + PsiParameter[] catches = tryStmt.getCatchBlockParameters(); for (int i = 0; i != catches.length; ++i) { if (!processExn(catches[i], processor, root)) { return false; } } } - else if (parent instanceof PsiTryStatement) { - final PsiTryStatement tryStmt = (PsiTryStatement)parent; + else if (parent instanceof PsiTryStatement tryStmt) { if (elem != tryStmt.getTryBlock()) { elem = parent.getParent(); continue; @@ -125,8 +125,9 @@ else if (parent instanceof PsiTryStatement) { return true; } - public static boolean addThrowUsages(@Nonnull Processor processor, @Nonnull Root root, @Nonnull FindUsagesOptions options) { - Set processed = new HashSet(); + @RequiredReadAction + public static boolean addThrowUsages(@Nonnull Predicate processor, @Nonnull Root root, @Nonnull FindUsagesOptions options) { + Set processed = new HashSet<>(); return scanCatches(root.myElement, processor, root, options, processed); } @@ -135,45 +136,40 @@ public static boolean addThrowUsages(@Nonnull Processor processor, @N * @return is type of exn exactly known */ - private static boolean isExactExnType(final PsiExpression exn) { + private static boolean isExactExnType(PsiExpression exn) { return exn instanceof PsiNewExpression; } @Nullable - public static Root[] getSearchRoots(final PsiElement element) { - if (element instanceof PsiThrowStatement) { - final PsiThrowStatement aThrow = (PsiThrowStatement)element; - final PsiExpression exn = aThrow.getException(); + public static Root[] getSearchRoots(PsiElement element) { + if (element instanceof PsiThrowStatement aThrow) { + PsiExpression exn = aThrow.getException(); return new Root[]{new Root(aThrow.getParent(), exn.getType(), isExactExnType(exn))}; } - if (element instanceof PsiKeyword) { - final PsiKeyword kwd = (PsiKeyword)element; - if (PsiKeyword.THROWS.equals(kwd.getText())) { - final PsiElement parent = kwd.getParent(); - if (parent != null && parent.getParent() instanceof PsiMethod) { - final PsiMethod method = (PsiMethod)parent.getParent(); - final PsiReferenceList throwsList = method.getThrowsList(); - final PsiClassType[] exns = throwsList.getReferencedTypes(); - final Root[] roots = new Root[exns.length]; - for (int i = 0; i != roots.length; ++i) { - final PsiClassType exn = exns[i]; - roots[i] = new Root(method, exn, false); // TODO: test for final - } - return roots; + if (element instanceof PsiKeyword kwd && PsiKeyword.THROWS.equals(kwd.getText())) { + PsiElement parent = kwd.getParent(); + if (parent != null && parent.getParent() instanceof PsiMethod method) { + PsiReferenceList throwsList = method.getThrowsList(); + PsiClassType[] exns = throwsList.getReferencedTypes(); + Root[] roots = new Root[exns.length]; + for (int i = 0; i != roots.length; ++i) { + PsiClassType exn = exns[i]; + roots[i] = new Root(method, exn, false); // TODO: test for final } + return roots; } } return null; } - public static boolean isSearchable(final PsiElement element) { + public static boolean isSearchable(PsiElement element) { return getSearchRoots(element) != null; } - public static String getSearchableTypeName(final PsiElement e) { - if (e instanceof PsiThrowStatement) { - final PsiThrowStatement aThrow = (PsiThrowStatement)e; - final PsiType type = aThrow.getException().getType(); + @RequiredReadAction + public static String getSearchableTypeName(PsiElement e) { + if (e instanceof PsiThrowStatement aThrow) { + PsiType type = aThrow.getException().getType(); return PsiFormatUtil.formatType(type, PsiFormatUtilBase.SHOW_FQ_CLASS_NAMES, PsiSubstitutor.EMPTY); } if (e instanceof PsiKeyword && PsiKeyword.THROWS.equals(e.getText())) { diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearch.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearch.java index 5dc03f012..e9f42b51b 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearch.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearch.java @@ -19,12 +19,12 @@ */ package com.intellij.java.indexing.search.searches; -import consulo.project.Project; -import consulo.util.lang.function.Condition; import com.intellij.java.language.psi.PsiClass; -import consulo.content.scope.SearchScope; import consulo.application.util.query.ExtensibleQueryFactory; import consulo.application.util.query.Query; +import consulo.content.scope.SearchScope; +import consulo.project.Project; +import consulo.util.lang.function.Condition; import java.util.function.Predicate; @@ -34,13 +34,13 @@ public class AllClassesSearch extends ExtensibleQueryFactory myShortNameCondition; + private final Predicate myShortNameCondition; - public SearchParameters(final SearchScope scope, final Project project) { + public SearchParameters(SearchScope scope, Project project) { this(scope, project, Condition.TRUE); } - public SearchParameters(final SearchScope scope, final Project project, final Condition shortNameCondition) { + public SearchParameters(SearchScope scope, Project project, Predicate shortNameCondition) { myScope = scope; myProject = project; myShortNameCondition = shortNameCondition; @@ -55,7 +55,7 @@ public Project getProject() { } public boolean nameMatches(String name) { - return myShortNameCondition.value(name); + return myShortNameCondition.test(name); } } diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearchExecutor.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearchExecutor.java index 97cfbdd5f..d6bf963bf 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearchExecutor.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllClassesSearchExecutor.java @@ -7,7 +7,7 @@ /** * @author VISTALL - * @since 01-Sep-22 + * @since 2022-09-01 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface AllClassesSearchExecutor extends QueryExecutor { diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllOverridingMethodsSearchExecutor.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllOverridingMethodsSearchExecutor.java index a74bdd1d9..8f629f4a5 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllOverridingMethodsSearchExecutor.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AllOverridingMethodsSearchExecutor.java @@ -8,7 +8,7 @@ /** * @author VISTALL - * @since 01-Sep-22 + * @since 2022-09-01 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface AllOverridingMethodsSearchExecutor extends QueryExecutor, AllOverridingMethodsSearch.SearchParameters> { diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AnnotatedElementsSearchExecutor.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AnnotatedElementsSearchExecutor.java index 94f7197fc..316cc8d8a 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AnnotatedElementsSearchExecutor.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/AnnotatedElementsSearchExecutor.java @@ -7,7 +7,7 @@ /** * @author VISTALL - * @since 01-Sep-22 + * @since 2022-09-01 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface AnnotatedElementsSearchExecutor extends QueryExecutor { diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassInheritorsSearch.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassInheritorsSearch.java index 5e80469d9..4e31edd14 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassInheritorsSearch.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassInheritorsSearch.java @@ -16,7 +16,7 @@ package com.intellij.java.indexing.search.searches; import com.intellij.java.language.psi.PsiClass; -import consulo.application.ApplicationManager; +import consulo.application.Application; import consulo.application.util.query.ExtensibleQueryFactory; import consulo.application.util.query.Query; import consulo.component.ProcessCanceledException; @@ -24,105 +24,135 @@ import consulo.language.psi.SmartPointerManager; import consulo.language.psi.SmartPsiElementPointer; import consulo.util.collection.HashingStrategy; -import consulo.util.lang.function.Condition; import consulo.util.lang.function.Conditions; - import jakarta.annotation.Nonnull; + +import java.util.function.Predicate; import java.util.function.Supplier; /** * @author max */ public class ClassInheritorsSearch extends ExtensibleQueryFactory { - public static final ClassInheritorsSearch INSTANCE = new ClassInheritorsSearch(); - - public static class SearchParameters { - private final PsiClass myClass; - private final SearchScope myScope; - private final boolean myCheckDeep; - private final boolean myCheckInheritance; - private final boolean myIncludeAnonymous; - private final Condition myNameCondition; - - public SearchParameters(@Nonnull final PsiClass aClass, @Nonnull SearchScope scope, final boolean checkDeep, final boolean checkInheritance, boolean includeAnonymous) { - this(aClass, scope, checkDeep, checkInheritance, includeAnonymous, Conditions.alwaysTrue()); + public static final ClassInheritorsSearch INSTANCE = new ClassInheritorsSearch(); + + public static class SearchParameters { + private final PsiClass myClass; + private final SearchScope myScope; + private final boolean myCheckDeep; + private final boolean myCheckInheritance; + private final boolean myIncludeAnonymous; + private final Predicate myNameCondition; + + public SearchParameters( + @Nonnull PsiClass aClass, + @Nonnull SearchScope scope, + boolean checkDeep, + boolean checkInheritance, + boolean includeAnonymous + ) { + this(aClass, scope, checkDeep, checkInheritance, includeAnonymous, Conditions.alwaysTrue()); + } + + public SearchParameters( + @Nonnull PsiClass aClass, + @Nonnull SearchScope scope, + boolean checkDeep, + boolean checkInheritance, + boolean includeAnonymous, + @Nonnull Predicate nameCondition + ) { + myClass = aClass; + myScope = scope; + myCheckDeep = checkDeep; + myCheckInheritance = checkInheritance; + myIncludeAnonymous = includeAnonymous; + myNameCondition = nameCondition; + } + + @Nonnull + public PsiClass getClassToProcess() { + return myClass; + } + + @Nonnull + public Predicate getNameCondition() { + return myNameCondition; + } + + public boolean isCheckDeep() { + return myCheckDeep; + } + + public SearchScope getScope() { + return myScope; + } + + public boolean isCheckInheritance() { + return myCheckInheritance; + } + + public boolean isIncludeAnonymous() { + return myIncludeAnonymous; + } } - public SearchParameters(@Nonnull final PsiClass aClass, - @Nonnull SearchScope scope, - final boolean checkDeep, - final boolean checkInheritance, - boolean includeAnonymous, - @Nonnull final Condition nameCondition) { - myClass = aClass; - myScope = scope; - myCheckDeep = checkDeep; - myCheckInheritance = checkInheritance; - myIncludeAnonymous = includeAnonymous; - myNameCondition = nameCondition; + private ClassInheritorsSearch() { + super(ClassInheritorsSearchExecutor.class); } - @Nonnull - public PsiClass getClassToProcess() { - return myClass; + public static Query search( + @Nonnull PsiClass aClass, + @Nonnull SearchScope scope, + boolean checkDeep, + boolean checkInheritance, + boolean includeAnonymous + ) { + return search(new SearchParameters(aClass, scope, checkDeep, checkInheritance, includeAnonymous)); } - @Nonnull - public Condition getNameCondition() { - return myNameCondition; + public static Query search(@Nonnull SearchParameters parameters) { + return INSTANCE.createUniqueResultsQuery( + parameters, + HashingStrategy.canonical(), + it -> Application.get().runReadAction( + (Supplier>)() -> SmartPointerManager.getInstance(it.getProject()) + .createSmartPsiElementPointer(it) + ) + ); } - public boolean isCheckDeep() { - return myCheckDeep; + public static Query search( + @Nonnull PsiClass aClass, + @Nonnull SearchScope scope, + boolean checkDeep, + boolean checkInheritance + ) { + return search(aClass, scope, checkDeep, checkInheritance, true); } - public SearchScope getScope() { - return myScope; + public static Query search(@Nonnull PsiClass aClass, @Nonnull SearchScope scope, boolean checkDeep) { + return search(aClass, scope, checkDeep, true); } - public boolean isCheckInheritance() { - return myCheckInheritance; + public static Query search(@Nonnull PsiClass aClass, boolean checkDeep) { + return search( + aClass, + Application.get().runReadAction(new Supplier<>() { + @Override + public SearchScope get() { + if (!aClass.isValid()) { + throw new ProcessCanceledException(); + } + return aClass.getUseScope(); + } + }), + checkDeep + ); } - public boolean isIncludeAnonymous() { - return myIncludeAnonymous; + public static Query search(@Nonnull PsiClass aClass) { + return search(aClass, true); } - } - - private ClassInheritorsSearch() { - super(ClassInheritorsSearchExecutor.class); - } - - public static Query search(@Nonnull final PsiClass aClass, @Nonnull SearchScope scope, final boolean checkDeep, final boolean checkInheritance, boolean includeAnonymous) { - return search(new SearchParameters(aClass, scope, checkDeep, checkInheritance, includeAnonymous)); - } - - public static Query search(@Nonnull SearchParameters parameters) { - return INSTANCE.createUniqueResultsQuery(parameters, HashingStrategy.canonical(), it -> ApplicationManager.getApplication().runReadAction((Supplier>) () -> SmartPointerManager.getInstance(it.getProject()).createSmartPsiElementPointer(it))); - } - - public static Query search(@Nonnull final PsiClass aClass, @Nonnull SearchScope scope, final boolean checkDeep, final boolean checkInheritance) { - return search(aClass, scope, checkDeep, checkInheritance, true); - } - - public static Query search(@Nonnull final PsiClass aClass, @Nonnull SearchScope scope, final boolean checkDeep) { - return search(aClass, scope, checkDeep, true); - } - - public static Query search(@Nonnull final PsiClass aClass, final boolean checkDeep) { - return search(aClass, ApplicationManager.getApplication().runReadAction(new Supplier() { - @Override - public SearchScope get() { - if (!aClass.isValid()) { - throw new ProcessCanceledException(); - } - return aClass.getUseScope(); - } - }), checkDeep); - } - - public static Query search(@Nonnull PsiClass aClass) { - return search(aClass, true); - } } diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassInheritorsSearchExecutor.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassInheritorsSearchExecutor.java index 6efd49432..8dca56f73 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassInheritorsSearchExecutor.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassInheritorsSearchExecutor.java @@ -7,7 +7,7 @@ /** * @author VISTALL - * @since 01-Sep-22 + * @since 2022-09-01 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface ClassInheritorsSearchExecutor extends QueryExecutor { diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassesWithAnnotatedMembersSearchExecutor.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassesWithAnnotatedMembersSearchExecutor.java index 6bebbe8bc..249c2baf4 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassesWithAnnotatedMembersSearchExecutor.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/ClassesWithAnnotatedMembersSearchExecutor.java @@ -7,7 +7,7 @@ /** * @author VISTALL - * @since 01-Sep-22 + * @since 2022-09-01 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface ClassesWithAnnotatedMembersSearchExecutor extends QueryExecutor { diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/DirectClassInheritorsSearchExecutor.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/DirectClassInheritorsSearchExecutor.java index ddf5996a5..313c11c98 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/DirectClassInheritorsSearchExecutor.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/DirectClassInheritorsSearchExecutor.java @@ -7,7 +7,7 @@ /** * @author VISTALL - * @since 01-Sep-22 + * @since 2022-09-01 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface DirectClassInheritorsSearchExecutor extends QueryExecutor { diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/FunctionalExpressionSearchExecutor.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/FunctionalExpressionSearchExecutor.java index 32b068e03..71b71e17c 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/FunctionalExpressionSearchExecutor.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/FunctionalExpressionSearchExecutor.java @@ -7,7 +7,7 @@ /** * @author VISTALL - * @since 01-Sep-22 + * @since 2022-09-01 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface FunctionalExpressionSearchExecutor extends QueryExecutor { diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/MethodReferencesSearchExecutor.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/MethodReferencesSearchExecutor.java index 398e48c3a..9a1a42ca5 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/MethodReferencesSearchExecutor.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/MethodReferencesSearchExecutor.java @@ -7,7 +7,7 @@ /** * @author VISTALL - * @since 01-Sep-22 + * @since 2022-09-01 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface MethodReferencesSearchExecutor extends QueryExecutor { diff --git a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/OverridingMethodsSearchExecutor.java b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/OverridingMethodsSearchExecutor.java index 2eafffb3d..6e4479442 100644 --- a/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/OverridingMethodsSearchExecutor.java +++ b/java-indexing-api/src/main/java/com/intellij/java/indexing/search/searches/OverridingMethodsSearchExecutor.java @@ -7,7 +7,7 @@ /** * @author VISTALL - * @since 01-Sep-22 + * @since 2022-09-01 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface OverridingMethodsSearchExecutor extends QueryExecutor { diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/ClassImplementationsSearch.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/ClassImplementationsSearch.java index 0181c4954..1383a9030 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/ClassImplementationsSearch.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/ClassImplementationsSearch.java @@ -19,7 +19,6 @@ import com.intellij.java.indexing.search.searches.FunctionalExpressionSearch; import com.intellij.java.language.psi.PsiClass; import consulo.annotation.component.ExtensionImpl; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.language.psi.PsiElement; import consulo.language.psi.resolve.PsiElementProcessor; @@ -28,34 +27,23 @@ import consulo.language.psi.search.DefinitionsScopedSearchExecutor; import jakarta.annotation.Nonnull; +import java.util.function.Predicate; + @ExtensionImpl public class ClassImplementationsSearch implements DefinitionsScopedSearchExecutor { @Override public boolean execute( @Nonnull DefinitionsScopedSearch.SearchParameters queryParameters, - @Nonnull Processor consumer + @Nonnull Predicate consumer ) { - final PsiElement sourceElement = queryParameters.getElement(); - return !(sourceElement instanceof PsiClass) || processImplementations( - (PsiClass)sourceElement, - consumer, - queryParameters.getScope() - ); + PsiElement sourceElement = queryParameters.getElement(); + return !(sourceElement instanceof PsiClass psiClass) + || processImplementations(psiClass, consumer, queryParameters.getScope()); } - public static boolean processImplementations( - final PsiClass psiClass, - final Processor processor, - SearchScope scope - ) { - if (!FunctionalExpressionSearch.search(psiClass, scope).forEach(expression -> - { - return processor.process(expression); - })) { - return false; - } - - return ClassInheritorsSearch.search(psiClass, scope, true) - .forEach(new PsiElementProcessorAdapter<>((PsiElementProcessor)element -> processor.process(element))); + public static boolean processImplementations(PsiClass psiClass, Predicate processor, SearchScope scope) { + return FunctionalExpressionSearch.search(psiClass, scope).forEach(processor::test) + && ClassInheritorsSearch.search(psiClass, scope, true) + .forEach(new PsiElementProcessorAdapter<>((PsiElementProcessor)processor::test)); } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/CompositeShortNamesCache.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/CompositeShortNamesCache.java index 830807fa7..3a391b563 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/CompositeShortNamesCache.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/CompositeShortNamesCache.java @@ -22,24 +22,22 @@ import com.intellij.java.language.psi.search.PsiShortNamesCache; import consulo.annotation.component.ServiceImpl; import consulo.application.util.function.CommonProcessors; -import consulo.application.util.function.Processor; import consulo.language.psi.PsiFile; import consulo.language.psi.scope.GlobalSearchScope; import consulo.language.psi.stub.IdFilter; import consulo.project.Project; import consulo.util.collection.ArrayUtil; import consulo.util.collection.ContainerUtil; -import jakarta.inject.Inject; -import jakarta.inject.Singleton; -import org.jetbrains.annotations.NonNls; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import jakarta.inject.Inject; +import jakarta.inject.Singleton; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.function.Predicate; @Singleton @ServiceImpl @@ -109,7 +107,7 @@ public String[] getAllClassNames() { } @Override - public boolean processAllClassNames(Processor processor) { + public boolean processAllClassNames(Predicate processor) { CommonProcessors.UniqueProcessor uniqueProcessor = new CommonProcessors.UniqueProcessor<>(processor); for (PsiShortNameProvider cache : myCaches) { if (!cache.processAllClassNames(uniqueProcessor)) { @@ -120,7 +118,7 @@ public boolean processAllClassNames(Processor processor) { } @Override - public boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + public boolean processAllClassNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { for (PsiShortNameProvider cache : myCaches) { if (!cache.processAllClassNames(processor, scope, filter)) { return false; @@ -130,7 +128,7 @@ public boolean processAllClassNames(Processor processor, GlobalSearchSco } @Override - public boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + public boolean processAllMethodNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { for (PsiShortNameProvider cache : myCaches) { if (!cache.processAllMethodNames(processor, scope, filter)) { return false; @@ -140,7 +138,7 @@ public boolean processAllMethodNames(Processor processor, GlobalSearchSc } @Override - public boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + public boolean processAllFieldNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { for (PsiShortNameProvider cache : myCaches) { if (!cache.processAllFieldNames(processor, scope, filter)) { return false; @@ -175,11 +173,7 @@ public PsiMethod[] getMethodsByName(@Nonnull String name, @Nonnull GlobalSearchS @Override @Nonnull - public PsiMethod[] getMethodsByNameIfNotMoreThan( - @NonNls @Nonnull final String name, - @Nonnull final GlobalSearchScope scope, - final int maxCount - ) { + public PsiMethod[] getMethodsByNameIfNotMoreThan(@Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount) { Merger merger = null; for (PsiShortNameProvider cache : myCaches) { PsiMethod[] methods = cache.getMethodsByNameIfNotMoreThan(name, scope, maxCount); @@ -199,7 +193,7 @@ public PsiMethod[] getMethodsByNameIfNotMoreThan( @Nonnull @Override - public PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount) { + public PsiField[] getFieldsByNameIfNotMoreThan(@Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount) { Merger merger = null; for (PsiShortNameProvider cache : myCaches) { PsiField[] fields = cache.getFieldsByNameIfNotMoreThan(name, scope, maxCount); @@ -219,17 +213,19 @@ public PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @Nonnull String name, @No @Override public boolean processMethodsWithName( - @NonNls @Nonnull String name, + @Nonnull String name, @Nonnull GlobalSearchScope scope, - @Nonnull Processor processor + @Nonnull Predicate processor ) { return processMethodsWithName(name, processor, scope, null); } @Override public boolean processMethodsWithName( - @NonNls @Nonnull String name, @Nonnull Processor processor, - @Nonnull GlobalSearchScope scope, @Nullable IdFilter idFilter + @Nonnull String name, + @Nonnull Predicate processor, + @Nonnull GlobalSearchScope scope, + @Nullable IdFilter idFilter ) { for (PsiShortNameProvider cache : myCaches) { if (!cache.processMethodsWithName(name, processor, scope, idFilter)) { @@ -300,7 +296,9 @@ public void getAllFieldNames(@Nonnull HashSet set) { @Override public boolean processFieldsWithName( - @Nonnull String key, @Nonnull Processor processor, @Nonnull GlobalSearchScope scope, + @Nonnull String key, + @Nonnull Predicate processor, + @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter ) { for (PsiShortNameProvider cache : myCaches) { @@ -313,7 +311,9 @@ public boolean processFieldsWithName( @Override public boolean processClassesWithName( - @Nonnull String key, @Nonnull Processor processor, @Nonnull GlobalSearchScope scope, + @Nonnull String key, + @Nonnull Predicate processor, + @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter ) { for (PsiShortNameProvider cache : myCaches) { diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/MethodImplementationsSearch.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/MethodImplementationsSearch.java index bb2e1c37a..26b3de456 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/MethodImplementationsSearch.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/MethodImplementationsSearch.java @@ -17,10 +17,8 @@ import com.intellij.java.indexing.search.searches.FunctionalExpressionSearch; import com.intellij.java.indexing.search.searches.OverridingMethodsSearch; -import com.intellij.java.language.psi.PsiFunctionalExpression; import com.intellij.java.language.psi.PsiMethod; import consulo.annotation.component.ExtensionImpl; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.language.psi.PsiElement; import consulo.language.psi.search.DefinitionsScopedSearch; @@ -30,35 +28,28 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.Predicate; @ExtensionImpl public class MethodImplementationsSearch implements DefinitionsScopedSearchExecutor { @Override public boolean execute( - @Nonnull final DefinitionsScopedSearch.SearchParameters queryParameters, - @Nonnull final Processor consumer + @Nonnull DefinitionsScopedSearch.SearchParameters queryParameters, + @Nonnull Predicate consumer ) { - final PsiElement sourceElement = queryParameters.getElement(); - if (sourceElement instanceof PsiMethod) { - return processImplementations((PsiMethod)sourceElement, consumer, queryParameters.getScope()); - } - return true; + PsiElement sourceElement = queryParameters.getElement(); + return !(sourceElement instanceof PsiMethod method) || processImplementations(method, consumer, queryParameters.getScope()); } public static boolean processImplementations( - final PsiMethod psiMethod, - final Processor consumer, - final SearchScope searchScope + PsiMethod psiMethod, + Predicate consumer, + SearchScope searchScope ) { - if (!FunctionalExpressionSearch.search(psiMethod, searchScope).forEach(new Processor() { - @Override - public boolean process(PsiFunctionalExpression expression) { - return consumer.process(expression); - } - })) { + if (!FunctionalExpressionSearch.search(psiMethod, searchScope).forEach(consumer::test)) { return false; } - List methods = new ArrayList(); + List methods = new ArrayList<>(); getOverridingMethods(psiMethod, methods, searchScope); return ContainerUtil.process(methods, consumer); } @@ -71,8 +62,8 @@ public static void getOverridingMethods(PsiMethod method, List list, @SuppressWarnings("UnusedDeclaration") @Deprecated - public static PsiMethod[] getMethodImplementations(final PsiMethod method, SearchScope scope) { - List result = new ArrayList(); + public static PsiMethod[] getMethodImplementations(PsiMethod method, SearchScope scope) { + List result = new ArrayList<>(); getOverridingMethods(method, result, scope); return result.toArray(new PsiMethod[result.size()]); diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/PsiShortNamesCacheImpl.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/PsiShortNamesCacheImpl.java index 2bd785efe..1995b36a9 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/PsiShortNamesCacheImpl.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/PsiShortNamesCacheImpl.java @@ -25,10 +25,10 @@ import com.intellij.java.language.psi.PsiMember; import com.intellij.java.language.psi.PsiMethod; import com.intellij.java.language.psi.search.PsiShortNameProvider; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ExtensionImpl; import consulo.application.progress.ProgressIndicatorProvider; import consulo.application.util.function.CommonProcessors; -import consulo.application.util.function.Processor; import consulo.language.psi.PsiFile; import consulo.language.psi.PsiManager; import consulo.language.psi.scope.GlobalSearchScope; @@ -41,13 +41,12 @@ import consulo.util.collection.Sets; import consulo.util.collection.SmartList; import consulo.virtualFileSystem.VirtualFile; +import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; import jakarta.inject.Inject; -import org.jetbrains.annotations.NonNls; - -import jakarta.annotation.Nonnull; import java.util.*; +import java.util.function.Predicate; @ExtensionImpl public class PsiShortNamesCacheImpl implements PsiShortNameProvider { @@ -58,8 +57,9 @@ public PsiShortNamesCacheImpl(Project project) { myProject = project; } - @Override @Nonnull + @Override + @RequiredReadAction public PsiFile[] getFilesByName(@Nonnull String name) { return FilenameIndex.getFilesByName(myProject, name, GlobalSearchScope.projectScope(myProject)); } @@ -72,13 +72,13 @@ public String[] getAllFileNames() { @Override @Nonnull - public PsiClass[] getClassesByName(@Nonnull String name, @Nonnull final GlobalSearchScope scope) { - final Collection classes = JavaShortClassNameIndex.getInstance().get(name, myProject, scope); + public PsiClass[] getClassesByName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { + Collection classes = JavaShortClassNameIndex.getInstance().get(name, myProject, scope); if (classes.isEmpty()) { return PsiClass.EMPTY_ARRAY; } - ArrayList list = new ArrayList(classes.size()); + ArrayList list = new ArrayList<>(classes.size()); OuterLoop: for (PsiClass aClass : classes) { @@ -119,32 +119,32 @@ public String[] getAllClassNames() { @Override public void getAllClassNames(@Nonnull HashSet set) { - processAllClassNames(new CommonProcessors.CollectProcessor(set)); + processAllClassNames(new CommonProcessors.CollectProcessor<>(set)); } @Override - public boolean processAllClassNames(Processor processor) { + public boolean processAllClassNames(Predicate processor) { return JavaShortClassNameIndex.getInstance().processAllKeys(myProject, processor); } @Override - public boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + public boolean processAllClassNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.CLASS_SHORT_NAMES, processor, scope, filter); } @Override - public boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + public boolean processAllMethodNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.METHODS, processor, scope, filter); } @Override - public boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + public boolean processAllFieldNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { return StubIndex.getInstance().processAllKeys(JavaStubIndexKeys.FIELDS, processor, scope, filter); } @Override @Nonnull - public PsiMethod[] getMethodsByName(@Nonnull String name, @Nonnull final GlobalSearchScope scope) { + public PsiMethod[] getMethodsByName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { Collection methods = StubIndex.getElements(JavaStubIndexKeys.METHODS, name, myProject, new JavaSourceFilterScope(scope), PsiMethod.class ); @@ -159,19 +159,15 @@ public PsiMethod[] getMethodsByName(@Nonnull String name, @Nonnull final GlobalS @Override @Nonnull - public PsiMethod[] getMethodsByNameIfNotMoreThan( - @NonNls @Nonnull final String name, - @Nonnull final GlobalSearchScope scope, - final int maxCount - ) { - final List methods = new SmartList(); + public PsiMethod[] getMethodsByNameIfNotMoreThan(@Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount) { + List methods = new SmartList<>(); StubIndex.getInstance().processElements( JavaStubIndexKeys.METHODS, name, myProject, scope, PsiMethod.class, - new CommonProcessors.CollectProcessor(methods) { + new CommonProcessors.CollectProcessor<>(methods) { @Override public boolean process(PsiMethod method) { return methods.size() != maxCount && super.process(method); @@ -188,9 +184,9 @@ public boolean process(PsiMethod method) { @Override public boolean processMethodsWithName( - @NonNls @Nonnull String name, + @Nonnull String name, @Nonnull GlobalSearchScope scope, - @Nonnull Processor processor + @Nonnull Predicate processor ) { return StubIndex.getInstance().processElements(JavaStubIndexKeys.METHODS, name, myProject, scope, PsiMethod.class, processor); } @@ -203,20 +199,20 @@ public String[] getAllMethodNames() { @Override public void getAllMethodNames(@Nonnull HashSet set) { - JavaMethodNameIndex.getInstance().processAllKeys(myProject, new CommonProcessors.CollectProcessor(set)); + JavaMethodNameIndex.getInstance().processAllKeys(myProject, new CommonProcessors.CollectProcessor<>(set)); } @Override @Nonnull - public PsiField[] getFieldsByNameIfNotMoreThan(@Nonnull String name, @Nonnull final GlobalSearchScope scope, final int maxCount) { - final List methods = new SmartList(); + public PsiField[] getFieldsByNameIfNotMoreThan(@Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount) { + List methods = new SmartList<>(); StubIndex.getInstance().processElements( JavaStubIndexKeys.FIELDS, name, myProject, scope, PsiField.class, - new CommonProcessors.CollectProcessor(methods) { + new CommonProcessors.CollectProcessor<>(methods) { @Override public boolean process(PsiField method) { return methods.size() != maxCount && super.process(method); @@ -233,8 +229,8 @@ public boolean process(PsiField method) { @Nonnull @Override - public PsiField[] getFieldsByName(@Nonnull String name, @Nonnull final GlobalSearchScope scope) { - final Collection fields = JavaFieldNameIndex.getInstance().get(name, myProject, scope); + public PsiField[] getFieldsByName(@Nonnull String name, @Nonnull GlobalSearchScope scope) { + Collection fields = JavaFieldNameIndex.getInstance().get(name, myProject, scope); if (fields.isEmpty()) { return PsiField.EMPTY_ARRAY; @@ -252,13 +248,13 @@ public String[] getAllFieldNames() { @Override public void getAllFieldNames(@Nonnull HashSet set) { - JavaFieldNameIndex.getInstance().processAllKeys(myProject, new CommonProcessors.CollectProcessor(set)); + JavaFieldNameIndex.getInstance().processAllKeys(myProject, new CommonProcessors.CollectProcessor<>(set)); } @Override public boolean processFieldsWithName( @Nonnull String name, - @Nonnull Processor processor, + @Nonnull Predicate processor, @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter ) { @@ -275,8 +271,8 @@ public boolean processFieldsWithName( @Override public boolean processMethodsWithName( - @NonNls @Nonnull String name, - @Nonnull Processor processor, + @Nonnull String name, + @Nonnull Predicate processor, @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter ) { @@ -295,7 +291,7 @@ public boolean processMethodsWithName( @Override public boolean processClassesWithName( @Nonnull String name, - @Nonnull Processor processor, + @Nonnull Predicate processor, @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter ) { @@ -310,13 +306,14 @@ public boolean processClassesWithName( ); } - private List filterMembers(Collection members, final GlobalSearchScope scope) { - List result = new ArrayList(members.size()); + private List filterMembers(Collection members, GlobalSearchScope scope) { + List result = new ArrayList<>(members.size()); Set set = Sets.newHashSet(members.size(), new HashingStrategy() { @Override + @RequiredReadAction public int hashCode(PsiMember member) { int code = 0; - final PsiClass clazz = member.getContainingClass(); + PsiClass clazz = member.getContainingClass(); if (clazz != null) { String name = clazz.getName(); if (name != null) { @@ -327,8 +324,8 @@ public int hashCode(PsiMember member) { code += clazz.hashCode(); } } - if (member instanceof PsiMethod) { - code += 37 * ((PsiMethod)member).getParameterList().getParametersCount(); + if (member instanceof PsiMethod method) { + code += 37 * method.getParameterList().getParametersCount(); } return code; } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AllClassesSearchExecutor.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AllClassesSearchExecutor.java index 2cb95cb49..7ed3bf3a3 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AllClassesSearchExecutor.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AllClassesSearchExecutor.java @@ -26,11 +26,9 @@ import com.intellij.java.language.psi.PsiClass; import com.intellij.java.language.psi.search.PsiShortNamesCache; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ApplicationManager; +import consulo.application.Application; import consulo.application.progress.ProgressIndicator; import consulo.application.progress.ProgressIndicatorProvider; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.language.psi.PsiCompiledElement; import consulo.language.psi.PsiElement; @@ -38,26 +36,27 @@ import consulo.language.psi.scope.LocalSearchScope; import consulo.language.psi.stub.IdFilter; import consulo.project.Project; - import jakarta.annotation.Nonnull; import java.util.*; +import java.util.function.Predicate; +import java.util.function.Supplier; @ExtensionImpl public class AllClassesSearchExecutor implements com.intellij.java.indexing.search.searches.AllClassesSearchExecutor { @Override public boolean execute( - @Nonnull final AllClassesSearch.SearchParameters queryParameters, - @Nonnull final Processor consumer + @Nonnull AllClassesSearch.SearchParameters queryParameters, + @Nonnull Predicate consumer ) { SearchScope scope = queryParameters.getScope(); - if (scope instanceof GlobalSearchScope) { - return processAllClassesInGlobalScope((GlobalSearchScope)scope, queryParameters, consumer); + if (scope instanceof GlobalSearchScope globalSearchScope) { + return processAllClassesInGlobalScope(globalSearchScope, queryParameters, consumer); } PsiElement[] scopeRoots = ((LocalSearchScope)scope).getScope(); - for (final PsiElement scopeRoot : scopeRoots) { + for (PsiElement scopeRoot : scopeRoots) { if (!processScopeRootForAllClasses(scopeRoot, consumer)) { return false; } @@ -66,19 +65,23 @@ public boolean execute( } private static boolean processAllClassesInGlobalScope( - @Nonnull final GlobalSearchScope scope, - @Nonnull final AllClassesSearch.SearchParameters parameters, - @Nonnull Processor processor + @Nonnull GlobalSearchScope scope, + @Nonnull AllClassesSearch.SearchParameters parameters, + @Nonnull Predicate processor ) { - final Set names = new HashSet(10000); - processClassNames(parameters.getProject(), scope, s -> { - if (parameters.nameMatches(s)) { - names.add(s); + Set names = new HashSet<>(10000); + processClassNames( + parameters.getProject(), + scope, + s -> { + if (parameters.nameMatches(s)) { + names.add(s); + } + return true; } - return true; - }); + ); - List sorted = new ArrayList(names); + List sorted = new ArrayList<>(names); Collections.sort(sorted, String.CASE_INSENSITIVE_ORDER); return processClassesByNames(parameters.getProject(), scope, sorted, processor); @@ -86,22 +89,17 @@ private static boolean processAllClassesInGlobalScope( public static boolean processClassesByNames( Project project, - final GlobalSearchScope scope, + GlobalSearchScope scope, Collection names, - Processor processor + Predicate processor ) { - final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project); - for (final String name : names) { + PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project); + for (String name : names) { ProgressIndicatorProvider.checkCanceled(); - final PsiClass[] classes = MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public PsiClass[] compute() { - return cache.getClassesByName(name, scope); - } - }); + PsiClass[] classes = MethodUsagesSearcher.resolveInReadAction(project, () -> cache.getClassesByName(name, scope)); for (PsiClass psiClass : classes) { ProgressIndicatorProvider.checkCanceled(); - if (!processor.process(psiClass)) { + if (!processor.test(psiClass)) { return false; } } @@ -109,26 +107,30 @@ public PsiClass[] compute() { return true; } - public static Project processClassNames(final Project project, final GlobalSearchScope scope, final Processor consumer) { - final ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); - - MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public Void compute() { - PsiShortNamesCache.getInstance(project).processAllClassNames(new Processor() { - int i = 0; - - @Override - public boolean process(String s) { - if (indicator != null && i++ % 512 == 0) { - indicator.checkCanceled(); + public static Project processClassNames(Project project, GlobalSearchScope scope, Predicate consumer) { + ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); + + MethodUsagesSearcher.resolveInReadAction( + project, + (Supplier)() -> { + PsiShortNamesCache.getInstance(project).processAllClassNames( + new Predicate<>() { + int i = 0; + + @Override + public boolean test(String s) { + if (indicator != null && i++ % 512 == 0) { + indicator.checkCanceled(); + } + return consumer.test(s); } - return consumer.process(s); - } - }, scope, IdFilter.getProjectIdFilter(project, true)); + }, + scope, + IdFilter.getProjectIdFilter(project, true) + ); return null; } - }); + ); if (indicator != null) { indicator.checkCanceled(); @@ -137,12 +139,13 @@ public boolean process(String s) { } private static boolean processScopeRootForAllClasses( - @Nonnull final PsiElement scopeRoot, - @Nonnull final Processor processor + @Nonnull PsiElement scopeRoot, + @Nonnull Predicate processor ) { - final boolean[] stopped = {false}; + boolean[] stopped = {false}; - final JavaElementVisitor visitor = scopeRoot instanceof PsiCompiledElement ? new JavaRecursiveElementVisitor() { + JavaElementVisitor visitor = scopeRoot instanceof PsiCompiledElement + ? new JavaRecursiveElementVisitor() { @Override public void visitElement(PsiElement element) { if (!stopped[0]) { @@ -151,11 +154,12 @@ public void visitElement(PsiElement element) { } @Override - public void visitClass(PsiClass aClass) { - stopped[0] = !processor.process(aClass); + public void visitClass(@Nonnull PsiClass aClass) { + stopped[0] = !processor.test(aClass); super.visitClass(aClass); } - } : new JavaRecursiveElementWalkingVisitor() { + } + : new JavaRecursiveElementWalkingVisitor() { @Override public void visitElement(PsiElement element) { if (!stopped[0]) { @@ -164,17 +168,12 @@ public void visitElement(PsiElement element) { } @Override - public void visitClass(PsiClass aClass) { - stopped[0] = !processor.process(aClass); + public void visitClass(@Nonnull PsiClass aClass) { + stopped[0] = !processor.test(aClass); super.visitClass(aClass); } }; - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - scopeRoot.accept(visitor); - } - }); + Application.get().runReadAction(() -> scopeRoot.accept(visitor)); return !stopped[0]; } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AnnotatedElementsSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AnnotatedElementsSearcher.java index 6b3dddc98..6dd82c119 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AnnotatedElementsSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/AnnotatedElementsSearcher.java @@ -20,21 +20,20 @@ import com.intellij.java.indexing.search.searches.AnnotatedElementsSearchExecutor; import com.intellij.java.language.psi.*; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ApplicationManager; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; +import consulo.application.Application; import consulo.content.scope.SearchScope; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiManager; import consulo.language.psi.scope.GlobalSearchScope; import consulo.language.psi.scope.LocalSearchScope; import consulo.language.psi.util.PsiTreeUtil; -import consulo.util.collection.ContainerUtil; - import jakarta.annotation.Nonnull; +import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.function.Predicate; +import java.util.function.Supplier; /** * @author max @@ -43,55 +42,43 @@ public class AnnotatedElementsSearcher implements AnnotatedElementsSearchExecutor { @Override public boolean execute( - @Nonnull final AnnotatedElementsSearch.Parameters p, - @Nonnull final Processor consumer + @Nonnull AnnotatedElementsSearch.Parameters p, + @Nonnull Predicate consumer ) { - final PsiClass annClass = p.getAnnotationClass(); + PsiClass annClass = p.getAnnotationClass(); assert annClass.isAnnotationType() : "Annotation type should be passed to annotated members search"; - final String annotationFQN = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - return annClass.getQualifiedName(); - } - }); + Application app = Application.get(); + String annotationFQN = app.runReadAction((Supplier)annClass::getQualifiedName); assert annotationFQN != null; - final PsiManager psiManager = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiManager compute() { - return annClass.getManager(); - } - }); - - final SearchScope useScope = p.getScope(); - final Class[] types = p.getTypes(); + PsiManager psiManager = app.runReadAction((Supplier)annClass::getManager); - for (final PsiAnnotation ann : getAnnotationCandidates(annClass, useScope)) { - final PsiModifierListOwner candidate = - ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiModifierListOwner compute() { - PsiElement parent = ann.getParent(); - if (!(parent instanceof PsiModifierList)) { - return null; // Can be a PsiNameValuePair, if annotation is used to annotate annotation parameters - } + SearchScope useScope = p.getScope(); + Class[] types = p.getTypes(); - final PsiElement owner = parent.getParent(); - if (!isInstanceof(owner, types)) { - return null; - } + for (PsiAnnotation ann : getAnnotationCandidates(annClass, useScope)) { + PsiModifierListOwner candidate = + app.runReadAction((Supplier)() -> { + PsiElement parent = ann.getParent(); + if (!(parent instanceof PsiModifierList)) { + return null; // Can be a PsiNameValuePair, if annotation is used to annotate annotation parameters + } - final PsiJavaCodeReferenceElement ref = ann.getNameReferenceElement(); - if (ref == null || !psiManager.areElementsEquivalent(ref.resolve(), annClass)) { - return null; - } + PsiElement owner = parent.getParent(); + if (!isInstanceof(owner, types)) { + return null; + } - return (PsiModifierListOwner)owner; + PsiJavaCodeReferenceElement ref = ann.getNameReferenceElement(); + if (ref == null || !psiManager.areElementsEquivalent(ref.resolve(), annClass)) { + return null; } + + return (PsiModifierListOwner)owner; }); - if (candidate != null && !consumer.process(candidate)) { + if (candidate != null && !consumer.test(candidate)) { return false; } } @@ -99,20 +86,17 @@ public PsiModifierListOwner compute() { return true; } - private static Collection getAnnotationCandidates(final PsiClass annClass, final SearchScope useScope) { - return ApplicationManager.getApplication().runReadAction(new Computable>() { - @Override - public Collection compute() { - if (useScope instanceof GlobalSearchScope) { - return JavaAnnotationIndex.getInstance().get(annClass.getName(), annClass.getProject(), (GlobalSearchScope)useScope); - } + private static Collection getAnnotationCandidates(PsiClass annClass, SearchScope useScope) { + return Application.get().runReadAction((Supplier>)() -> { + if (useScope instanceof GlobalSearchScope globalSearchScope) { + return JavaAnnotationIndex.getInstance().get(annClass.getName(), annClass.getProject(), globalSearchScope); + } - final List result = ContainerUtil.newArrayList(); - for (PsiElement element : ((LocalSearchScope)useScope).getScope()) { - result.addAll(PsiTreeUtil.findChildrenOfType(element, PsiAnnotation.class)); - } - return result; + List result = new ArrayList<>(); + for (PsiElement element : ((LocalSearchScope)useScope).getScope()) { + result.addAll(PsiTreeUtil.findChildrenOfType(element, PsiAnnotation.class)); } + return result; }); } @@ -124,5 +108,4 @@ public static boolean isInstanceof(PsiElement owner, Class consumer + @Nonnull Predicate consumer ) { SearchScope scope = queryParameters.getScope(); for (QueryExecutor executor : Application.get().getExtensionList(ClassesWithAnnotatedMembersSearchExecutor.class)) { - if (executor instanceof ScopedQueryExecutor) { - scope = scope.intersectWith(GlobalSearchScope.notScope(((ScopedQueryExecutor)executor).getScope(queryParameters))); + if (executor instanceof ScopedQueryExecutor scopedQueryExecutor) { + scope = scope.intersectWith(GlobalSearchScope.notScope(scopedQueryExecutor.getScope(queryParameters))); } } - final Set processed = new HashSet<>(); + Set processed = new HashSet<>(); AnnotatedElementsSearch.searchPsiMembers(queryParameters.getAnnotationClass(), scope).forEach(member -> { - PsiClass psiClass = ReadAction.compute(() -> member instanceof PsiClass ? (PsiClass)member : member.getContainingClass()); + PsiClass psiClass = AccessRule.read(() -> member instanceof PsiClass clazz ? clazz : member.getContainingClass()); if (psiClass != null && processed.add(psiClass)) { - consumer.process(psiClass); + consumer.test(psiClass); } return true; diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearchHelper.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearchHelper.java index 1f7a8662f..31d7622c0 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearchHelper.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearchHelper.java @@ -22,8 +22,6 @@ import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.util.PsiUtil; import consulo.annotation.access.RequiredReadAction; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.document.util.TextRange; import consulo.document.util.UnfairTextRange; @@ -36,10 +34,12 @@ import consulo.language.psi.search.SearchRequestCollector; import consulo.project.DumbService; import consulo.project.Project; -import consulo.util.lang.function.PairProcessor; - import jakarta.annotation.Nonnull; +import java.util.function.BiPredicate; +import java.util.function.Predicate; +import java.util.function.Supplier; + /** * @author max */ @@ -57,28 +57,28 @@ public ConstructorReferencesSearchHelper(@Nonnull PsiManager manager) { * and so getProject would fail with an assertion that read action is required but not present. */ public boolean processConstructorReferences( - @Nonnull final Processor processor, - @Nonnull final PsiMethod constructor, - @Nonnull final PsiClass containingClass, - @Nonnull final SearchScope searchScope, - @Nonnull final Project project, + @Nonnull Predicate processor, + @Nonnull PsiMethod constructor, + @Nonnull PsiClass containingClass, + @Nonnull SearchScope searchScope, + @Nonnull Project project, boolean ignoreAccessScope, - final boolean isStrictSignatureSearch, + boolean isStrictSignatureSearch, @Nonnull SearchRequestCollector collector ) { - final boolean[] constructorCanBeCalledImplicitly = new boolean[1]; - final boolean[] isEnum = new boolean[1]; - final boolean[] isUnder18 = new boolean[1]; + boolean[] constructorCanBeCalledImplicitly = new boolean[1]; + boolean[] isEnum = new boolean[1]; + boolean[] isUnder18 = new boolean[1]; - MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public Void compute() { + MethodUsagesSearcher.resolveInReadAction( + project, + (Supplier)() -> { constructorCanBeCalledImplicitly[0] = constructor.getParameterList().getParametersCount() == 0; isEnum[0] = containingClass.isEnum(); isUnder18[0] = PsiUtil.getLanguageLevel(containingClass).isAtLeast(LanguageLevel.JDK_1_8); return null; } - }); + ); if (isEnum[0]) { if (!processEnumReferences(processor, constructor, project, containingClass)) { @@ -87,30 +87,27 @@ public Void compute() { } // search usages like "new XXX(..)" - PairProcessor processor1 = new PairProcessor() { - @Override - public boolean process(PsiReference reference, SearchRequestCollector collector) { - PsiElement parent = reference.getElement().getParent(); - if (parent instanceof PsiAnonymousClass) { - parent = parent.getParent(); - } - if (parent instanceof PsiNewExpression) { - PsiMethod constructor1 = ((PsiNewExpression)parent).resolveConstructor(); - if (constructor1 != null) { - if (isStrictSignatureSearch) { - if (myManager.areElementsEquivalent(constructor, constructor1)) { - return processor.process(reference); - } + BiPredicate processor1 = (reference, collector1) -> { + PsiElement parent = reference.getElement().getParent(); + if (parent instanceof PsiAnonymousClass) { + parent = parent.getParent(); + } + if (parent instanceof PsiNewExpression newExpr) { + PsiMethod constructor1 = newExpr.resolveConstructor(); + if (constructor1 != null) { + if (isStrictSignatureSearch) { + if (myManager.areElementsEquivalent(constructor, constructor1)) { + return processor.test(reference); } - else { - if (myManager.areElementsEquivalent(containingClass, constructor1.getContainingClass())) { - return processor.process(reference); - } + } + else { + if (myManager.areElementsEquivalent(containingClass, constructor1.getContainingClass())) { + return processor.test(reference); } } } - return true; } + return true; }; ReferencesSearch.searchOptimized(containingClass, searchScope, ignoreAccessScope, collector, true, processor1); @@ -121,113 +118,93 @@ public boolean process(PsiReference reference, SearchRequestCollector collector) } // search usages like "this(..)" - if (!MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public Boolean compute() { - return processSuperOrThis( - containingClass, - constructor, - constructorCanBeCalledImplicitly[0], - searchScope, - project, - isStrictSignatureSearch, - PsiKeyword.THIS, - processor - ); - } - })) { + if (!MethodUsagesSearcher.resolveInReadAction( + project, + () -> processSuperOrThis( + containingClass, + constructor, + constructorCanBeCalledImplicitly[0], + searchScope, + project, + isStrictSignatureSearch, + PsiKeyword.THIS, + processor + ) + )) { return false; } // search usages like "super(..)" - Processor processor2 = new Processor() { - @Override - public boolean process(PsiClass inheritor) { - final PsiElement navigationElement = inheritor.getNavigationElement(); - if (navigationElement instanceof PsiClass) { - return processSuperOrThis( - (PsiClass)navigationElement, - constructor, - constructorCanBeCalledImplicitly[0], - searchScope, - project, - isStrictSignatureSearch, - PsiKeyword.SUPER, - processor - ); - } - return true; - } + Predicate processor2 = inheritor -> { + PsiElement navigationElement = inheritor.getNavigationElement(); + return !(navigationElement instanceof PsiClass psiClass) || processSuperOrThis( + psiClass, + constructor, + constructorCanBeCalledImplicitly[0], + searchScope, + project, + isStrictSignatureSearch, + PsiKeyword.SUPER, + processor + ); }; return ClassInheritorsSearch.search(containingClass, searchScope, false).forEach(processor2); } private static boolean processEnumReferences( - @Nonnull final Processor processor, - @Nonnull final PsiMethod constructor, - @Nonnull final Project project, - @Nonnull final PsiClass aClass + @Nonnull Predicate processor, + @Nonnull PsiMethod constructor, + @Nonnull Project project, + @Nonnull PsiClass aClass ) { - return MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public Boolean compute() { + return MethodUsagesSearcher.resolveInReadAction( + project, + () -> { for (PsiField field : aClass.getFields()) { if (field instanceof PsiEnumConstant) { PsiReference reference = field.getReference(); - if (reference != null && reference.isReferenceTo(constructor)) { - if (!processor.process(reference)) { - return false; - } + if (reference != null && reference.isReferenceTo(constructor) && !processor.test(reference)) { + return false; } } } return true; } - }); + ); } private static boolean process18MethodPointers( - @Nonnull final Processor processor, - @Nonnull final PsiMethod constructor, - @Nonnull final Project project, + @Nonnull Predicate processor, + @Nonnull PsiMethod constructor, + @Nonnull Project project, @Nonnull PsiClass aClass, SearchScope searchScope ) { - return ReferencesSearch.search(aClass, searchScope).forEach(new Processor() { - @Override - public boolean process(PsiReference reference) { - final PsiElement element = reference.getElement(); - if (element != null) { - return MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public Boolean compute() { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiMethodReferenceExpression && ((PsiMethodReferenceExpression)parent).getReferenceNameElement() instanceof PsiKeyword) { - if (((PsiMethodReferenceExpression)parent).isReferenceTo(constructor)) { - if (!processor.process((PsiReference)parent)) { - return false; - } - } - } - return true; - } - }); - } - return true; + return ReferencesSearch.search(aClass, searchScope).forEach(reference -> { + PsiElement element = reference.getElement(); + if (element != null) { + return MethodUsagesSearcher.resolveInReadAction( + project, + () -> !(element.getParent() instanceof PsiMethodReferenceExpression methodReferenceExpression + && methodReferenceExpression.getReferenceNameElement() instanceof PsiKeyword + && methodReferenceExpression.isReferenceTo(constructor) + && !processor.test(methodReferenceExpression)) + ); } + return true; }); } private boolean processSuperOrThis( @Nonnull PsiClass inheritor, @Nonnull PsiMethod constructor, - final boolean constructorCanBeCalledImplicitly, + boolean constructorCanBeCalledImplicitly, @Nonnull SearchScope searchScope, @Nonnull Project project, - final boolean isStrictSignatureSearch, + boolean isStrictSignatureSearch, @Nonnull String superOrThisKeyword, - @Nonnull Processor processor + @Nonnull Predicate processor ) { PsiMethod[] constructors = inheritor.getConstructors(); if (constructors.length == 0 && constructorCanBeCalledImplicitly) { @@ -243,29 +220,23 @@ private boolean processSuperOrThis( PsiStatement[] statements = body.getStatements(); if (statements.length != 0) { PsiStatement statement = statements[0]; - if (statement instanceof PsiExpressionStatement) { - PsiExpression expr = ((PsiExpressionStatement)statement).getExpression(); - if (expr instanceof PsiMethodCallExpression) { - PsiReferenceExpression refExpr = ((PsiMethodCallExpression)expr).getMethodExpression(); - if (PsiSearchScopeUtil.isInScope(searchScope, refExpr)) { - if (refExpr.textMatches(superOrThisKeyword)) { - PsiElement referencedElement = refExpr.resolve(); - if (referencedElement instanceof PsiMethod) { - PsiMethod constructor1 = (PsiMethod)referencedElement; - boolean match = isStrictSignatureSearch - ? myManager.areElementsEquivalent(constructor1, constructor) - : myManager.areElementsEquivalent( - constructor.getContainingClass(), - constructor1.getContainingClass() - ); - if (match && !processor.process(refExpr)) { - return false; - } - } - //as long as we've encountered super/this keyword, no implicit ctr calls are possible here - continue; + if (statement instanceof PsiExpressionStatement exprStmt + && exprStmt.getExpression() instanceof PsiMethodCallExpression methodCall) { + PsiReferenceExpression refExpr = methodCall.getMethodExpression(); + if (PsiSearchScopeUtil.isInScope(searchScope, refExpr) && refExpr.textMatches(superOrThisKeyword)) { + if (refExpr.resolve() instanceof PsiMethod constructor1) { + boolean match = isStrictSignatureSearch + ? myManager.areElementsEquivalent(constructor1, constructor) + : myManager.areElementsEquivalent( + constructor.getContainingClass(), + constructor1.getContainingClass() + ); + if (match && !processor.test(refExpr)) { + return false; } } + //as long as we've encountered super/this keyword, no implicit ctr calls are possible here + continue; } } } @@ -280,11 +251,11 @@ private boolean processSuperOrThis( } private boolean processImplicitConstructorCall( - @Nonnull final PsiMember usage, - @Nonnull final Processor processor, - @Nonnull final PsiMethod constructor, - @Nonnull final Project project, - @Nonnull final PsiClass containingClass + @Nonnull PsiMember usage, + @Nonnull Predicate processor, + @Nonnull PsiMethod constructor, + @Nonnull Project project, + @Nonnull PsiClass containingClass ) { if (containingClass instanceof PsiAnonymousClass) { return true; @@ -306,11 +277,12 @@ private boolean processImplicitConstructorCall( boolean resolvesToThisConstructor = DumbService.getInstance(project).runReadActionInSmartMode( () -> myManager.areElementsEquivalent(constructor, resolved)); + //noinspection SimplifiableIfStatement if (!resolvesToThisConstructor) { return true; } - return processor.process(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) { + return processor.test(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) { @Nonnull @Override public PsiElement getElement() { @@ -321,10 +293,10 @@ public PsiElement getElement() { @Override @RequiredReadAction public TextRange getRangeInElement() { - if (usage instanceof PsiNameIdentifierOwner) { - PsiElement identifier = ((PsiNameIdentifierOwner)usage).getNameIdentifier(); + if (usage instanceof PsiNameIdentifierOwner nameIdentifierOwner) { + PsiElement identifier = nameIdentifierOwner.getNameIdentifier(); if (identifier != null) { - final int startOffsetInParent = identifier.getStartOffsetInParent(); + int startOffsetInParent = identifier.getStartOffsetInParent(); if (startOffsetInParent >= 0) { // -1 for light elements generated e.g. by lombok return TextRange.from(startOffsetInParent, identifier.getTextLength()); } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearcher.java index 00d1ba499..b0a82b1dd 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/ConstructorReferencesSearcher.java @@ -3,9 +3,7 @@ import com.intellij.java.language.psi.PsiClass; import com.intellij.java.language.psi.PsiMethod; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ApplicationManager; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; +import consulo.application.Application; import consulo.content.scope.SearchScope; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiManager; @@ -15,39 +13,33 @@ import consulo.project.util.query.QueryExecutorBase; import jakarta.annotation.Nonnull; +import java.util.function.Predicate; +import java.util.function.Supplier; + /** * @author max */ @ExtensionImpl public class ConstructorReferencesSearcher extends QueryExecutorBase implements ReferencesSearchQueryExecutor { @Override - public void processQuery(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull Processor consumer) { - final PsiElement element = p.getElementToSearch(); - if (!(element instanceof PsiMethod)) { + public void processQuery(@Nonnull ReferencesSearch.SearchParameters p, @Nonnull Predicate consumer) { + PsiElement element = p.getElementToSearch(); + if (!(element instanceof PsiMethod method)) { return; } - final PsiMethod method = (PsiMethod)element; - final PsiManager[] manager = new PsiManager[1]; - PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiClass compute() { - if (!method.isConstructor()) { - return null; - } - PsiClass aClass = method.getContainingClass(); - manager[0] = aClass == null ? null : aClass.getManager(); - return aClass; + PsiManager[] manager = new PsiManager[1]; + PsiClass aClass = Application.get().runReadAction((Supplier)() -> { + if (!method.isConstructor()) { + return null; } + PsiClass aClass1 = method.getContainingClass(); + manager[0] = aClass1 == null ? null : aClass1.getManager(); + return aClass1; }); if (manager[0] == null) { return; } - SearchScope scope = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public SearchScope compute() { - return p.getEffectiveSearchScope(); - } - }); + SearchScope scope = Application.get().runReadAction((Supplier)p::getEffectiveSearchScope); new ConstructorReferencesSearchHelper(manager[0]).processConstructorReferences( consumer, method, diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaAllOverridingMethodsSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaAllOverridingMethodsSearcher.java index 948715097..732900f8f 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaAllOverridingMethodsSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaAllOverridingMethodsSearcher.java @@ -24,15 +24,16 @@ import com.intellij.java.language.psi.util.PsiUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ApplicationManager; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; +import consulo.application.Application; import consulo.content.scope.SearchScope; import consulo.util.collection.MultiMap; +import consulo.util.lang.Couple; import consulo.util.lang.Pair; - import jakarta.annotation.Nonnull; +import java.util.function.Predicate; +import java.util.function.Supplier; + /** * @author ven */ @@ -40,77 +41,69 @@ public class JavaAllOverridingMethodsSearcher implements AllOverridingMethodsSearchExecutor { @Override public boolean execute( - @Nonnull final AllOverridingMethodsSearch.SearchParameters p, - @Nonnull final Processor> consumer + @Nonnull AllOverridingMethodsSearch.SearchParameters p, + @Nonnull Predicate> consumer ) { - final PsiClass psiClass = p.getPsiClass(); + PsiClass psiClass = p.getPsiClass(); - final MultiMap methods = - ApplicationManager.getApplication().runReadAction(new Computable>() { - @Override - public MultiMap compute() { - final MultiMap methods = MultiMap.create(); - for (PsiMethod method : psiClass.getMethods()) { - if (PsiUtil.canBeOverriden(method)) { - methods.putValue(method.getName(), method); - } + MultiMap methods = + Application.get().runReadAction((Supplier>)() -> { + MultiMap methods1 = MultiMap.create(); + for (PsiMethod method : psiClass.getMethods()) { + if (PsiUtil.canBeOverriden(method)) { + methods1.putValue(method.getName(), method); } - return methods; } + return methods1; }); - final SearchScope scope = p.getScope(); + SearchScope scope = p.getScope(); + + Predicate inheritorsProcessor = inheritor -> { + PsiSubstitutor substitutor = null; - Processor inheritorsProcessor = new Processor() { - @Override - public boolean process(PsiClass inheritor) { - PsiSubstitutor substitutor = null; + for (String name : methods.keySet()) { + if (inheritor.findMethodsByName(name, true).length == 0) { + continue; + } - for (String name : methods.keySet()) { - if (inheritor.findMethodsByName(name, true).length == 0) { + for (PsiMethod method : methods.get(name)) { + if (method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && !JavaPsiFacade.getInstance(inheritor.getProject()) + .arePackagesTheSame(psiClass, inheritor)) { continue; } - for (PsiMethod method : methods.get(name)) { - if (method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && !JavaPsiFacade.getInstance(inheritor.getProject()) - .arePackagesTheSame(psiClass, inheritor)) { - continue; - } - + if (substitutor == null) { + //could be null if not java inheritor, TODO only JavaClassInheritors are needed + substitutor = TypeConversionUtil.getClassSubstitutor(psiClass, inheritor, PsiSubstitutor.EMPTY); if (substitutor == null) { - //could be null if not java inheritor, TODO only JavaClassInheritors are needed - substitutor = TypeConversionUtil.getClassSubstitutor(psiClass, inheritor, PsiSubstitutor.EMPTY); - if (substitutor == null) { - return true; - } + return true; } + } - MethodSignature signature = method.getSignature(substitutor); - PsiMethod inInheritor = MethodSignatureUtil.findMethodBySuperSignature(inheritor, signature, false); - if (inInheritor != null && !inInheritor.hasModifierProperty(PsiModifier.STATIC)) { - if (!consumer.process(Pair.create(method, inInheritor))) { - return false; - } + MethodSignature signature = method.getSignature(substitutor); + PsiMethod inInheritor = MethodSignatureUtil.findMethodBySuperSignature(inheritor, signature, false); + if (inInheritor != null && !inInheritor.isStatic()) { + if (!consumer.test(Couple.of(method, inInheritor))) { + return false; } + } - if (psiClass.isInterface() && !inheritor.isInterface()) { //check for sibling implementation - final PsiClass superClass = inheritor.getSuperClass(); - if (superClass != null && !superClass.isInheritor(psiClass, true)) { - inInheritor = - MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(inheritor, superClass, signature, true); - if (inInheritor != null && !inInheritor.hasModifierProperty(PsiModifier.STATIC)) { - if (!consumer.process(Pair.create(method, inInheritor))) { - return false; - } - } + if (psiClass.isInterface() && !inheritor.isInterface()) { //check for sibling implementation + PsiClass superClass = inheritor.getSuperClass(); + if (superClass != null && !superClass.isInheritor(psiClass, true)) { + inInheritor = + MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(inheritor, superClass, signature, true); + if (inInheritor != null && !inInheritor.isStatic() && !consumer.test(Couple.of(method, inInheritor))) { + return false; } } } } - - return true; } + + return true; }; return ClassInheritorsSearch.search(psiClass, scope, true).forEach(inheritorsProcessor); diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaClassInheritorsSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaClassInheritorsSearcher.java index 9de9fc7a6..2046382fc 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaClassInheritorsSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaClassInheritorsSearcher.java @@ -21,15 +21,13 @@ import com.intellij.java.indexing.search.searches.DirectClassInheritorsSearch; import com.intellij.java.language.psi.PsiAnonymousClass; import com.intellij.java.language.psi.PsiClass; -import com.intellij.java.language.psi.PsiModifier; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ApplicationManager; +import consulo.application.Application; import consulo.application.progress.ProgressIndicator; import consulo.application.progress.ProgressIndicatorProvider; import consulo.application.progress.ProgressManager; import consulo.application.util.ReadActionProcessor; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.java.language.module.util.JavaClassNames; import consulo.language.impl.psi.PsiAnchor; @@ -41,28 +39,38 @@ import consulo.project.Project; import consulo.project.util.query.QueryExecutorBase; import consulo.util.collection.Stack; -import consulo.util.lang.ref.Ref; - +import consulo.util.lang.ref.SimpleReference; import jakarta.annotation.Nonnull; +import jakarta.inject.Inject; import java.util.HashSet; import java.util.Set; +import java.util.function.Predicate; +import java.util.function.Supplier; @ExtensionImpl public class JavaClassInheritorsSearcher extends QueryExecutorBase implements ClassInheritorsSearchExecutor { private static final Logger LOG = Logger.getInstance(JavaClassInheritorsSearcher.class); + @Nonnull + private final Application myApplication; + + @Inject + public JavaClassInheritorsSearcher(@Nonnull Application application) { + myApplication = application; + } + @Override - public void processQuery(@Nonnull ClassInheritorsSearch.SearchParameters parameters, @Nonnull Processor consumer) { - final PsiClass baseClass = parameters.getClassToProcess(); - final SearchScope searchScope = parameters.getScope(); + public void processQuery(@Nonnull ClassInheritorsSearch.SearchParameters parameters, @Nonnull Predicate consumer) { + PsiClass baseClass = parameters.getClassToProcess(); + SearchScope searchScope = parameters.getScope(); LOG.assertTrue(searchScope != null); ProgressIndicator progress = ProgressIndicatorProvider.getGlobalProgressIndicator(); if (progress != null) { progress.pushState(); - String className = ApplicationManager.getApplication().runReadAction((Computable)() -> baseClass.getName()); + String className = myApplication.runReadAction((Supplier)baseClass::getName); progress.setText( className != null ? PsiBundle.message("psi.search.inheritors.of.class.progress", className) @@ -78,33 +86,32 @@ public void processQuery(@Nonnull ClassInheritorsSearch.SearchParameters paramet } private static void processInheritors( - @Nonnull final Processor consumer, - @Nonnull final PsiClass baseClass, - @Nonnull final SearchScope searchScope, - @Nonnull final ClassInheritorsSearch.SearchParameters parameters + @Nonnull Predicate consumer, + @Nonnull PsiClass baseClass, + @Nonnull SearchScope searchScope, + @Nonnull ClassInheritorsSearch.SearchParameters parameters ) { - if (baseClass instanceof PsiAnonymousClass || isFinal(baseClass)) { + Project project = PsiUtilCore.getProjectInReadAction(baseClass); + Application app = project.getApplication(); + if (baseClass instanceof PsiAnonymousClass || isFinal(app, baseClass)) { return; } - Project project = PsiUtilCore.getProjectInReadAction(baseClass); - if (isJavaLangObject(baseClass)) { - AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(new Processor() { - @Override - public boolean process(final PsiClass aClass) { - ProgressManager.checkCanceled(); - return isJavaLangObject(aClass) || consumer.process(aClass); - } + if (isJavaLangObject(app, baseClass)) { + AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(aClass -> { + ProgressManager.checkCanceled(); + return isJavaLangObject(app, aClass) || consumer.test(aClass); }); return; } - final Ref currentBase = Ref.create(null); - final Stack stack = new Stack(); - final Set processed = new HashSet<>(); + SimpleReference currentBase = SimpleReference.create(null); + Stack stack = new Stack<>(); + Set processed = new HashSet<>(); - final Processor processor = new ReadActionProcessor() { + Predicate processor = new ReadActionProcessor<>() { @Override + @RequiredReadAction public boolean processInReadAction(PsiClass candidate) { ProgressManager.checkCanceled(); @@ -116,44 +123,34 @@ public boolean processInReadAction(PsiClass candidate) { if (PsiSearchScopeUtil.isInScope(searchScope, candidate)) { if (candidate instanceof PsiAnonymousClass) { - return consumer.process(candidate); + return consumer.test(candidate); } - final String name = candidate.getName(); - if (name != null && parameters.getNameCondition().value(name) && !consumer.process(candidate)) { + String name = candidate.getName(); + if (name != null && parameters.getNameCondition().test(name) && !consumer.test(candidate)) { return false; } } - if (parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass) && !isFinal(candidate)) { + if (parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass) && !isFinal(app, candidate)) { stack.push(PsiAnchor.create(candidate)); } return true; } }; - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - stack.push(PsiAnchor.create(baseClass)); - } - }); - final GlobalSearchScope projectScope = GlobalSearchScope.allScope(project); + app.runReadAction(() -> stack.push(PsiAnchor.create(baseClass))); + GlobalSearchScope projectScope = GlobalSearchScope.allScope(project); while (!stack.isEmpty()) { ProgressManager.checkCanceled(); - final PsiAnchor anchor = stack.pop(); + PsiAnchor anchor = stack.pop(); if (!processed.add(anchor)) { continue; } - PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiClass compute() { - return (PsiClass)anchor.retrieve(); - } - }); + PsiClass psiClass = app.runReadAction((Supplier)() -> (PsiClass)anchor.retrieve()); if (psiClass == null) { continue; } @@ -165,22 +162,13 @@ public PsiClass compute() { } } - private static boolean isJavaLangObject(@Nonnull final PsiClass baseClass) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - return baseClass.isValid() && JavaClassNames.JAVA_LANG_OBJECT.equals(baseClass.getQualifiedName()); - } - }); + private static boolean isJavaLangObject(Application application, @Nonnull PsiClass baseClass) { + return application.runReadAction( + (Supplier)() -> baseClass.isValid() && JavaClassNames.JAVA_LANG_OBJECT.equals(baseClass.getQualifiedName()) + ); } - private static boolean isFinal(@Nonnull final PsiClass baseClass) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - return Boolean.valueOf(baseClass.hasModifierProperty(PsiModifier.FINAL)); - } - }).booleanValue(); + private static boolean isFinal(Application application, @Nonnull PsiClass baseClass) { + return application.runReadAction((Supplier)baseClass::isFinal); } - } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaDirectInheritorsSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaDirectInheritorsSearcher.java index fda38a826..8454b6a67 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaDirectInheritorsSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaDirectInheritorsSearcher.java @@ -23,10 +23,8 @@ import com.intellij.java.language.psi.*; import com.intellij.java.language.psi.util.PsiUtil; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ApplicationManager; +import consulo.application.Application; import consulo.application.progress.ProgressManager; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.java.language.module.util.JavaClassNames; import consulo.language.psi.PsiElement; @@ -38,10 +36,11 @@ import consulo.util.lang.Comparing; import consulo.util.lang.StringUtil; import consulo.virtualFileSystem.VirtualFile; - import jakarta.annotation.Nonnull; import java.util.*; +import java.util.function.Predicate; +import java.util.function.Supplier; /** * @author max @@ -50,102 +49,65 @@ public class JavaDirectInheritorsSearcher implements DirectClassInheritorsSearchExecutor { @Override public boolean execute( - @Nonnull final DirectClassInheritorsSearch.SearchParameters p, - @Nonnull final Processor consumer + @Nonnull DirectClassInheritorsSearch.SearchParameters p, + @Nonnull Predicate consumer ) { - final PsiClass aClass = p.getClassToProcess(); - - final SearchScope useScope = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public SearchScope compute() { - return aClass.getUseScope(); - } - }); + PsiClass aClass = p.getClassToProcess(); - final String qualifiedName = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - return aClass.getQualifiedName(); - } - }); + Application app = Application.get(); + SearchScope useScope = app.runReadAction((Supplier)aClass::getUseScope); + String qualifiedName = app.runReadAction((Supplier)aClass::getQualifiedName); - final Project project = PsiUtilCore.getProjectInReadAction(aClass); + Project project = PsiUtilCore.getProjectInReadAction(aClass); if (JavaClassNames.JAVA_LANG_OBJECT.equals(qualifiedName)) { //[pasynkov]: WTF? - //final SearchScope scope = useScope.intersectWith(GlobalSearchScope.notScope(GlobalSearchScope.getScopeRestrictedByFileTypes( + //SearchScope scope = useScope.intersectWith(GlobalSearchScope.notScope(GlobalSearchScope.getScopeRestrictedByFileTypes( // GlobalSearchScope.allScope(psiManager.getProject()), StdFileTypes.JSP, StdFileTypes.JSPX))); - return AllClassesSearch.search(useScope, project).forEach(new Processor() { - @Override - public boolean process(final PsiClass psiClass) { - ProgressManager.checkCanceled(); - if (psiClass.isInterface()) { - return consumer.process(psiClass); - } - final PsiClass superClass = psiClass.getSuperClass(); - if (superClass != null && JavaClassNames.JAVA_LANG_OBJECT.equals(ApplicationManager.getApplication() - .runReadAction(new Computable() { - public String compute() { - return superClass.getQualifiedName(); - } - }))) { - return consumer.process(psiClass); - } - return true; + return AllClassesSearch.search(useScope, project).forEach(psiClass -> { + ProgressManager.checkCanceled(); + if (psiClass.isInterface()) { + return consumer.test(psiClass); } + PsiClass superClass = psiClass.getSuperClass(); + return !(superClass != null + && JavaClassNames.JAVA_LANG_OBJECT.equals(app.runReadAction((Supplier)superClass::getQualifiedName))) + || consumer.test(psiClass); }); } - final GlobalSearchScope scope = - useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : new EverythingGlobalScope(project); - final String searchKey = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - return aClass.getName(); - } - }); + GlobalSearchScope scope = + useScope instanceof GlobalSearchScope globalSearchScope ? globalSearchScope : new EverythingGlobalScope(project); + String searchKey = app.runReadAction((Supplier)aClass::getName); if (StringUtil.isEmpty(searchKey)) { return true; } - Collection candidates = - MethodUsagesSearcher.resolveInReadAction(project, new Computable>() { - @Override - public Collection compute() { - return JavaSuperClassNameOccurenceIndex.getInstance().get(searchKey, project, scope); - } - }); + Collection candidates = MethodUsagesSearcher.resolveInReadAction( + project, + () -> JavaSuperClassNameOccurenceIndex.getInstance().get(searchKey, project, scope) + ); - Map> classes = new HashMap>(); + Map> classes = new HashMap<>(); - for (final PsiReferenceList referenceList : candidates) { + for (PsiReferenceList referenceList : candidates) { ProgressManager.checkCanceled(); - final PsiClass candidate = (PsiClass)ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiElement compute() { - return referenceList.getParent(); - } - }); + PsiClass candidate = (PsiClass)app.runReadAction((Supplier)referenceList::getParent); if (!checkInheritance(p, aClass, candidate, project)) { continue; } - String fqn = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public String compute() { - return candidate.getQualifiedName(); - } - }); + String fqn = app.runReadAction((Supplier)candidate::getQualifiedName); List list = classes.get(fqn); if (list == null) { - list = new ArrayList(); + list = new ArrayList<>(); classes.put(fqn, list); } list.add(candidate); } if (!classes.isEmpty()) { - final VirtualFile jarFile = getArchiveFile(aClass); + VirtualFile jarFile = getArchiveFile(aClass); for (List sameNamedClasses : classes.values()) { ProgressManager.checkCanceled(); if (!processSameNamedClasses(consumer, sameNamedClasses, jarFile)) { @@ -156,12 +118,10 @@ public String compute() { if (p.includeAnonymous()) { Collection anonymousCandidates = - MethodUsagesSearcher.resolveInReadAction(project, new Computable>() { - @Override - public Collection compute() { - return JavaAnonymousClassBaseRefOccurenceIndex.getInstance().get(searchKey, project, scope); - } - }); + MethodUsagesSearcher.resolveInReadAction( + project, + () -> JavaAnonymousClassBaseRefOccurenceIndex.getInstance().get(searchKey, project, scope) + ); for (PsiAnonymousClass candidate : anonymousCandidates) { ProgressManager.checkCanceled(); @@ -169,39 +129,22 @@ public Collection compute() { continue; } - if (!consumer.process(candidate)) { + if (!consumer.test(candidate)) { return false; } } - boolean isEnum = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - return aClass.isEnum(); - } - }); + boolean isEnum = app.runReadAction((Supplier)aClass::isEnum); if (isEnum) { // abstract enum can be subclassed in the body - PsiField[] fields = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiField[] compute() { - return aClass.getFields(); - } - }); - for (final PsiField field : fields) { + PsiField[] fields = app.runReadAction((Supplier)aClass::getFields); + for (PsiField field : fields) { ProgressManager.checkCanceled(); - if (field instanceof PsiEnumConstant) { + if (field instanceof PsiEnumConstant enumConstant) { PsiEnumConstantInitializer initializingClass = - ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiEnumConstantInitializer compute() { - return ((PsiEnumConstant)field).getInitializingClass(); - } - }); - if (initializingClass != null) { - if (!consumer.process(initializingClass)) { - return false; - } + app.runReadAction((Supplier)enumConstant::getInitializingClass); + if (initializingClass != null && !consumer.test(initializingClass)) { + return false; } } } @@ -212,23 +155,18 @@ public PsiEnumConstantInitializer compute() { } private static boolean checkInheritance( - final DirectClassInheritorsSearch.SearchParameters p, - final PsiClass aClass, - final PsiClass candidate, + DirectClassInheritorsSearch.SearchParameters p, + PsiClass aClass, + PsiClass candidate, Project project ) { - return MethodUsagesSearcher.resolveInReadAction(project, new Computable() { - @Override - public Boolean compute() { - return !p.isCheckInheritance() || candidate.isInheritor(aClass, false); - } - }); + return MethodUsagesSearcher.resolveInReadAction(project, () -> !p.isCheckInheritance() || candidate.isInheritor(aClass, false)); } private static boolean processSameNamedClasses( - Processor consumer, + Predicate consumer, List sameNamedClasses, - final VirtualFile jarFile + VirtualFile jarFile ) { // if there is a class from the same jar, prefer it boolean sameJarClassFound = false; @@ -239,7 +177,7 @@ private static boolean processSameNamedClasses( boolean fromSameJar = Comparing.equal(getArchiveFile(sameNamedClass), jarFile); if (fromSameJar) { sameJarClassFound = true; - if (!consumer.process(sameNamedClass)) { + if (!consumer.test(sameNamedClass)) { return false; } } @@ -249,12 +187,7 @@ private static boolean processSameNamedClasses( return sameJarClassFound || ContainerUtil.process(sameNamedClasses, consumer); } - private static VirtualFile getArchiveFile(final PsiClass aClass) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public VirtualFile compute() { - return PsiUtil.getJarFile(aClass); - } - }); + private static VirtualFile getArchiveFile(PsiClass aClass) { + return Application.get().runReadAction((Supplier)() -> PsiUtil.getJarFile(aClass)); } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaFunctionalExpressionSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaFunctionalExpressionSearcher.java index e162cc3b3..d15b8827d 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaFunctionalExpressionSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaFunctionalExpressionSearcher.java @@ -25,12 +25,10 @@ import com.intellij.java.language.psi.util.PsiUtil; import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ApplicationManager; -import consulo.application.ReadAction; +import consulo.application.AccessRule; +import consulo.application.Application; import consulo.application.util.ReadActionProcessor; import consulo.application.util.function.CommonProcessors; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.java.language.module.extension.JavaModuleExtension; import consulo.language.psi.*; @@ -51,12 +49,13 @@ import consulo.project.Project; import consulo.project.util.query.QueryExecutorBase; import consulo.util.collection.ContainerUtil; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import consulo.virtualFileSystem.VirtualFile; - import jakarta.annotation.Nonnull; import java.util.*; +import java.util.function.Predicate; +import java.util.function.Supplier; import static consulo.util.collection.ContainerUtil.addIfNotNull; import static consulo.util.collection.ContainerUtil.process; @@ -78,20 +77,20 @@ private static record ClassLambdaInfo(Project project, GlobalSearchScope scope, public static final int SMART_SEARCH_THRESHOLD = 5; @Override + @RequiredReadAction public void processQuery( @Nonnull FunctionalExpressionSearch.SearchParameters queryParameters, - @Nonnull Processor consumer + @Nonnull Predicate consumer ) { - final PsiClass aClass = queryParameters.getElementToSearch(); + PsiClass aClass = queryParameters.getElementToSearch(); - ClassLambdaInfo classLambdaInfo = ReadAction.compute(() -> - { + ClassLambdaInfo classLambdaInfo = AccessRule.read(() -> { if (!aClass.isValid() || !LambdaUtil.isFunctionalClass(aClass)) { return null; } Project project = aClass.getProject(); - final Set highLevelModules = getJava8Modules(project); + Set highLevelModules = getJava8Modules(project); if (highLevelModules.isEmpty()) { return null; } @@ -99,10 +98,9 @@ public void processQuery( GlobalSearchScope useScope = convertToGlobalScope(project, queryParameters.getEffectiveSearchScope()); - final MethodSignature functionalInterfaceMethod = LambdaUtil.getFunction(aClass); + MethodSignature functionalInterfaceMethod = LambdaUtil.getFunction(aClass); LOG.assertTrue(functionalInterfaceMethod != null); - int expectedFunExprParamsCount = - functionalInterfaceMethod.getParameterTypes().length; + int expectedFunExprParamsCount = functionalInterfaceMethod.getParameterTypes().length; return new ClassLambdaInfo(project, useScope, expectedFunExprParamsCount); }); @@ -110,9 +108,9 @@ public void processQuery( return; } - final Project project = classLambdaInfo.project(); - final GlobalSearchScope useScope = classLambdaInfo.scope(); - final int expectedFunExprParamsCount = classLambdaInfo.expectedFunExprParamsCount(); + Project project = classLambdaInfo.project(); + GlobalSearchScope useScope = classLambdaInfo.scope(); + int expectedFunExprParamsCount = classLambdaInfo.expectedFunExprParamsCount(); //collect all files with '::' and '->' in useScope Set candidateFiles = getFilesWithFunctionalExpressionsScope(project, new JavaSourceFilterScope(useScope)); @@ -121,45 +119,43 @@ public void processQuery( return; } - final GlobalSearchScope candidateScope = GlobalSearchScope.filesScope(project, candidateFiles); + GlobalSearchScope candidateScope = GlobalSearchScope.filesScope(project, candidateFiles); //collect all methods with parameter of functional interface or free type parameter type - final Collection methodCandidates = + Collection methodCandidates = getCandidateMethodsWithSuitableParams(aClass, project, useScope, candidateFiles, candidateScope); - final LinkedHashSet filesToProcess = new LinkedHashSet(); - final FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance(); + LinkedHashSet filesToProcess = new LinkedHashSet<>(); + FileBasedIndex fileBasedIndex = FileBasedIndex.getInstance(); + + Application app = project.getApplication(); //find all usages of method candidates in files with functional expressions - for (final PsiMethod psiMethod : methodCandidates) { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - if (!psiMethod.isValid()) { - return; - } - final int parametersCount = psiMethod.getParameterList().getParametersCount(); - final boolean varArgs = psiMethod.isVarArgs(); - final PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); - final GlobalSearchScope methodUseScope = convertToGlobalScope(project, psiMethod.getUseScope()); - final LinkedHashMap> holders = - new LinkedHashMap>(); - //functional expressions checker: number and type of parameters at call site should correspond to candidate method currently check - final SuitableFilesProcessor processor = - new SuitableFilesProcessor(holders, expectedFunExprParamsCount, parametersCount, varArgs, parameters); - fileBasedIndex.processValues( - JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID, - psiMethod.getName(), - null, - processor, - useScope.intersectWith(methodUseScope) - ); - for (Map.Entry> entry : holders.entrySet()) { - for (JavaFunctionalExpressionIndex.IndexHolder holder : entry.getValue()) { - if (processor.canBeFunctional(holder)) { - filesToProcess.add(entry.getKey()); - break; - } + for (PsiMethod psiMethod : methodCandidates) { + app.runReadAction(() -> { + if (!psiMethod.isValid()) { + return; + } + int parametersCount = psiMethod.getParameterList().getParametersCount(); + boolean varArgs = psiMethod.isVarArgs(); + PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); + GlobalSearchScope methodUseScope = convertToGlobalScope(project, psiMethod.getUseScope()); + LinkedHashMap> holders = new LinkedHashMap<>(); + //functional expressions checker: number and type of parameters at call site should correspond to candidate method currently check + SuitableFilesProcessor processor = + new SuitableFilesProcessor(holders, expectedFunExprParamsCount, parametersCount, varArgs, parameters); + fileBasedIndex.processValues( + JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID, + psiMethod.getName(), + null, + processor, + useScope.intersectWith(methodUseScope) + ); + for (Map.Entry> entry : holders.entrySet()) { + for (JavaFunctionalExpressionIndex.IndexHolder holder : entry.getValue()) { + if (processor.canBeFunctional(holder)) { + filesToProcess.add(entry.getKey()); + break; } } } @@ -175,7 +171,7 @@ public void run() { @Nonnull @RequiredReadAction private static Set getJava8Modules(Project project) { - final Set highLevelModules = new HashSet(); + Set highLevelModules = new HashSet<>(); for (Module module : ModuleManager.getInstance(project).getModules()) { JavaModuleExtension moduleExtension = ModuleUtilCore.getExtension(module, JavaModuleExtension.class); if (moduleExtension != null && moduleExtension.getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_8)) { @@ -186,13 +182,13 @@ private static Set getJava8Modules(Project project) { } private static void searchInFiles( - final PsiClass aClass, - final Processor consumer, + PsiClass aClass, + Predicate consumer, Set filesToProcess, - final int expectedFunExprParamsCount + int expectedFunExprParamsCount ) { LOG.info("#usage files: " + filesToProcess.size()); - process(filesToProcess, new ReadActionProcessor() { + process(filesToProcess, new ReadActionProcessor<>() { @RequiredReadAction @Override public boolean processInReadAction(VirtualFile file) { @@ -202,61 +198,56 @@ public boolean processInReadAction(VirtualFile file) { }); } + @RequiredReadAction private static Collection getCandidateMethodsWithSuitableParams( - final PsiClass aClass, - final Project project, - final GlobalSearchScope useScope, - final Set candidateFiles, - final GlobalSearchScope candidateScope + PsiClass aClass, + Project project, + GlobalSearchScope useScope, + Set candidateFiles, + GlobalSearchScope candidateScope ) { - return ApplicationManager.getApplication().runReadAction(new Computable>() { - @Override - public Collection compute() { - if (!aClass.isValid()) { - return Collections.emptyList(); - } + return Application.get().runReadAction((Supplier>)() -> { + if (!aClass.isValid()) { + return Collections.emptyList(); + } - GlobalSearchScope visibleFromCandidates = combineResolveScopes(project, candidateFiles); + GlobalSearchScope visibleFromCandidates = combineResolveScopes(project, candidateFiles); - final Set usedMethodNames = new HashSet<>(); - FileBasedIndex.getInstance().processAllKeys( - JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID, - new CommonProcessors.CollectProcessor(usedMethodNames), - candidateScope, - null - ); + Set usedMethodNames = new HashSet<>(); + FileBasedIndex.getInstance().processAllKeys( + JavaFunctionalExpressionIndex.JAVA_FUNCTIONAL_EXPRESSION_INDEX_ID, + new CommonProcessors.CollectProcessor<>(usedMethodNames), + candidateScope, + null + ); - final LinkedHashSet methods = new LinkedHashSet<>(); - Processor methodProcessor = new Processor() { - @Override - public boolean process(PsiMethod method) { - if (usedMethodNames.contains(method.getName())) { - methods.add(method); - } - return true; - } - }; - - StubIndexKey key = JavaMethodParameterTypesIndex.getInstance().getKey(); - StubIndex index = StubIndex.getInstance(); - index.processElements( - key, - aClass.getName(), - project, - useScope.intersectWith(visibleFromCandidates), - PsiMethod.class, - methodProcessor - ); - //broken index.processElements(key, JavaMethodElementType.TYPE_PARAMETER_PSEUDO_NAME, project, visibleFromCandidates, PsiMethod.class, methodProcessor); - LOG.info("#methods: " + methods.size()); - return methods; - } + LinkedHashSet methods = new LinkedHashSet<>(); + Predicate methodProcessor = method -> { + if (usedMethodNames.contains(method.getName())) { + methods.add(method); + } + return true; + }; + + StubIndexKey key = JavaMethodParameterTypesIndex.getInstance().getKey(); + StubIndex index = StubIndex.getInstance(); + index.processElements( + key, + aClass.getName(), + project, + useScope.intersectWith(visibleFromCandidates), + PsiMethod.class, + methodProcessor + ); + //broken index.processElements(key, JavaMethodElementType.TYPE_PARAMETER_PSEUDO_NAME, project, visibleFromCandidates, PsiMethod.class, methodProcessor); + LOG.info("#methods: " + methods.size()); + return methods; }); } @Nonnull private static GlobalSearchScope combineResolveScopes(Project project, Set candidateFiles) { - final PsiManager psiManager = PsiManager.getInstance(project); + PsiManager psiManager = PsiManager.getInstance(project); LinkedHashSet resolveScopes = new LinkedHashSet<>(candidateFiles.stream().map(file -> { PsiFile psiFile = file.isValid() ? psiManager.findFile(file) : null; return psiFile == null ? null : psiFile.getResolveScope(); @@ -266,9 +257,9 @@ private static GlobalSearchScope combineResolveScopes(Project project, Set getFilesWithFunctionalExpressionsScope(Project project, GlobalSearchScope useScope) { - final Set files = new LinkedHashSet<>(); - final PsiSearchHelper helper = PsiSearchHelper.getInstance(project); - final CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor(files); + Set files = new LinkedHashSet<>(); + PsiSearchHelper helper = PsiSearchHelper.getInstance(project); + CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor<>(files); helper.processFilesWithText(useScope, UsageSearchContext.IN_CODE, true, "::", processor); helper.processFilesWithText(useScope, UsageSearchContext.IN_CODE, true, "->", processor); return files; @@ -276,19 +267,13 @@ private static Set getFilesWithFunctionalExpressionsScope(Project p @Nonnull private static GlobalSearchScope convertToGlobalScope(Project project, SearchScope useScope) { - final GlobalSearchScope scope; - if (useScope instanceof GlobalSearchScope) { - scope = (GlobalSearchScope)useScope; + GlobalSearchScope scope; + if (useScope instanceof GlobalSearchScope globalSearchScope) { + scope = globalSearchScope; } - else if (useScope instanceof LocalSearchScope) { - final Set files = new HashSet(); - ContainerUtil.addAllNotNull( - files, - ContainerUtil.map( - ((LocalSearchScope)useScope).getScope(), - element -> PsiUtilCore.getVirtualFile(element) - ) - ); + else if (useScope instanceof LocalSearchScope localSearchScope) { + Set files = new HashSet<>(); + ContainerUtil.addAllNotNull(files, ContainerUtil.map(localSearchScope.getScope(), PsiUtilCore::getVirtualFile)); scope = GlobalSearchScope.filesScope(project, files); } else { @@ -316,36 +301,31 @@ else if (useScope instanceof LocalSearchScope) { private static void collectFilesWithTypeOccurrencesAndFieldAssignments( PsiClass aClass, GlobalSearchScope filesScope, - final LinkedHashSet usageFiles + LinkedHashSet usageFiles ) { - final Set fields = new LinkedHashSet(); - for (final PsiReference reference : ReferencesSearch.search(aClass, filesScope)) { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - final PsiElement element = reference.getElement(); - if (element != null) { - addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(element)); - final PsiElement parent = element.getParent(); - if (parent instanceof PsiTypeElement) { - final PsiElement gParent = parent.getParent(); - if (gParent instanceof PsiField && - !((PsiField)gParent).hasModifierProperty(PsiModifier.PRIVATE) && - !((PsiField)gParent).hasModifierProperty(PsiModifier.FINAL)) { - fields.add((PsiField)gParent); - } - } + Set fields = new LinkedHashSet<>(); + Application app = Application.get(); + for (PsiReference reference : ReferencesSearch.search(aClass, filesScope)) { + app.runReadAction(() -> { + PsiElement element = reference.getElement(); + if (element != null) { + addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(element)); + PsiElement parent = element.getParent(); + if (parent instanceof PsiTypeElement && parent.getParent() instanceof PsiField field + && !field.isPrivate() && !field.isFinal()) { + fields.add(field); } } }); } for (PsiField field : fields) { - ReferencesSearch.search(field, filesScope).forEach(new ReadActionProcessor() { + ReferencesSearch.search(field, filesScope).forEach(new ReadActionProcessor<>() { @Override + @RequiredReadAction public boolean processInReadAction(PsiReference fieldRef) { - final PsiElement fieldElement = fieldRef.getElement(); - final PsiAssignmentExpression varElementParent = + PsiElement fieldElement = fieldRef.getElement(); + PsiAssignmentExpression varElementParent = PsiTreeUtil.getParentOfType(fieldElement, PsiAssignmentExpression.class); if (varElementParent != null && PsiTreeUtil.isAncestor(varElementParent.getLExpression(), fieldElement, false)) { addIfNotNull(usageFiles, PsiUtilCore.getVirtualFile(fieldElement)); @@ -356,15 +336,16 @@ public boolean processInReadAction(PsiReference fieldRef) { } } + @RequiredReadAction private static boolean processFileWithFunctionalInterfaces( - final PsiClass aClass, - final int expectedParamCount, - final Processor consumer, + PsiClass aClass, + int expectedParamCount, + Predicate consumer, VirtualFile file ) { - final PsiFile psiFile = aClass.getManager().findFile(file); + PsiFile psiFile = aClass.getManager().findFile(file); if (psiFile != null) { - final Ref ref = new Ref(true); + SimpleReference ref = new SimpleReference<>(true); psiFile.accept(new JavaRecursiveElementWalkingVisitor() { @Override public void visitElement(PsiElement element) { @@ -377,14 +358,14 @@ public void visitElement(PsiElement element) { private void visitFunctionalExpression(PsiFunctionalExpression expression) { PsiType functionalInterfaceType = expression.getFunctionalInterfaceType(); if (InheritanceUtil.isInheritorOrSelf(PsiUtil.resolveClassInType(functionalInterfaceType), aClass, true)) { - if (!consumer.process(expression)) { + if (!consumer.test(expression)) { ref.set(false); } } } @Override - public void visitLambdaExpression(PsiLambdaExpression expression) { + public void visitLambdaExpression(@Nonnull PsiLambdaExpression expression) { super.visitLambdaExpression(expression); if (expression.getParameterList().getParametersCount() == expectedParamCount) { visitFunctionalExpression(expression); @@ -392,7 +373,7 @@ public void visitLambdaExpression(PsiLambdaExpression expression) { } @Override - public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) { + public void visitMethodReferenceExpression(@Nonnull PsiMethodReferenceExpression expression) { super.visitMethodReferenceExpression(expression); visitFunctionalExpression(expression); } @@ -427,12 +408,12 @@ public SuitableFilesProcessor( } @Override - public boolean process(VirtualFile file, Collection holders) { + public boolean process(@Nonnull VirtualFile file, Collection holders) { Set savedHolders = myHolders.get(file); for (JavaFunctionalExpressionIndex.IndexHolder holder : holders) { - final int lambdaParamsNumber = holder.getLambdaParamsNumber(); + int lambdaParamsNumber = holder.getLambdaParamsNumber(); if (lambdaParamsNumber == myExpectedFunExprParamsCount || lambdaParamsNumber == -1) { - final boolean suitableParamNumbers; + boolean suitableParamNumbers; if (myVarArgs) { suitableParamNumbers = holder.getMethodArgsLength() >= myParametersCount - 1; } @@ -441,7 +422,7 @@ public boolean process(VirtualFile file, Collection(); + savedHolders = new LinkedHashSet<>(); myHolders.put(file, savedHolders); } savedHolders.add(holder); @@ -453,12 +434,12 @@ public boolean process(VirtualFile file, Collection= myParametersCount ? myParametersCount - 1 : paramIdx].getType(); - if (paramType instanceof PsiEllipsisType) { - paramType = ((PsiEllipsisType)paramType).getComponentType(); + if (paramType instanceof PsiEllipsisType ellipsisType) { + paramType = ellipsisType.getComponentType(); } - final PsiClass functionalCandidate = PsiUtil.resolveClassInClassTypeOnly(paramType); + PsiClass functionalCandidate = PsiUtil.resolveClassInClassTypeOnly(paramType); return functionalCandidate instanceof PsiTypeParameter || LambdaUtil.isFunctionalClass(functionalCandidate); } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaOverridingMethodsSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaOverridingMethodsSearcher.java index 787b7f0e5..d7e9da28e 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaOverridingMethodsSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaOverridingMethodsSearcher.java @@ -8,6 +8,7 @@ import com.intellij.java.language.psi.util.MethodSignatureUtil; import com.intellij.java.language.psi.util.TypeConversionUtil; import consulo.annotation.component.ExtensionImpl; +import consulo.application.Application; import consulo.application.ApplicationManager; import consulo.application.util.function.Computable; import consulo.application.util.function.Processor; @@ -16,6 +17,9 @@ import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; +import java.util.function.Predicate; +import java.util.function.Supplier; + /** * @author max */ @@ -23,32 +27,17 @@ public class JavaOverridingMethodsSearcher implements OverridingMethodsSearchExecutor { @Override public boolean execute( - @Nonnull final OverridingMethodsSearch.SearchParameters p, - @Nonnull final Processor consumer + @Nonnull OverridingMethodsSearch.SearchParameters p, + @Nonnull Predicate consumer ) { - final PsiMethod method = p.getMethod(); - final SearchScope scope = p.getScope(); + PsiMethod method = p.getMethod(); + SearchScope scope = p.getScope(); - final PsiClass parentClass = ApplicationManager.getApplication().runReadAction(new Computable() { - @Nullable - @Override - public PsiClass compute() { - return method.getContainingClass(); - } - }); + PsiClass parentClass = Application.get().runReadAction((Supplier)method::getContainingClass); assert parentClass != null; - Processor inheritorsProcessor = new Processor() { - @Override - public boolean process(final PsiClass inheritor) { - PsiMethod found = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - @Nullable - public PsiMethod compute() { - return findOverridingMethod(inheritor, method, parentClass); - } - }); - return found == null || consumer.process(found) && p.isCheckDeep(); - } + Predicate inheritorsProcessor = inheritor -> { + PsiMethod found = Application.get().runReadAction((Supplier)() -> findOverridingMethod(inheritor, method, parentClass)); + return found == null || consumer.test(found) && p.isCheckDeep(); }; return ClassInheritorsSearch.search(parentClass, scope, true).forEach(inheritorsProcessor); @@ -69,7 +58,7 @@ public static PsiMethod findOverridingMethod(PsiClass inheritor, PsiMethod metho } if (methodContainingClass.isInterface() && !inheritor.isInterface()) { //check for sibling implementation - final PsiClass superClass = inheritor.getSuperClass(); + PsiClass superClass = inheritor.getSuperClass(); if (superClass != null && !superClass.isInheritor(methodContainingClass, true) && superClass.findMethodsByName(name, true).length > 0) { MethodSignature signature = getSuperSignature(inheritor, methodContainingClass, method); @@ -90,9 +79,8 @@ private static MethodSignature getSuperSignature(PsiClass inheritor, @Nonnull Ps } - private static boolean isAcceptable(final PsiMethod found, final PsiMethod method) { - return !found.hasModifierProperty(PsiModifier.STATIC) && (!method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) || JavaPsiFacade.getInstance( - found.getProject()).arePackagesTheSame(method - .getContainingClass(), found.getContainingClass())); + private static boolean isAcceptable(PsiMethod found, PsiMethod method) { + return !found.isStatic() && (!method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) + || JavaPsiFacade.getInstance(found.getProject()).arePackagesTheSame(method.getContainingClass(), found.getContainingClass())); } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaRecordComponentSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaRecordComponentSearcher.java index 3c2d5ab4e..45531a5ca 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaRecordComponentSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/JavaRecordComponentSearcher.java @@ -4,8 +4,7 @@ import com.intellij.java.language.impl.psi.util.JavaPsiRecordUtil; import com.intellij.java.language.psi.*; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ReadAction; -import consulo.application.util.function.Processor; +import consulo.application.AccessRule; import consulo.content.scope.SearchScope; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiReference; @@ -19,13 +18,15 @@ import jakarta.annotation.Nullable; import java.util.List; +import java.util.function.Predicate; @ExtensionImpl -public final class JavaRecordComponentSearcher extends QueryExecutorBase implements ReferencesSearchQueryExecutor { +public final class JavaRecordComponentSearcher extends QueryExecutorBase + implements ReferencesSearchQueryExecutor { @Override public void processQuery( @Nonnull ReferencesSearch.SearchParameters queryParameters, - @Nonnull Processor consumer + @Nonnull Predicate consumer ) { PsiElement element = queryParameters.getElementToSearch(); if (element instanceof PsiRecordComponent recordComponent) { @@ -35,14 +36,14 @@ public void processQuery( SearchRequestCollector optimizer = queryParameters.getOptimizer(); optimizer.searchWord( info.myName, - ReadAction.compute(() -> info.myLightMethod.getUseScope().intersectWith(scope)), + AccessRule.read(() -> info.myLightMethod.getUseScope().intersectWith(scope)), true, info.myLightMethod ); optimizer.searchWord( info.myName, - ReadAction.compute(() -> info.myLightField.getUseScope().intersectWith(scope)), + AccessRule.read(() -> info.myLightField.getUseScope().intersectWith(scope)), true, info.myLightField ); @@ -51,7 +52,7 @@ public void processQuery( if (parameter != null) { optimizer.searchWord( info.myName, - ReadAction.compute(() -> new LocalSearchScope(parameter.getDeclarationScope())), + AccessRule.read(() -> new LocalSearchScope(parameter.getDeclarationScope())), true, parameter ); @@ -61,7 +62,7 @@ public void processQuery( } private static RecordNavigationInfo findNavigationInfo(PsiRecordComponent recordComponent) { - return ReadAction.compute(() -> { + return AccessRule.read(() -> { String name = recordComponent.getName(); PsiClass containingClass = recordComponent.getContainingClass(); if (containingClass == null) { diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodDeepestSuperSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodDeepestSuperSearcher.java index 93471d6c3..9557bd630 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodDeepestSuperSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodDeepestSuperSearcher.java @@ -18,14 +18,13 @@ import com.intellij.java.language.psi.PsiMethod; import com.intellij.java.language.psi.search.searches.DeepestSuperMethodsSearchExecutor; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ApplicationManager; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; - +import consulo.application.Application; import jakarta.annotation.Nonnull; import java.util.HashSet; import java.util.Set; +import java.util.function.Predicate; +import java.util.function.Supplier; /** * @author peter @@ -33,38 +32,33 @@ @ExtensionImpl public class MethodDeepestSuperSearcher implements DeepestSuperMethodsSearchExecutor { @Override - public boolean execute(@Nonnull PsiMethod method, @Nonnull Processor consumer) { + public boolean execute(@Nonnull PsiMethod method, @Nonnull Predicate consumer) { return processDeepestSuperMethods(method, consumer); } - public static boolean processDeepestSuperMethods(PsiMethod method, Processor consumer) { - final Set methods = new HashSet(); + public static boolean processDeepestSuperMethods(PsiMethod method, Predicate consumer) { + Set methods = new HashSet<>(); methods.add(method); return findDeepestSuperOrSelfSignature(method, methods, null, consumer); } private static boolean findDeepestSuperOrSelfSignature( - final PsiMethod method, + PsiMethod method, Set set, Set guard, - Processor processor + Predicate processor ) { if (guard != null && !guard.add(method)) { return true; } - PsiMethod[] supers = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiMethod[] compute() { - return method.findSuperMethods(); - } - }); + PsiMethod[] supers = Application.get().runReadAction((Supplier)method::findSuperMethods); - if (supers.length == 0 && set.add(method) && !processor.process(method)) { + if (supers.length == 0 && set.add(method) && !processor.test(method)) { return false; } for (PsiMethod superMethod : supers) { if (guard == null) { - guard = new HashSet(); + guard = new HashSet<>(); guard.add(method); } if (!findDeepestSuperOrSelfSignature(superMethod, set, guard, processor)) { diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodSuperSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodSuperSearcher.java index 2ca963b1d..cacdecde2 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodSuperSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodSuperSearcher.java @@ -15,21 +15,23 @@ */ package com.intellij.java.indexing.impl.search; -import com.intellij.java.language.psi.*; +import com.intellij.java.language.psi.HierarchicalMethodSignature; +import com.intellij.java.language.psi.JavaPsiFacade; +import com.intellij.java.language.psi.PsiClass; +import com.intellij.java.language.psi.PsiMethod; import com.intellij.java.language.psi.search.searches.SuperMethodsSearch; import com.intellij.java.language.psi.search.searches.SuperMethodsSearchExecutor; import com.intellij.java.language.psi.util.InheritanceUtil; import com.intellij.java.language.psi.util.MethodSignatureBackedByPsiMethod; import com.intellij.java.language.psi.util.MethodSignatureUtil; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ApplicationManager; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; +import consulo.application.Application; import consulo.logging.Logger; - import jakarta.annotation.Nonnull; import java.util.List; +import java.util.function.Predicate; +import java.util.function.Supplier; /** * @author ven @@ -40,39 +42,35 @@ public class MethodSuperSearcher implements SuperMethodsSearchExecutor { @Override public boolean execute( - @Nonnull final SuperMethodsSearch.SearchParameters queryParameters, - @Nonnull final Processor consumer + @Nonnull SuperMethodsSearch.SearchParameters queryParameters, + @Nonnull Predicate consumer ) { - final PsiClass parentClass = queryParameters.getPsiClass(); - final PsiMethod method = queryParameters.getMethod(); - return ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature(); + PsiClass parentClass = queryParameters.getPsiClass(); + PsiMethod method = queryParameters.getMethod(); + return Application.get().runReadAction((Supplier)() -> { + HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature(); - final boolean checkBases = queryParameters.isCheckBases(); - final boolean allowStaticMethod = queryParameters.isAllowStaticMethod(); - final List supers = signature.getSuperSignatures(); - for (HierarchicalMethodSignature superSignature : supers) { - if (MethodSignatureUtil.isSubsignature(superSignature, signature)) { - if (!addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer)) { - return false; - } - } + boolean checkBases = queryParameters.isCheckBases(); + boolean allowStaticMethod = queryParameters.isAllowStaticMethod(); + List supers = signature.getSuperSignatures(); + for (HierarchicalMethodSignature superSignature : supers) { + if (MethodSignatureUtil.isSubsignature(superSignature, signature) + && !addSuperMethods(superSignature, method, parentClass, allowStaticMethod, checkBases, consumer)) { + return false; } - - return true; } + + return true; }); } private static boolean addSuperMethods( - final HierarchicalMethodSignature signature, - final PsiMethod method, - final PsiClass parentClass, - final boolean allowStaticMethod, - final boolean checkBases, - final Processor consumer + HierarchicalMethodSignature signature, + PsiMethod method, + PsiClass parentClass, + boolean allowStaticMethod, + boolean checkBases, + Predicate consumer ) { PsiMethod signatureMethod = signature.getMethod(); PsiClass hisClass = signatureMethod.getContainingClass(); @@ -82,7 +80,7 @@ private static boolean addSuperMethods( return true; } LOG.assertTrue(signatureMethod != method, method); // method != method.getsuper() - return consumer.process(signature); //no need to check super classes + return consumer.test(signature); //no need to check super classes } } for (HierarchicalMethodSignature superSignature : signature.getSuperSignatures()) { @@ -94,10 +92,9 @@ private static boolean addSuperMethods( return true; } - private static boolean isAcceptable(final PsiMethod superMethod, final PsiMethod method, final boolean allowStaticMethod) { - boolean hisStatic = superMethod.hasModifierProperty(PsiModifier.STATIC); - return hisStatic == method.hasModifierProperty(PsiModifier.STATIC) - && (allowStaticMethod || !hisStatic) + private static boolean isAcceptable(PsiMethod superMethod, PsiMethod method, boolean allowStaticMethod) { + boolean hisStatic = superMethod.isStatic(); + return hisStatic == method.isStatic() && (allowStaticMethod || !hisStatic) && JavaPsiFacade.getInstance(method.getProject()).getResolveHelper().isAccessible(superMethod, method, null); } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodUsagesSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodUsagesSearcher.java index 40459a278..c7d1fe14c 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodUsagesSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/MethodUsagesSearcher.java @@ -17,13 +17,13 @@ import com.intellij.java.indexing.search.searches.MethodReferencesSearch; import com.intellij.java.indexing.search.searches.MethodReferencesSearchExecutor; -import com.intellij.java.language.psi.*; +import com.intellij.java.language.psi.PsiAnnotation; +import com.intellij.java.language.psi.PsiAnonymousClass; +import com.intellij.java.language.psi.PsiClass; +import com.intellij.java.language.psi.PsiMethod; import com.intellij.java.language.psi.util.PsiUtil; import consulo.annotation.component.ExtensionImpl; import consulo.application.Application; -import consulo.application.ApplicationManager; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.language.psi.PsiManager; import consulo.language.psi.PsiReference; @@ -35,59 +35,56 @@ import consulo.project.Project; import consulo.project.util.query.QueryExecutorBase; import consulo.util.lang.StringUtil; - import jakarta.annotation.Nonnull; +import java.util.function.Predicate; +import java.util.function.Supplier; + /** * @author max */ @ExtensionImpl -public class MethodUsagesSearcher extends QueryExecutorBase implements MethodReferencesSearchExecutor { +public class MethodUsagesSearcher extends QueryExecutorBase + implements MethodReferencesSearchExecutor { @Override public void processQuery( - @Nonnull final MethodReferencesSearch.SearchParameters p, - @Nonnull final Processor consumer + @Nonnull MethodReferencesSearch.SearchParameters p, + @Nonnull Predicate consumer ) { - final PsiMethod method = p.getMethod(); - final boolean[] isConstructor = new boolean[1]; - final PsiManager[] psiManager = new PsiManager[1]; - final String[] methodName = new String[1]; - final boolean[] isValueAnnotation = new boolean[1]; - final boolean[] needStrictSignatureSearch = new boolean[1]; - final boolean strictSignatureSearch = p.isStrictSignatureSearch(); - - final PsiClass aClass = resolveInReadAction(p.getProject(), new Computable() { - @Override - public PsiClass compute() { - PsiClass aClass = method.getContainingClass(); - if (aClass == null) { + PsiMethod method = p.getMethod(); + boolean[] isConstructor = new boolean[1]; + PsiManager[] psiManager = new PsiManager[1]; + String[] methodName = new String[1]; + boolean[] isValueAnnotation = new boolean[1]; + boolean[] needStrictSignatureSearch = new boolean[1]; + boolean strictSignatureSearch = p.isStrictSignatureSearch(); + + PsiClass aClass = resolveInReadAction( + p.getProject(), + () -> { + PsiClass aClass1 = method.getContainingClass(); + if (aClass1 == null) { return null; } isConstructor[0] = method.isConstructor(); - psiManager[0] = aClass.getManager(); + psiManager[0] = aClass1.getManager(); methodName[0] = method.getName(); isValueAnnotation[0] = PsiUtil.isAnnotationMethod(method) && PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(methodName[0]) && method.getParameterList().getParametersCount() == 0; needStrictSignatureSearch[0] = strictSignatureSearch - && (aClass instanceof PsiAnonymousClass || aClass.hasModifierProperty(PsiModifier.FINAL) - || method.hasModifierProperty(PsiModifier.STATIC) || method.hasModifierProperty(PsiModifier.FINAL) - || method.hasModifierProperty(PsiModifier.PRIVATE)); - return aClass; + && (aClass1 instanceof PsiAnonymousClass + || aClass1.isFinal() || method.isStatic() || method.isFinal() || method.isPrivate()); + return aClass1; } - }); + ); if (aClass == null) { return; } - final SearchRequestCollector collector = p.getOptimizer(); + SearchRequestCollector collector = p.getOptimizer(); - final SearchScope searchScope = resolveInReadAction(p.getProject(), new Computable() { - @Override - public SearchScope compute() { - return p.getEffectiveSearchScope(); - } - }); + SearchScope searchScope = resolveInReadAction(p.getProject(), p::getEffectiveSearchScope); if (searchScope == GlobalSearchScope.EMPTY_SCOPE) { return; } @@ -106,7 +103,7 @@ public SearchScope compute() { } if (isValueAnnotation[0]) { - Processor refProcessor = + Predicate refProcessor = PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer(consumer); ReferencesSearch.search(aClass, searchScope).forEach(refProcessor); } @@ -120,10 +117,10 @@ public SearchScope compute() { return; } - resolveInReadAction(p.getProject(), new Computable() { - @Override - public Void compute() { - final PsiMethod[] methods = + resolveInReadAction( + p.getProject(), + (Supplier)() -> { + PsiMethod[] methods = strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(methodName[0], false); SearchScope accessScope = methods[0].getUseScope(); for (int i = 1; i < methods.length; i++) { @@ -146,12 +143,12 @@ public Void compute() { SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccessScope, collector); return null; } - }); + ); } - static T resolveInReadAction(@Nonnull Project p, @Nonnull Computable computable) { + static T resolveInReadAction(@Nonnull Project p, @Nonnull Supplier computable) { return Application.get().isReadAccessAllowed() - ? computable.compute() + ? computable.get() : DumbService.getInstance(p).runReadActionInSmartMode(computable); } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/PsiAnnotationMethodReferencesSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/PsiAnnotationMethodReferencesSearcher.java index 0733b329b..759f4f666 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/PsiAnnotationMethodReferencesSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/PsiAnnotationMethodReferencesSearcher.java @@ -5,31 +5,31 @@ import com.intellij.java.language.psi.PsiMethod; import com.intellij.java.language.psi.PsiNameValuePair; import com.intellij.java.language.psi.util.PsiUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ExtensionImpl; import consulo.application.util.ReadActionProcessor; -import consulo.application.util.function.Processor; import consulo.application.util.query.Query; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiReference; import consulo.language.psi.search.ReferencesSearch; import consulo.language.psi.search.ReferencesSearchQueryExecutor; - import jakarta.annotation.Nonnull; +import java.util.function.Predicate; + /** * @author max */ @ExtensionImpl public class PsiAnnotationMethodReferencesSearcher implements ReferencesSearchQueryExecutor { @Override - public boolean execute(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull final Processor consumer) { - final PsiElement refElement = p.getElementToSearch(); + public boolean execute(@Nonnull ReferencesSearch.SearchParameters p, @Nonnull Predicate consumer) { + PsiElement refElement = p.getElementToSearch(); if (PsiUtil.isAnnotationMethod(refElement)) { PsiMethod method = (PsiMethod)refElement; if (PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) && method.getParameterList().getParametersCount() == 0) { - final Query query = - ReferencesSearch.search(method.getContainingClass(), p.getScope(), p.isIgnoreAccessScope()); + Query query = ReferencesSearch.search(method.getContainingClass(), p.getScope(), p.isIgnoreAccessScope()); return query.forEach(createImplicitDefaultAnnotationMethodConsumer(consumer)); } } @@ -38,20 +38,19 @@ public boolean execute(@Nonnull final ReferencesSearch.SearchParameters p, @Nonn } public static ReadActionProcessor createImplicitDefaultAnnotationMethodConsumer( - final Processor consumer + Predicate consumer ) { - return new ReadActionProcessor() { + return new ReadActionProcessor<>() { @Override - public boolean processInReadAction(final PsiReference reference) { - if (reference instanceof PsiJavaCodeReferenceElement) { - PsiJavaCodeReferenceElement javaReference = (PsiJavaCodeReferenceElement)reference; - if (javaReference.getParent() instanceof PsiAnnotation) { - PsiNameValuePair[] members = ((PsiAnnotation)javaReference.getParent()).getParameterList().getAttributes(); - if (members.length == 1 && members[0].getNameIdentifier() == null) { - PsiReference t = members[0].getReference(); - if (t != null && !consumer.process(t)) { - return false; - } + @RequiredReadAction + public boolean processInReadAction(PsiReference reference) { + if (reference instanceof PsiJavaCodeReferenceElement javaReference + && javaReference.getParent() instanceof PsiAnnotation annotation) { + PsiNameValuePair[] members = annotation.getParameterList().getAttributes(); + if (members.length == 1 && members[0].getNameIdentifier() == null) { + PsiReference t = members[0].getReference(); + if (t != null && !consumer.test(t)) { + return false; } } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SPIReferencesSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SPIReferencesSearcher.java index f86a0a258..066242f1b 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SPIReferencesSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SPIReferencesSearcher.java @@ -18,8 +18,8 @@ import com.intellij.java.language.psi.PsiClass; import com.intellij.java.language.psi.util.ClassUtil; import com.intellij.java.language.spi.SPILanguage; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ExtensionImpl; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiFile; @@ -31,9 +31,10 @@ import consulo.language.psi.search.ReferencesSearchQueryExecutor; import consulo.project.Project; import consulo.project.util.query.QueryExecutorBase; - import jakarta.annotation.Nonnull; +import java.util.function.Predicate; + @ExtensionImpl public class SPIReferencesSearcher extends QueryExecutorBase implements ReferencesSearchQueryExecutor { public SPIReferencesSearcher() { @@ -41,47 +42,44 @@ public SPIReferencesSearcher() { } @Override - public void processQuery(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull final Processor consumer) { - final PsiElement element = p.getElementToSearch(); + @RequiredReadAction + public void processQuery(@Nonnull ReferencesSearch.SearchParameters p, @Nonnull Predicate consumer) { + PsiElement element = p.getElementToSearch(); if (!element.isValid()) { return; } - final SearchScope scope = p.getEffectiveSearchScope(); - if (!(scope instanceof GlobalSearchScope)) { + if (!(p.getEffectiveSearchScope() instanceof GlobalSearchScope globalSearchScope)) { return; } - if (element instanceof PsiClass) { - final PsiClass aClass = (PsiClass)element; - final String jvmClassName = ClassUtil.getJVMClassName(aClass); + if (element instanceof PsiClass aClass) { + String jvmClassName = ClassUtil.getJVMClassName(aClass); if (jvmClassName == null) { return; } - final PsiFile[] files = FilenameIndex.getFilesByName(aClass.getProject(), jvmClassName, (GlobalSearchScope)scope); + PsiFile[] files = FilenameIndex.getFilesByName(aClass.getProject(), jvmClassName, globalSearchScope); for (PsiFile file : files) { if (file.getLanguage() == SPILanguage.INSTANCE) { - final PsiReference reference = file.getReference(); + PsiReference reference = file.getReference(); if (reference != null) { - consumer.process(reference); + consumer.test(reference); } } } } - else if (element instanceof PsiPackage) { - final String qualifiedName = ((PsiPackage)element).getQualifiedName(); - final Project project = element.getProject(); - final String[] filenames = FilenameIndex.getAllFilenames(project); - for (final String filename : filenames) { + else if (element instanceof PsiPackage aPackage) { + String qualifiedName = aPackage.getQualifiedName(); + Project project = aPackage.getProject(); + String[] filenames = FilenameIndex.getAllFilenames(project); + for (String filename : filenames) { if (filename.startsWith(qualifiedName + ".")) { - final PsiFile[] files = FilenameIndex.getFilesByName(project, filename, (GlobalSearchScope)scope); - for (PsiFile file : files) { + for (PsiFile file : FilenameIndex.getFilesByName(project, filename, globalSearchScope)) { if (file.getLanguage() == SPILanguage.INSTANCE) { - final PsiReference[] references = file.getReferences(); - for (final PsiReference reference : references) { + for (PsiReference reference : file.getReferences()) { if (reference.getCanonicalText().equals(qualifiedName)) { - consumer.process(reference); + consumer.test(reference); } } } diff --git a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SimpleAccessorReferenceSearcher.java b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SimpleAccessorReferenceSearcher.java index d7d48f53c..261a9f3cb 100644 --- a/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SimpleAccessorReferenceSearcher.java +++ b/java-indexing-impl/src/main/java/com/intellij/java/indexing/impl/search/SimpleAccessorReferenceSearcher.java @@ -18,7 +18,6 @@ import com.intellij.java.language.psi.PsiMethod; import com.intellij.java.language.psi.util.PropertyUtil; import consulo.annotation.component.ExtensionImpl; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiReference; @@ -29,9 +28,10 @@ import consulo.language.psi.search.UsageSearchContext; import consulo.project.util.query.QueryExecutorBase; import consulo.util.lang.StringUtil; - import jakarta.annotation.Nonnull; +import java.util.function.Predicate; + /** * @author ven */ @@ -44,25 +44,22 @@ public SimpleAccessorReferenceSearcher() { @Override public void processQuery( @Nonnull ReferencesSearch.SearchParameters queryParameters, - @Nonnull Processor consumer + @Nonnull Predicate consumer ) { - PsiElement refElement = queryParameters.getElementToSearch(); - if (!(refElement instanceof PsiMethod)) { - return; + if (queryParameters.getElementToSearch() instanceof PsiMethod method) { + addPropertyAccessUsages(method, queryParameters.getEffectiveSearchScope(), queryParameters.getOptimizer()); } - - addPropertyAccessUsages((PsiMethod)refElement, queryParameters.getEffectiveSearchScope(), queryParameters.getOptimizer()); } static void addPropertyAccessUsages(PsiMethod method, SearchScope scope, SearchRequestCollector collector) { - final String propertyName = PropertyUtil.getPropertyName(method); + String propertyName = PropertyUtil.getPropertyName(method); if (StringUtil.isNotEmpty(propertyName)) { SearchScope additional = GlobalSearchScope.EMPTY_SCOPE; for (CustomPropertyScopeProvider provider : CustomPropertyScopeProvider.EP_NAME.getExtensionList()) { additional = additional.union(provider.getScope(method.getProject())); } assert propertyName != null; - final SearchScope propScope = scope.intersectWith(method.getUseScope()).intersectWith(additional); + SearchScope propScope = scope.intersectWith(method.getUseScope()).intersectWith(additional); collector.searchWord(propertyName, propScope, UsageSearchContext.IN_FOREIGN_LANGUAGES, true, method); } } diff --git a/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNameProvider.java b/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNameProvider.java index 97cfa82fc..d7470004a 100644 --- a/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNameProvider.java +++ b/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNameProvider.java @@ -5,22 +5,20 @@ import com.intellij.java.language.psi.PsiMethod; import consulo.annotation.component.ComponentScope; import consulo.annotation.component.ExtensionAPI; -import consulo.application.util.function.Processor; import consulo.language.psi.PsiFile; import consulo.language.psi.scope.GlobalSearchScope; import consulo.language.psi.stub.IdFilter; import consulo.util.collection.ArrayUtil; import consulo.util.collection.ContainerUtil; -import jakarta.annotation.Nullable; -import org.jetbrains.annotations.NonNls; - import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import java.util.HashSet; +import java.util.function.Predicate; /** * @author VISTALL - * @since 09/12/2022 + * @since 2022-12-09 */ @ExtensionAPI(ComponentScope.PROJECT) public interface PsiShortNameProvider { @@ -53,7 +51,7 @@ default String[] getAllFileNames() { * @return the list of found classes. */ @Nonnull - public abstract PsiClass[] getClassesByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); + public abstract PsiClass[] getClassesByName(@Nonnull String name, @Nonnull GlobalSearchScope scope); /** * Returns the list of names of all classes in the project and @@ -64,11 +62,11 @@ default String[] getAllFileNames() { @Nonnull public abstract String[] getAllClassNames(); - default boolean processAllClassNames(Processor processor) { + default boolean processAllClassNames(Predicate processor) { return ContainerUtil.process(getAllClassNames(), processor); } - default boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + default boolean processAllClassNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { return ContainerUtil.process(getAllClassNames(), processor); } @@ -88,32 +86,32 @@ default boolean processAllClassNames(Processor processor, GlobalSearchSc * @return the list of found methods. */ @Nonnull - public abstract PsiMethod[] getMethodsByName(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope); + public abstract PsiMethod[] getMethodsByName(@Nonnull String name, @Nonnull GlobalSearchScope scope); @Nonnull - public abstract PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); + public abstract PsiMethod[] getMethodsByNameIfNotMoreThan(@Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); @Nonnull - public abstract PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); + public abstract PsiField[] getFieldsByNameIfNotMoreThan(@Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); public abstract boolean processMethodsWithName( - @NonNls @Nonnull String name, + @Nonnull String name, @Nonnull GlobalSearchScope scope, - @Nonnull Processor processor + @Nonnull Predicate processor ); public abstract boolean processMethodsWithName( - @NonNls @Nonnull String name, - @Nonnull Processor processor, + @Nonnull String name, + @Nonnull Predicate processor, @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter ); - default boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + default boolean processAllMethodNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { return ContainerUtil.process(getAllFieldNames(), processor); } - default boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + default boolean processAllFieldNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { return ContainerUtil.process(getAllFieldNames(), processor); } @@ -142,7 +140,7 @@ default boolean processAllFieldNames(Processor processor, GlobalSearchSc * @return the list of found fields. */ @Nonnull - public abstract PsiField[] getFieldsByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); + public abstract PsiField[] getFieldsByName(@Nonnull String name, @Nonnull GlobalSearchScope scope); /** * Returns the list of names of all fields in the project and @@ -163,14 +161,14 @@ default boolean processAllFieldNames(Processor processor, GlobalSearchSc public abstract boolean processFieldsWithName( @Nonnull String name, - @Nonnull Processor processor, + @Nonnull Predicate processor, @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter ); public abstract boolean processClassesWithName( @Nonnull String name, - @Nonnull Processor processor, + @Nonnull Predicate processor, @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter ); diff --git a/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNamesCache.java b/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNamesCache.java index f3311f4e6..318cdf17c 100644 --- a/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNamesCache.java +++ b/java-language-api/src/main/java/com/intellij/java/language/psi/search/PsiShortNamesCache.java @@ -20,7 +20,6 @@ import com.intellij.java.language.psi.PsiMethod; import consulo.annotation.component.ComponentScope; import consulo.annotation.component.ServiceAPI; -import consulo.application.util.function.Processor; import consulo.ide.ServiceManager; import consulo.language.psi.PsiFile; import consulo.language.psi.scope.GlobalSearchScope; @@ -28,12 +27,11 @@ import consulo.project.Project; import consulo.util.collection.ArrayUtil; import consulo.util.collection.ContainerUtil; -import org.jetbrains.annotations.NonNls; - import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; import java.util.HashSet; +import java.util.function.Predicate; /** * Allows to retrieve files and Java classes, methods and fields in a project by @@ -81,7 +79,7 @@ public String[] getAllFileNames() { * @return the list of found classes. */ @Nonnull - public abstract PsiClass[] getClassesByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); + public abstract PsiClass[] getClassesByName(@Nonnull String name, @Nonnull GlobalSearchScope scope); /** * Returns the list of names of all classes in the project and @@ -92,11 +90,11 @@ public String[] getAllFileNames() { @Nonnull public abstract String[] getAllClassNames(); - public boolean processAllClassNames(Processor processor) { + public boolean processAllClassNames(Predicate processor) { return ContainerUtil.process(getAllClassNames(), processor); } - public boolean processAllClassNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + public boolean processAllClassNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { return ContainerUtil.process(getAllClassNames(), processor); } @@ -116,29 +114,32 @@ public boolean processAllClassNames(Processor processor, GlobalSearchSco * @return the list of found methods. */ @Nonnull - public abstract PsiMethod[] getMethodsByName(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope); + public abstract PsiMethod[] getMethodsByName(@Nonnull String name, @Nonnull GlobalSearchScope scope); @Nonnull - public abstract PsiMethod[] getMethodsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); + public abstract PsiMethod[] getMethodsByNameIfNotMoreThan(@Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); @Nonnull - public abstract PsiField[] getFieldsByNameIfNotMoreThan(@NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); + public abstract PsiField[] getFieldsByNameIfNotMoreThan(@Nonnull String name, @Nonnull GlobalSearchScope scope, int maxCount); public abstract boolean processMethodsWithName( - @NonNls @Nonnull String name, @Nonnull GlobalSearchScope scope, - @Nonnull Processor processor + @Nonnull String name, + @Nonnull GlobalSearchScope scope, + @Nonnull Predicate processor ); public abstract boolean processMethodsWithName( - @NonNls @Nonnull String name, @Nonnull Processor processor, - @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter + @Nonnull String name, + @Nonnull Predicate processor, + @Nonnull GlobalSearchScope scope, + @Nullable IdFilter filter ); - public boolean processAllMethodNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + public boolean processAllMethodNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { return ContainerUtil.process(getAllFieldNames(), processor); } - public boolean processAllFieldNames(Processor processor, GlobalSearchScope scope, IdFilter filter) { + public boolean processAllFieldNames(Predicate processor, GlobalSearchScope scope, IdFilter filter) { return ContainerUtil.process(getAllFieldNames(), processor); } @@ -167,7 +168,7 @@ public boolean processAllFieldNames(Processor processor, GlobalSearchSco * @return the list of found fields. */ @Nonnull - public abstract PsiField[] getFieldsByName(@Nonnull @NonNls String name, @Nonnull GlobalSearchScope scope); + public abstract PsiField[] getFieldsByName(@Nonnull String name, @Nonnull GlobalSearchScope scope); /** * Returns the list of names of all fields in the project and @@ -187,12 +188,16 @@ public boolean processAllFieldNames(Processor processor, GlobalSearchSco public abstract void getAllFieldNames(@Nonnull HashSet set); public abstract boolean processFieldsWithName( - @Nonnull String name, @Nonnull Processor processor, - @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter + @Nonnull String name, + @Nonnull Predicate processor, + @Nonnull GlobalSearchScope scope, + @Nullable IdFilter filter ); public abstract boolean processClassesWithName( - @Nonnull String name, @Nonnull Processor processor, - @Nonnull GlobalSearchScope scope, @Nullable IdFilter filter + @Nonnull String name, + @Nonnull Predicate processor, + @Nonnull GlobalSearchScope scope, + @Nullable IdFilter filter ); } diff --git a/java-language-api/src/main/java/com/intellij/java/language/psi/search/searches/DeepestSuperMethodsSearchExecutor.java b/java-language-api/src/main/java/com/intellij/java/language/psi/search/searches/DeepestSuperMethodsSearchExecutor.java index 9c2e41203..3dd790acb 100644 --- a/java-language-api/src/main/java/com/intellij/java/language/psi/search/searches/DeepestSuperMethodsSearchExecutor.java +++ b/java-language-api/src/main/java/com/intellij/java/language/psi/search/searches/DeepestSuperMethodsSearchExecutor.java @@ -7,7 +7,7 @@ /** * @author VISTALL - * @since 01-Sep-22 + * @since 2022-09-01 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface DeepestSuperMethodsSearchExecutor extends QueryExecutor { diff --git a/java-language-api/src/main/java/com/intellij/java/language/psi/search/searches/SuperMethodsSearchExecutor.java b/java-language-api/src/main/java/com/intellij/java/language/psi/search/searches/SuperMethodsSearchExecutor.java index 2f0d1ef42..d15fa478e 100644 --- a/java-language-api/src/main/java/com/intellij/java/language/psi/search/searches/SuperMethodsSearchExecutor.java +++ b/java-language-api/src/main/java/com/intellij/java/language/psi/search/searches/SuperMethodsSearchExecutor.java @@ -7,7 +7,7 @@ /** * @author VISTALL - * @since 01-Sep-22 + * @since 2022-09-01 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface SuperMethodsSearchExecutor extends QueryExecutor { diff --git a/plugin/src/main/java/com/intellij/java/impl/analysis/AnalysisScopeRule.java b/plugin/src/main/java/com/intellij/java/impl/analysis/AnalysisScopeRule.java index 0613987a0..fa0cd09b0 100644 --- a/plugin/src/main/java/com/intellij/java/impl/analysis/AnalysisScopeRule.java +++ b/plugin/src/main/java/com/intellij/java/impl/analysis/AnalysisScopeRule.java @@ -25,7 +25,6 @@ import consulo.annotation.component.ExtensionImpl; import consulo.dataContext.DataProvider; import consulo.dataContext.GetDataRule; -import consulo.ide.impl.idea.analysis.AnalysisScopeUtil; import consulo.language.editor.scope.AnalysisScope; import consulo.language.psi.PsiDirectory; import consulo.language.psi.PsiElement; @@ -41,12 +40,12 @@ public class AnalysisScopeRule implements GetDataRule { @Nonnull @Override public Key getKey() { - return AnalysisScopeUtil.KEY; + return AnalysisScope.KEY; } @Override - public AnalysisScope getData(@Nonnull final DataProvider dataProvider) { - final Object psiFile = dataProvider.getDataUnchecked(PsiFile.KEY); + public AnalysisScope getData(@Nonnull DataProvider dataProvider) { + Object psiFile = dataProvider.getDataUnchecked(PsiFile.KEY); if (psiFile instanceof PsiJavaFile javaFile) { return new JavaAnalysisScope(javaFile); } diff --git a/plugin/src/main/java/com/intellij/java/impl/analysis/BaseClassesAnalysisAction.java b/plugin/src/main/java/com/intellij/java/impl/analysis/BaseClassesAnalysisAction.java index 6682cec2a..7605876f3 100644 --- a/plugin/src/main/java/com/intellij/java/impl/analysis/BaseClassesAnalysisAction.java +++ b/plugin/src/main/java/com/intellij/java/impl/analysis/BaseClassesAnalysisAction.java @@ -21,14 +21,14 @@ import consulo.application.progress.Task; import consulo.compiler.CompilerManager; import consulo.document.FileDocumentManager; -import consulo.ide.impl.idea.analysis.BaseAnalysisAction; +import consulo.language.editor.impl.action.BaseAnalysisAction; import consulo.language.editor.scope.AnalysisScope; import consulo.language.editor.scope.localize.AnalysisScopeLocalize; +import consulo.localize.LocalizeValue; import consulo.project.Project; import consulo.ui.ex.awt.Messages; import consulo.ui.ex.awt.UIUtil; import jakarta.annotation.Nonnull; -import jakarta.annotation.Nullable; /** * @author mike @@ -38,25 +38,25 @@ protected BaseClassesAnalysisAction(String title, String analysisNoon) { super(title, analysisNoon); } - protected abstract void analyzeClasses(final Project project, final AnalysisScope scope, ProgressIndicator indicator); + protected abstract void analyzeClasses(Project project, AnalysisScope scope, ProgressIndicator indicator); @Override - protected void analyze(@Nonnull final Project project, @Nonnull final AnalysisScope scope) { + protected void analyze(@Nonnull Project project, @Nonnull AnalysisScope scope) { FileDocumentManager.getInstance().saveAllDocuments(); - ProgressManager.getInstance().run(new Task.Backgroundable(project, AnalysisScopeLocalize.analyzingProject().get(), true) { + ProgressManager.getInstance().run(new Task.Backgroundable(project, AnalysisScopeLocalize.analyzingProject(), true) { @RequiredReadAction @Override - public void run(@Nonnull final ProgressIndicator indicator) { + public void run(@Nonnull ProgressIndicator indicator) { indicator.setIndeterminate(true); indicator.setTextValue(AnalysisScopeLocalize.checkingClassFiles()); - final CompilerManager compilerManager = CompilerManager.getInstance((Project)getProject()); - final boolean upToDate = compilerManager.isUpToDate(compilerManager.createProjectCompileScope()); + CompilerManager compilerManager = CompilerManager.getInstance((Project)getProject()); + boolean upToDate = compilerManager.isUpToDate(compilerManager.createProjectCompileScope()); project.getApplication().invokeLater(() -> { if (!upToDate) { - final int i = Messages.showYesNoCancelDialog( + int i = Messages.showYesNoCancelDialog( (Project)getProject(), AnalysisScopeLocalize.recompileConfirmationMessage().get(), AnalysisScopeLocalize.projectIsOutOfDate().get(), @@ -82,24 +82,28 @@ public void run(@Nonnull final ProgressIndicator indicator) { }); } - private void doAnalyze(final Project project, final AnalysisScope scope) { - ProgressManager.getInstance().run(new Task.Backgroundable(project, AnalysisScopeLocalize.analyzingProject().get(), true) { + private void doAnalyze(Project project, AnalysisScope scope) { + ProgressManager.getInstance().run(new Task.Backgroundable(project, AnalysisScopeLocalize.analyzingProject(), true) { + @Nonnull @Override - @Nullable public NotificationInfo getNotificationInfo() { - return new NotificationInfo("Analysis", "\"" + getTitle() + "\" Analysis Finished", ""); + return new NotificationInfo( + LocalizeValue.localizeTODO("Analysis"), + LocalizeValue.localizeTODO("\"" + getTitle() + "\" Analysis Finished"), + LocalizeValue.empty() + ); } @Override - public void run(@Nonnull final ProgressIndicator indicator) { + public void run(@Nonnull ProgressIndicator indicator) { analyzeClasses(project, scope, indicator); } }); } @RequiredReadAction - private void compileAndAnalyze(final Project project, final AnalysisScope scope) { - final CompilerManager compilerManager = CompilerManager.getInstance(project); + private void compileAndAnalyze(Project project, AnalysisScope scope) { + CompilerManager compilerManager = CompilerManager.getInstance(project); compilerManager.make(compilerManager.createProjectCompileScope(), (aborted, errors, warnings, compileContext) -> { if (aborted || errors != 0) { return; diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInspection/inferNullity/InferNullityAnnotationsAction.java b/plugin/src/main/java/com/intellij/java/impl/codeInspection/inferNullity/InferNullityAnnotationsAction.java index 30e7944b0..374713cae 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInspection/inferNullity/InferNullityAnnotationsAction.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInspection/inferNullity/InferNullityAnnotationsAction.java @@ -28,17 +28,15 @@ import consulo.application.Result; import consulo.application.progress.ProgressIndicator; import consulo.application.progress.ProgressManager; -import consulo.application.util.function.Computable; -import consulo.application.util.function.Processor; import consulo.content.library.Library; import consulo.document.Document; -import consulo.ide.impl.idea.analysis.BaseAnalysisAction; import consulo.ide.impl.idea.ide.util.PropertiesComponent; import consulo.ide.impl.idea.openapi.project.ProjectUtil; import consulo.ide.impl.idea.openapi.roots.libraries.LibraryUtil; import consulo.ide.impl.idea.util.SequentialModalProgressTask; import consulo.language.editor.FileModificationService; import consulo.language.editor.WriteCommandAction; +import consulo.language.editor.impl.action.BaseAnalysisAction; import consulo.language.editor.refactoring.localize.RefactoringLocalize; import consulo.language.editor.scope.AnalysisScope; import consulo.language.editor.scope.localize.AnalysisScopeLocalize; @@ -63,13 +61,14 @@ import consulo.util.collection.ContainerUtil; import consulo.util.lang.ObjectUtil; import consulo.util.lang.StringUtil; -import consulo.util.lang.ref.Ref; +import consulo.util.lang.ref.SimpleReference; import consulo.virtualFileSystem.VirtualFile; import jakarta.annotation.Nonnull; import jakarta.annotation.Nullable; import org.jetbrains.annotations.NonNls; import java.util.*; +import java.util.function.Predicate; import java.util.function.Supplier; @ActionImpl(id = "InferNullity", parents = @@ -86,27 +85,27 @@ public InferNullityAnnotationsAction() { @Override @RequiredUIAccess - protected void analyze(@Nonnull final Project project, @Nonnull final AnalysisScope scope) { + protected void analyze(@Nonnull Project project, @Nonnull AnalysisScope scope) { boolean annotateLocaVars = myAnnotateLocalVariablesCb.getValueOrError(); PropertiesComponent.getInstance().setValue(ANNOTATE_LOCAL_VARIABLES, annotateLocaVars); myAnnotateLocalVariablesCb = null; - final ProgressManager progressManager = ProgressManager.getInstance(); - final Set modulesWithoutAnnotations = new HashSet<>(); - final Set modulesWithLL = new HashSet<>(); - final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); - final String defaultNullable = NullableNotNullManager.getInstance(project).getDefaultNullable(); - final int[] fileCount = new int[]{0}; + ProgressManager progressManager = ProgressManager.getInstance(); + Set modulesWithoutAnnotations = new HashSet<>(); + Set modulesWithLL = new HashSet<>(); + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); + String defaultNullable = NullableNotNullManager.getInstance(project).getDefaultNullable(); + int[] fileCount = new int[]{0}; if (!progressManager.runProcessWithProgressSynchronously(() -> scope.accept(new PsiElementVisitor() { - final private Set processed = new HashSet<>(); + private Set processed = new HashSet<>(); @Override @RequiredReadAction public void visitFile(PsiFile file) { fileCount[0]++; - final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); if (progressIndicator != null) { - final VirtualFile virtualFile = file.getVirtualFile(); + VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile != null) { progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project)); } @@ -115,7 +114,7 @@ public void visitFile(PsiFile file) { if (!(file instanceof PsiJavaFile)) { return; } - final Module module = file.getModule(); + Module module = file.getModule(); if (module != null && processed.add(module)) { if (PsiUtil.getLanguageLevel(file).compareTo(LanguageLevel.JDK_1_5) < 0) { modulesWithLL.add(module); @@ -146,7 +145,7 @@ else if (javaPsiFacade.findClass( return; } PsiDocumentManager.getInstance(project).commitAllDocuments(); - final UsageInfo[] usageInfos = findUsages(annotateLocaVars, project, scope, fileCount[0]); + UsageInfo[] usageInfos = findUsages(annotateLocaVars, project, scope, fileCount[0]); if (usageInfos == null) { return; } @@ -170,12 +169,12 @@ protected void processUsages( @RequiredUIAccess public static boolean addAnnotationsDependency( - @Nonnull final Project project, - @Nonnull final Set modulesWithoutAnnotations, + @Nonnull Project project, + @Nonnull Set modulesWithoutAnnotations, @Nonnull String annoFQN, - final String title + String title ) { - final Library annotationsLib = LibraryUtil.findLibraryByClass(annoFQN, project); + Library annotationsLib = LibraryUtil.findLibraryByClass(annoFQN, project); if (annotationsLib != null) { @NonNls String message = "Module" + (modulesWithoutAnnotations.size() == 1 ? " " : "s "); @@ -211,25 +210,25 @@ public static boolean addAnnotationsDependency( @Nullable protected UsageInfo[] findUsages( boolean annotateLocaVars, - @Nonnull final Project project, - @Nonnull final AnalysisScope scope, - final int fileCount + @Nonnull Project project, + @Nonnull AnalysisScope scope, + int fileCount ) { - final NullityInferrer inferrer = new NullityInferrer(annotateLocaVars, project); - final PsiManager psiManager = PsiManager.getInstance(project); - final Runnable searchForUsages = () -> scope.accept(new PsiElementVisitor() { + NullityInferrer inferrer = new NullityInferrer(annotateLocaVars, project); + PsiManager psiManager = PsiManager.getInstance(project); + Runnable searchForUsages = () -> scope.accept(new PsiElementVisitor() { int myFileCount; @Override - public void visitFile(final PsiFile file) { + public void visitFile(PsiFile file) { myFileCount++; - final VirtualFile virtualFile = file.getVirtualFile(); - final FileViewProvider viewProvider = psiManager.findViewProvider(virtualFile); - final Document document = viewProvider == null ? null : viewProvider.getDocument(); + VirtualFile virtualFile = file.getVirtualFile(); + FileViewProvider viewProvider = psiManager.findViewProvider(virtualFile); + Document document = viewProvider == null ? null : viewProvider.getDocument(); if (document == null || virtualFile.getFileType().isBinary()) { return; //do not inspect binary files } - final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); + ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); if (progressIndicator != null) { progressIndicator.setText2(ProjectUtil.calcRelativeToProjectPath(virtualFile, project)); progressIndicator.setFraction(((double)myFileCount) / fileCount); @@ -249,25 +248,24 @@ public void visitFile(final PsiFile file) { searchForUsages.run(); } - final List usages = new ArrayList<>(); + List usages = new ArrayList<>(); inferrer.collect(usages); return usages.toArray(new UsageInfo[usages.size()]); } - private static Runnable applyRunnable(final Project project, final Computable computable) { - return () -> - { - final LocalHistoryAction action = LocalHistory.getInstance().startAction(INFER_NULLITY_ANNOTATIONS); + private static Runnable applyRunnable(Project project, Supplier computable) { + return () -> { + LocalHistoryAction action = LocalHistory.getInstance().startAction(INFER_NULLITY_ANNOTATIONS); try { new WriteCommandAction(project, INFER_NULLITY_ANNOTATIONS) { @Override protected void run(@Nonnull Result result) throws Throwable { - final UsageInfo[] infos = computable.compute(); + UsageInfo[] infos = computable.get(); if (infos.length > 0) { - final Set elements = new LinkedHashSet<>(); + Set elements = new LinkedHashSet<>(); for (UsageInfo info : infos) { - final PsiElement element = info.getElement(); + PsiElement element = info.getElement(); if (element != null) { ContainerUtil.addIfNotNull(elements, element.getContainingFile()); } @@ -276,7 +274,7 @@ protected void run(@Nonnull Result result) throws Throwable { return; } - final SequentialModalProgressTask progressTask = + SequentialModalProgressTask progressTask = new SequentialModalProgressTask(project, INFER_NULLITY_ANNOTATIONS, false); progressTask.setMinIterationTime(200); progressTask.setTask(new AnnotateTask(project, progressTask, infos)); @@ -295,7 +293,7 @@ protected void run(@Nonnull Result result) throws Throwable { } @RequiredUIAccess - protected void restartAnalysis(final Project project, final AnalysisScope scope) { + protected void restartAnalysis(Project project, AnalysisScope scope) { DumbService.getInstance(project).smartInvokeLater(() -> { if (DumbService.isDumb(project)) { restartAnalysis(project, scope); @@ -309,11 +307,11 @@ protected void restartAnalysis(final Project project, final AnalysisScope scope) private void showUsageView( boolean annotateLocaVars, @Nonnull Project project, - final UsageInfo[] usageInfos, + UsageInfo[] usageInfos, @Nonnull AnalysisScope scope ) { - final UsageTarget[] targets = UsageTarget.EMPTY_ARRAY; - final Ref convertUsagesRef = new Ref<>(); + UsageTarget[] targets = UsageTarget.EMPTY_ARRAY; + SimpleReference convertUsagesRef = new SimpleReference<>(); if (!ProgressManager.getInstance().runProcessWithProgressSynchronously( () -> project.getApplication().runReadAction(() -> convertUsagesRef.set(UsageInfo2UsageAdapter.convert(usageInfos))), "Preprocess Usages", @@ -326,20 +324,20 @@ private void showUsageView( if (convertUsagesRef.isNull()) { return; } - final Usage[] usages = convertUsagesRef.get(); + Usage[] usages = convertUsagesRef.get(); - final UsageViewPresentation presentation = new UsageViewPresentation(); + UsageViewPresentation presentation = new UsageViewPresentation(); presentation.setTabText("Infer Nullity Preview"); presentation.setShowReadOnlyStatusAsRed(true); presentation.setShowCancelButton(true); presentation.setUsagesString(RefactoringLocalize.usageviewUsagestext().get()); - final UsageView usageView = + UsageView usageView = UsageViewManager.getInstance(project).showUsages(targets, usages, presentation, rerunFactory(annotateLocaVars, project, scope)); - final Runnable refactoringRunnable = applyRunnable(project, () -> + Runnable refactoringRunnable = applyRunnable(project, () -> { - final Set infos = UsageViewUtil.getNotExcludedUsageInfos(usageView); + Set infos = UsageViewUtil.getNotExcludedUsageInfos(usageView); return infos.toArray(new UsageInfo[infos.size()]); }); @@ -358,8 +356,8 @@ private void showUsageView( @Nonnull private Supplier rerunFactory( boolean annotateLocaVars, - @Nonnull final Project project, - @Nonnull final AnalysisScope scope + @Nonnull Project project, + @Nonnull AnalysisScope scope ) { return () -> new UsageInfoSearcherAdapter() { @Nonnull @@ -372,7 +370,7 @@ protected UsageInfo[] findUsages() { } @Override - public void generate(@Nonnull Processor processor) { + public void generate(@Nonnull Predicate processor) { processUsages(processor, project); } }; diff --git a/plugin/src/main/java/com/intellij/java/impl/codeInspection/nullable/NullableStuffInspection.java b/plugin/src/main/java/com/intellij/java/impl/codeInspection/nullable/NullableStuffInspection.java index 87f01e701..67530a713 100644 --- a/plugin/src/main/java/com/intellij/java/impl/codeInspection/nullable/NullableStuffInspection.java +++ b/plugin/src/main/java/com/intellij/java/impl/codeInspection/nullable/NullableStuffInspection.java @@ -19,8 +19,9 @@ import com.intellij.java.analysis.impl.psi.impl.search.JavaNullMethodArgumentUtil; import com.intellij.java.language.psi.PsiMethod; import com.intellij.java.language.psi.PsiParameter; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ExtensionImpl; -import consulo.application.ReadAction; +import consulo.application.AccessRule; import consulo.ide.impl.find.PsiElement2UsageTargetAdapter; import consulo.java.analysis.impl.localize.JavaInspectionsLocalize; import consulo.language.editor.inspection.LocalQuickFix; @@ -66,6 +67,7 @@ public String getFamilyName() { } @Override + @RequiredReadAction public void invoke( @Nonnull Project project, @Nonnull PsiFile file, @@ -73,11 +75,11 @@ public void invoke( @Nonnull PsiElement endElement ) { PsiParameter p = (PsiParameter)startElement; - final PsiMethod method = PsiTreeUtil.getParentOfType(p, PsiMethod.class); + PsiMethod method = PsiTreeUtil.getParentOfType(p, PsiMethod.class); if (method == null) { return; } - final int parameterIdx = ArrayUtil.find(method.getParameterList().getParameters(), p); + int parameterIdx = ArrayUtil.find(method.getParameterList().getParameters(), p); if (parameterIdx < 0) { return; } @@ -89,10 +91,10 @@ public void invoke( presentation.setTabText(title); UsageViewManager.getInstance(project).searchAndShowUsages( new UsageTarget[]{new PsiElement2UsageTargetAdapter(method.getParameterList().getParameters()[parameterIdx])}, - () -> processor -> ReadAction.run(() -> JavaNullMethodArgumentUtil.searchNullArgument( + () -> processor -> AccessRule.read(() -> JavaNullMethodArgumentUtil.searchNullArgument( method, parameterIdx, - (arg) -> processor.process(new UsageInfo2UsageAdapter(new UsageInfo(arg))) + (arg) -> processor.test(new UsageInfo2UsageAdapter(new UsageInfo(arg))) )), false, false, diff --git a/plugin/src/main/java/com/intellij/java/impl/find/findUsages/JavaFindUsagesHandler.java b/plugin/src/main/java/com/intellij/java/impl/find/findUsages/JavaFindUsagesHandler.java index e48f979c3..8a5176b7a 100644 --- a/plugin/src/main/java/com/intellij/java/impl/find/findUsages/JavaFindUsagesHandler.java +++ b/plugin/src/main/java/com/intellij/java/impl/find/findUsages/JavaFindUsagesHandler.java @@ -26,13 +26,11 @@ import com.intellij.java.language.psi.codeStyle.VariableKind; import com.intellij.java.language.psi.util.PropertyUtil; import com.intellij.java.language.psi.util.PsiUtil; -import consulo.annotation.access.RequiredReadAction; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.dataContext.DataContext; -import consulo.find.FindBundle; import consulo.find.FindUsagesHandler; import consulo.find.FindUsagesOptions; +import consulo.find.localize.FindLocalize; import consulo.find.ui.AbstractFindUsagesDialog; import consulo.language.editor.refactoring.util.NonCodeSearchDescriptionLocation; import consulo.language.psi.PsiElement; @@ -41,6 +39,7 @@ import consulo.language.psi.PsiUtilCore; import consulo.logging.Logger; import consulo.platform.base.localize.CommonLocalize; +import consulo.ui.annotation.RequiredUIAccess; import consulo.ui.ex.awt.Messages; import consulo.ui.ex.awt.UIUtil; import consulo.usage.UsageInfo; @@ -49,6 +48,7 @@ import jakarta.annotation.Nullable; import java.util.*; +import java.util.function.Predicate; /** * @author peter @@ -104,14 +104,15 @@ public AbstractFindUsagesDialog getFindUsagesDialog( return super.getFindUsagesDialog(isSingleFile, toShowInNewTab, mustOpenInNewTab); } + @RequiredUIAccess private static boolean askWhetherShouldSearchForParameterInOverridingMethods( @Nonnull PsiElement psiElement, @Nonnull PsiParameter parameter ) { return Messages.showOkCancelDialog( psiElement.getProject(), - FindBundle.message("find.parameter.usages.in.overriding.methods.prompt", parameter.getName()), - FindBundle.message("find.parameter.usages.in.overriding.methods.title"), + FindLocalize.findParameterUsagesInOverridingMethodsPrompt(parameter.getName()).get(), + FindLocalize.findParameterUsagesInOverridingMethodsTitle().get(), CommonLocalize.buttonYes().get(), CommonLocalize.buttonNo().get(), UIUtil.getQuestionIcon() @@ -125,7 +126,7 @@ private static PsiElement[] getParameterElementsToSearch( ) { PsiMethod[] overrides = OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY); for (int i = 0; i < overrides.length; i++) { - final PsiElement navigationElement = overrides[i].getNavigationElement(); + PsiElement navigationElement = overrides[i].getNavigationElement(); if (navigationElement instanceof PsiMethod psiMethod) { overrides[i] = psiMethod; } @@ -134,7 +135,7 @@ private static PsiElement[] getParameterElementsToSearch( elementsToSearch.add(parameter); int idx = method.getParameterList().getParameterIndex(parameter); for (PsiMethod override : overrides) { - final PsiParameter[] parameters = override.getParameterList().getParameters(); + PsiParameter[] parameters = override.getParameterList().getParameters(); if (idx < parameters.length) { elementsToSearch.add(parameters[idx]); } @@ -143,22 +144,20 @@ private static PsiElement[] getParameterElementsToSearch( } - @Override @Nonnull + @Override + @RequiredUIAccess public PsiElement[] getPrimaryElements() { - final PsiElement element = getPsiElement(); - if (element instanceof PsiParameter parameter) { - final PsiElement scope = parameter.getDeclarationScope(); - if (scope instanceof PsiMethod method) { - if (PsiUtil.canBeOverriden(method)) { - final PsiClass aClass = method.getContainingClass(); - LOG.assertTrue(aClass != null); //Otherwise can not be overriden + PsiElement element = getPsiElement(); + if (element instanceof PsiParameter parameter + && parameter.getDeclarationScope() instanceof PsiMethod method + && PsiUtil.canBeOverriden(method)) { + PsiClass aClass = method.getContainingClass(); + LOG.assertTrue(aClass != null); //Otherwise can not be overriden - boolean hasOverridden = OverridingMethodsSearch.search(method).findFirst() != null; - if (hasOverridden && askWhetherShouldSearchForParameterInOverridingMethods(element, parameter)) { - return getParameterElementsToSearch(parameter, method); - } - } + boolean hasOverridden = OverridingMethodsSearch.search(method).findFirst() != null; + if (hasOverridden && askWhetherShouldSearchForParameterInOverridingMethods(parameter, parameter)) { + return getParameterElementsToSearch(parameter, method); } } return myElementsToSearch.length == 0 ? new PsiElement[]{element} : myElementsToSearch; @@ -166,7 +165,7 @@ public PsiElement[] getPrimaryElements() { @Override @Nonnull - @RequiredReadAction + @RequiredUIAccess public PsiElement[] getSecondaryElements() { PsiElement element = getPsiElement(); if (element.getApplication().isUnitTestMode()) { @@ -176,10 +175,10 @@ public PsiElement[] getSecondaryElements() { PsiClass containingClass = field.getContainingClass(); if (containingClass != null) { String fieldName = field.getName(); - final String propertyName = JavaCodeStyleManager.getInstance(getProject()) + String propertyName = JavaCodeStyleManager.getInstance(getProject()) .variableNameToPropertyName(fieldName, VariableKind.FIELD); Set accessors = new HashSet<>(); - boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC); + boolean isStatic = field.isStatic(); PsiMethod getter = PropertyUtil.findPropertyGetterWithType(propertyName, isStatic, field.getType(), List.of(containingClass.getMethods()).iterator()); if (getter != null) { @@ -192,20 +191,20 @@ public PsiElement[] getSecondaryElements() { } accessors.addAll(PropertyUtil.getAccessors(containingClass, fieldName)); if (!accessors.isEmpty()) { - boolean containsPhysical = ContainerUtil.find(accessors, psiMethod -> psiMethod.isPhysical()) != null; - final boolean doSearch = !containsPhysical || Messages.showOkCancelDialog( - FindBundle.message("find.field.accessors.prompt", fieldName), - FindBundle.message("find.field.accessors.title"), + boolean containsPhysical = ContainerUtil.find(accessors, PsiElement::isPhysical) != null; + boolean doSearch = !containsPhysical || Messages.showOkCancelDialog( + FindLocalize.findFieldAccessorsPrompt(fieldName).get(), + FindLocalize.findFieldAccessorsTitle().get(), CommonLocalize.buttonYes().get(), CommonLocalize.buttonNo().get(), UIUtil.getQuestionIcon() ) == Messages.OK; if (doSearch) { - final Set elements = new HashSet<>(); + Set elements = new HashSet<>(); for (PsiMethod accessor : accessors) { ContainerUtil.addAll( elements, - SuperMethodWarningUtil.checkSuperMethods(accessor, FindBundle.message("find.super.method.warning.action.verb")) + SuperMethodWarningUtil.checkSuperMethods(accessor, FindLocalize.findSuperMethodWarningActionVerb().get()) ); } return PsiUtilCore.toPsiElementArray(elements); @@ -218,7 +217,7 @@ public PsiElement[] getSecondaryElements() { @Override @Nonnull - public FindUsagesOptions getFindUsagesOptions(@Nullable final DataContext dataContext) { + public FindUsagesOptions getFindUsagesOptions(@Nullable DataContext dataContext) { PsiElement element = getPsiElement(); if (element instanceof PsiPackage) { return myFactory.getFindPackageOptions(); @@ -239,15 +238,15 @@ public FindUsagesOptions getFindUsagesOptions(@Nullable final DataContext dataCo } @Override - protected Set getStringsToSearch(@Nonnull final PsiElement element) { + protected Set getStringsToSearch(@Nonnull PsiElement element) { return JavaFindUsagesHelper.getElementNames(element); } @Override public boolean processElementUsages( - @Nonnull final PsiElement element, - @Nonnull final Processor processor, - @Nonnull final FindUsagesOptions options + @Nonnull PsiElement element, + @Nonnull Predicate processor, + @Nonnull FindUsagesOptions options ) { return JavaFindUsagesHelper.processElementUsages(element, options, processor); } @@ -260,13 +259,13 @@ protected boolean isSearchForTextOccurencesAvailable(@Nonnull PsiElement psiElem @Nonnull @Override - public Collection findReferencesToHighlight(@Nonnull final PsiElement target, @Nonnull final SearchScope searchScope) { - if (target instanceof PsiMethod) { - final PsiMethod[] superMethods = ((PsiMethod) target).findDeepestSuperMethods(); + public Collection findReferencesToHighlight(@Nonnull PsiElement target, @Nonnull SearchScope searchScope) { + if (target instanceof PsiMethod method) { + PsiMethod[] superMethods = method.findDeepestSuperMethods(); if (superMethods.length == 0) { - return MethodReferencesSearch.search((PsiMethod) target, searchScope, true).findAll(); + return MethodReferencesSearch.search(method, searchScope, true).findAll(); } - final Collection result = new ArrayList<>(); + Collection result = new ArrayList<>(); for (PsiMethod superMethod : superMethods) { result.addAll(MethodReferencesSearch.search(superMethod, searchScope, true).findAll()); } diff --git a/plugin/src/main/java/com/intellij/java/impl/javadoc/actions/GenerateJavadocAction.java b/plugin/src/main/java/com/intellij/java/impl/javadoc/actions/GenerateJavadocAction.java index 53f789883..30e3911ed 100644 --- a/plugin/src/main/java/com/intellij/java/impl/javadoc/actions/GenerateJavadocAction.java +++ b/plugin/src/main/java/com/intellij/java/impl/javadoc/actions/GenerateJavadocAction.java @@ -17,8 +17,8 @@ import com.intellij.java.impl.javadoc.JavadocConfigurable; import com.intellij.java.impl.javadoc.JavadocGenerationManager; -import com.intellij.java.language.JavadocBundle; -import consulo.ide.impl.idea.analysis.BaseAnalysisAction; +import consulo.java.language.localize.JavadocLocalize; +import consulo.language.editor.impl.action.BaseAnalysisAction; import consulo.language.editor.scope.AnalysisScope; import consulo.language.editor.ui.awt.scope.BaseAnalysisActionDialog; import consulo.project.Project; @@ -35,11 +35,11 @@ public final class GenerateJavadocAction extends BaseAnalysisAction { private JavadocConfigurable myConfigurable; public GenerateJavadocAction() { - super(JavadocBundle.message("javadoc.generate.title"), JavadocBundle.message("javadoc.generate.title")); + super(JavadocLocalize.javadocGenerateTitle().get(), JavadocLocalize.javadocGenerateTitle().get()); } @Override - protected void analyze(@Nonnull Project project, AnalysisScope scope) { + protected void analyze(@Nonnull Project project, @Nonnull AnalysisScope scope) { myConfigurable.apply(); JavadocGenerationManager.getInstance(project).generateJavadoc(scope); dispose(); @@ -49,7 +49,7 @@ protected void analyze(@Nonnull Project project, AnalysisScope scope) { @Override protected void extendMainLayout(BaseAnalysisActionDialog dialog, VerticalLayout layout, Project project) { myConfigurable = new JavadocConfigurable(JavadocGenerationManager.getInstance(project).getConfiguration()); - final JComponent component = myConfigurable.createComponent(); + JComponent component = myConfigurable.createComponent(); myConfigurable.reset(); myConfigurable.getOutputDirField().getDocument().addDocumentListener(new DocumentAdapter() { @Override diff --git a/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/AnnotatedPackagesSearcher.java b/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/AnnotatedPackagesSearcher.java index 1405eb5ec..fd9230c8c 100644 --- a/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/AnnotatedPackagesSearcher.java +++ b/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/AnnotatedPackagesSearcher.java @@ -23,11 +23,10 @@ import com.intellij.java.impl.psi.search.searches.AnnotatedPackagesSearchExecutor; import com.intellij.java.indexing.impl.stubs.index.JavaAnnotationIndex; import com.intellij.java.language.psi.*; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ExtensionImpl; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.language.psi.PsiElement; -import consulo.language.psi.PsiFile; import consulo.language.psi.PsiManager; import consulo.language.psi.scope.GlobalSearchScope; import consulo.language.psi.search.PsiSearchHelper; @@ -35,47 +34,43 @@ import consulo.logging.Logger; import consulo.module.Module; import consulo.virtualFileSystem.VirtualFile; - import jakarta.annotation.Nonnull; import java.util.Collection; +import java.util.function.Predicate; @ExtensionImpl public class AnnotatedPackagesSearcher implements AnnotatedPackagesSearchExecutor { private static final Logger LOG = Logger.getInstance(AnnotatedPackagesSearcher.class); @Override - public boolean execute(@Nonnull final AnnotatedPackagesSearch.Parameters p, @Nonnull final Processor consumer) { - final PsiClass annClass = p.getAnnotationClass(); + @RequiredReadAction + public boolean execute(@Nonnull AnnotatedPackagesSearch.Parameters p, @Nonnull Predicate consumer) { + PsiClass annClass = p.getAnnotationClass(); assert annClass.isAnnotationType() : "Annotation type should be passed to annotated packages search"; - final String annotationFQN = annClass.getQualifiedName(); + String annotationFQN = annClass.getQualifiedName(); assert annotationFQN != null; - final PsiManager psiManager = annClass.getManager(); - final SearchScope useScope = p.getScope(); + PsiManager psiManager = annClass.getManager(); + SearchScope useScope = p.getScope(); - final String annotationShortName = annClass.getName(); + String annotationShortName = annClass.getName(); assert annotationShortName != null; - final GlobalSearchScope scope = useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : null; + GlobalSearchScope scope = useScope instanceof GlobalSearchScope globalSearchScope ? globalSearchScope : null; - final Collection annotations = + Collection annotations = JavaAnnotationIndex.getInstance().get(annotationShortName, psiManager.getProject(), scope); for (PsiAnnotation annotation : annotations) { PsiModifierList modlist = (PsiModifierList)annotation.getParent(); - final PsiElement owner = modlist.getParent(); - if (!(owner instanceof PsiClass)) { - continue; - } - PsiClass candidate = (PsiClass)owner; - if (!"package-info".equals(candidate.getName())) { + if (!(modlist.getParent() instanceof PsiClass candidate && "package-info".equals(candidate.getName()))) { continue; } LOG.assertTrue(candidate.isValid()); - final PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement(); + PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement(); if (ref == null) { continue; } @@ -83,53 +78,53 @@ public boolean execute(@Nonnull final AnnotatedPackagesSearch.Parameters p, @Non if (!psiManager.areElementsEquivalent(ref.resolve(), annClass)) { continue; } - if (useScope instanceof GlobalSearchScope && - !((GlobalSearchScope)useScope).contains(candidate.getContainingFile().getVirtualFile())) { + if (useScope instanceof GlobalSearchScope + && !useScope.contains(candidate.getContainingFile().getVirtualFile())) { continue; } - final String qname = candidate.getQualifiedName(); - if (qname != null && !consumer.process(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage( + String qname = candidate.getQualifiedName(); + if (qname != null && !consumer.test(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage( qname.substring(0, qname.lastIndexOf('.'))))) { return false; } } PsiSearchHelper helper = PsiSearchHelper.SERVICE.getInstance(psiManager.getProject()); - final GlobalSearchScope infoFilesFilter = new PackageInfoFilesOnly(); + GlobalSearchScope infoFilesFilter = new PackageInfoFilesOnly(); GlobalSearchScope infoFiles = - useScope instanceof GlobalSearchScope ? ((GlobalSearchScope)useScope).intersectWith(infoFilesFilter) : infoFilesFilter; - - final boolean[] wantmore = new boolean[]{true}; - helper.processAllFilesWithWord(annotationShortName, infoFiles, new Processor() { - @Override - public boolean process(final PsiFile psiFile) { - PsiPackageStatement stmt = PsiTreeUtil.getChildOfType(psiFile, PsiPackageStatement.class); - if (stmt == null) { - return true; - } - - final PsiModifierList annotations = stmt.getAnnotationList(); - if (annotations == null) { - return true; - } - final PsiAnnotation ann = annotations.findAnnotation(annotationFQN); - if (ann == null) { - return true; - } - - final PsiJavaCodeReferenceElement ref = ann.getNameReferenceElement(); - if (ref == null) { - return true; - } - - if (!psiManager.areElementsEquivalent(ref.resolve(), annClass)) { - return true; - } - - wantmore[0] = consumer.process(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(stmt.getPackageName())); - return wantmore[0]; + useScope instanceof GlobalSearchScope globalSearchScope ? globalSearchScope.intersectWith(infoFilesFilter) : infoFilesFilter; + + boolean[] wantmore = new boolean[]{true}; + helper.processAllFilesWithWord( + annotationShortName, + infoFiles, + psiFile -> { + PsiPackageStatement stmt = PsiTreeUtil.getChildOfType(psiFile, PsiPackageStatement.class); + if (stmt == null) { + return true; + } + + PsiModifierList annotations1 = stmt.getAnnotationList(); + if (annotations1 == null) { + return true; + } + PsiAnnotation ann = annotations1.findAnnotation(annotationFQN); + if (ann == null) { + return true; } + + PsiJavaCodeReferenceElement ref = ann.getNameReferenceElement(); + if (ref == null) { + return true; + } + + if (!psiManager.areElementsEquivalent(ref.resolve(), annClass)) { + return true; + } + + wantmore[0] = consumer.test(JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(stmt.getPackageName())); + return wantmore[0]; }, true ); @@ -139,12 +134,12 @@ public boolean process(final PsiFile psiFile) { private static class PackageInfoFilesOnly extends GlobalSearchScope { @Override - public int compare(final VirtualFile file1, final VirtualFile file2) { + public int compare(@Nonnull VirtualFile file1, @Nonnull VirtualFile file2) { return 0; } @Override - public boolean contains(final VirtualFile file) { + public boolean contains(VirtualFile file) { return "package-info.java".equals(file.getName()); } @@ -154,7 +149,7 @@ public boolean isSearchInLibraries() { } @Override - public boolean isSearchInModuleContent(@Nonnull final Module aModule) { + public boolean isSearchInModuleContent(@Nonnull Module aModule) { return true; } } diff --git a/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/VariableInIncompleteCodeSearcher.java b/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/VariableInIncompleteCodeSearcher.java index 9ee095460..c18f12b7d 100644 --- a/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/VariableInIncompleteCodeSearcher.java +++ b/plugin/src/main/java/com/intellij/java/impl/psi/impl/search/VariableInIncompleteCodeSearcher.java @@ -20,8 +20,8 @@ import com.intellij.java.language.psi.PsiLocalVariable; import com.intellij.java.language.psi.PsiParameter; import com.intellij.java.language.psi.PsiVariable; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ExtensionImpl; -import consulo.application.util.function.Processor; import consulo.content.scope.SearchScope; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiReference; @@ -31,9 +31,10 @@ import consulo.language.psi.search.ReferencesSearchQueryExecutor; import consulo.language.psi.util.PsiTreeUtil; import consulo.project.util.query.QueryExecutorBase; - import jakarta.annotation.Nonnull; +import java.util.function.Predicate; + /** * Looks for references to local variable or method parameter in invalid (incomplete) code. */ @@ -44,39 +45,35 @@ public VariableInIncompleteCodeSearcher() { } @Override - public void processQuery(@Nonnull final ReferencesSearch.SearchParameters p, @Nonnull final Processor consumer) { - final PsiElement refElement = p.getElementToSearch(); + @RequiredReadAction + public void processQuery(@Nonnull ReferencesSearch.SearchParameters p, @Nonnull Predicate consumer) { + PsiElement refElement = p.getElementToSearch(); if (!refElement.isValid() || !(refElement instanceof PsiLocalVariable || refElement instanceof PsiParameter)) { return; } - final String name = ((PsiVariable)refElement).getName(); + String name = ((PsiVariable)refElement).getName(); if (name == null) { return; } - final SearchScope scope = p.getEffectiveSearchScope(); - if (!(scope instanceof LocalSearchScope)) { + SearchScope scope = p.getEffectiveSearchScope(); + if (!(scope instanceof LocalSearchScope localSearchScope)) { return; } - PsiElement[] elements = ((LocalSearchScope)scope).getScope(); + PsiElement[] elements = localSearchScope.getScope(); if (elements == null || elements.length == 0) { return; } - PsiElementProcessor processor = new PsiElementProcessor() { - @Override - public boolean execute(@Nonnull final PsiElement element) { - if (element instanceof PsiJavaCodeReferenceElement) { - final PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement)element; - if (!ref.isQualified() && name.equals(ref.getText()) && - ref.resolve() == null && ref.advancedResolve(true).getElement() == refElement) { - consumer.process(ref); - } - } - return true; + PsiElementProcessor processor = element -> { + if (element instanceof PsiJavaCodeReferenceElement ref + && !ref.isQualified() && name.equals(ref.getText()) + && ref.resolve() == null && ref.advancedResolve(true).getElement() == refElement) { + consumer.test(ref); } + return true; }; for (PsiElement element : elements) { diff --git a/plugin/src/main/java/com/intellij/java/impl/psi/search/searches/AnnotatedPackagesSearchExecutor.java b/plugin/src/main/java/com/intellij/java/impl/psi/search/searches/AnnotatedPackagesSearchExecutor.java index a19652b20..32e69420d 100644 --- a/plugin/src/main/java/com/intellij/java/impl/psi/search/searches/AnnotatedPackagesSearchExecutor.java +++ b/plugin/src/main/java/com/intellij/java/impl/psi/search/searches/AnnotatedPackagesSearchExecutor.java @@ -7,7 +7,7 @@ /** * @author VISTALL - * @since 14/11/2022 + * @since 2022-11-14 */ @ExtensionAPI(ComponentScope.APPLICATION) public interface AnnotatedPackagesSearchExecutor extends QueryExecutor {