diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java index a5ea8242b66c..e9f6b483ad86 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java @@ -49,12 +49,12 @@ import java.util.concurrent.atomic.AtomicIntegerArray; public class JavaDirectInheritorsSearcher implements QueryExecutor { @Override public boolean execute(@NotNull final DirectClassInheritorsSearch.SearchParameters parameters, @NotNull final Processor consumer) { - final PsiClass aClass = parameters.getClassToProcess(); + final PsiClass baseClass = parameters.getClassToProcess(); - final SearchScope useScope = ApplicationManager.getApplication().runReadAction((Computable)aClass::getUseScope); + final SearchScope useScope = ApplicationManager.getApplication().runReadAction((Computable)baseClass::getUseScope); - final Project project = PsiUtilCore.getProjectInReadAction(aClass); - if (JavaClassInheritorsSearcher.isJavaLangObject(aClass)) { + final Project project = PsiUtilCore.getProjectInReadAction(baseClass); + if (JavaClassInheritorsSearcher.isJavaLangObject(baseClass)) { return AllClassesSearch.search(useScope, project).forEach(psiClass -> { ProgressManager.checkCanceled(); if (psiClass.isInterface()) { @@ -66,7 +66,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor, AtomicIntegerArray> pair = calculateDirectSubClasses(project, aClass); + Pair, AtomicIntegerArray> pair = getOrCalculateDirectSubClasses(project, baseClass); List result = pair.getFirst(); AtomicIntegerArray isInheritorFlag = pair.getSecond(); @@ -74,7 +74,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor consumer) { + if (!isInScope(scope, candidate)) return CheckResult.CANDIDATE_REJECTED; + if (!checkInheritance(parameters.isCheckInheritance(), baseClass, candidate, project, isInheritorFlag, i)) return CheckResult.CANDIDATE_REJECTED; + return consumer.process(candidate) ? CheckResult.PROCESSED_OK : CheckResult.PROCESSED_ABORT; + } + + private static boolean isInScope(@NotNull GlobalSearchScope scope, @NotNull PsiClass subClass) { return ApplicationManager.getApplication().runReadAction((Computable)() -> PsiSearchScopeUtil.isInScope(scope, subClass)); } @@ -138,7 +154,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor, AtomicIntegerArray> calculateDirectSubClasses(@NotNull Project project, @NotNull PsiClass baseClass) { + private static Pair, AtomicIntegerArray> getOrCalculateDirectSubClasses(@NotNull Project project, @NotNull PsiClass baseClass) { Pair, AtomicIntegerArray> cached = HighlightingCaches.getInstance(project).DIRECT_SUB_CLASSES.get(baseClass); if (cached != null) { return cached; @@ -148,9 +164,19 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor, AtomicIntegerArray> pair = calculateDirectSubClasses(project, baseClass, className); + HighlightingCaches.getInstance(project).DIRECT_SUB_CLASSES.put(baseClass, pair); + return pair; + } + + @NotNull + private static Pair, AtomicIntegerArray> calculateDirectSubClasses(@NotNull Project project, + @NotNull PsiClass baseClass, + @NotNull String className) { GlobalSearchScope allScope = GlobalSearchScope.allScope(project); Collection candidates = - MethodUsagesSearcher.resolveInReadAction(project, () -> JavaSuperClassNameOccurenceIndex.getInstance().get(className, project, allScope)); + MethodUsagesSearcher + .resolveInReadAction(project, () -> JavaSuperClassNameOccurenceIndex.getInstance().get(className, project, allScope)); Map> classes = new HashMap<>(); int count = 0; @@ -172,7 +198,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor anonymousCandidates = MethodUsagesSearcher.resolveInReadAction(project, () -> JavaAnonymousClassBaseRefOccurenceIndex.getInstance().get(className, project, allScope)); - List result = new ArrayList<>(count+classes.size()+anonymousCandidates.size()+1); + List result = new ArrayList<>(count + classes.size() + anonymousCandidates.size() + 1); for (Map.Entry> entry : classes.entrySet()) { result.addAll(entry.getValue()); result.add(PsiUtil.NULL_PSI_CLASS); @@ -196,13 +222,11 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor, AtomicIntegerArray> pair = Pair.create(result, new AtomicIntegerArray(result.size())); - HighlightingCaches.getInstance(project).DIRECT_SUB_CLASSES.put(baseClass, pair); - return pair; + return Pair.create(result, new AtomicIntegerArray(result.size())); } private static boolean checkInheritance(boolean checkInheritance, - @NotNull PsiClass aClass, + @NotNull PsiClass baseClass, @NotNull PsiClass candidate, @NotNull Project project, @NotNull AtomicIntegerArray isInheritorFlags, @@ -212,7 +236,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor candidate.isInheritor(aClass, false)); + boolean isReallyInherited = MethodUsagesSearcher.resolveInReadAction(project, () -> candidate.isInheritor(baseClass, false)); isInheritorFlags.set(i, isReallyInherited ? INHERITANCE_YES : INHERITANCE_NO); return isReallyInherited; }