1 package com.intellij.psi.impl.search;
\r
3 import com.intellij.openapi.application.ApplicationManager;
\r
4 import com.intellij.openapi.util.Computable;
\r
5 import com.intellij.psi.*;
\r
6 import com.intellij.psi.search.SearchScope;
\r
7 import com.intellij.psi.search.searches.ClassInheritorsSearch;
\r
8 import com.intellij.psi.search.searches.OverridingMethodsSearch;
\r
9 import com.intellij.psi.util.MethodSignature;
\r
10 import com.intellij.psi.util.MethodSignatureUtil;
\r
11 import com.intellij.psi.util.TypeConversionUtil;
\r
12 import com.intellij.util.Processor;
\r
13 import com.intellij.util.QueryExecutor;
\r
14 import org.jetbrains.annotations.NotNull;
\r
15 import org.jetbrains.annotations.Nullable;
\r
20 public class JavaOverridingMethodsSearcher implements QueryExecutor<PsiMethod, OverridingMethodsSearch.SearchParameters> {
\r
22 public boolean execute(@NotNull final OverridingMethodsSearch.SearchParameters p, @NotNull final Processor<PsiMethod> consumer) {
\r
23 final PsiMethod method = p.getMethod();
\r
24 final SearchScope scope = p.getScope();
\r
26 final PsiClass parentClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
\r
29 public PsiClass compute() {
\r
30 return method.getContainingClass();
\r
33 assert parentClass != null;
\r
34 Processor<PsiClass> inheritorsProcessor = new Processor<PsiClass>() {
\r
36 public boolean process(final PsiClass inheritor) {
\r
37 PsiMethod found = ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod>() {
\r
40 public PsiMethod compute() {
\r
41 return findOverridingMethod(inheritor, parentClass, method);
\r
44 return found == null || consumer.process(found) && p.isCheckDeep();
\r
48 return ClassInheritorsSearch.search(parentClass, scope, true).forEach(inheritorsProcessor);
\r
52 private static PsiMethod findOverridingMethod(PsiClass inheritor, @NotNull PsiClass parentClass, PsiMethod method) {
\r
53 if (!inheritor.isInheritor(parentClass, true)) {
\r
57 PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(parentClass, inheritor, PsiSubstitutor.EMPTY);
\r
58 MethodSignature signature = method.getSignature(substitutor);
\r
59 PsiMethod found = MethodSignatureUtil.findMethodBySuperSignature(inheritor, signature, false);
\r
60 if (found != null && isAcceptable(found, method)) {
\r
64 if (parentClass.isInterface() && !inheritor.isInterface()) { //check for sibling implementation
\r
65 final PsiClass superClass = inheritor.getSuperClass();
\r
66 if (superClass != null && !superClass.isInheritor(parentClass, true)) {
\r
67 PsiMethod derived = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived(inheritor, superClass, signature, true);
\r
68 if (derived != null && isAcceptable(derived, method)) {
\r
76 private static boolean isAcceptable(final PsiMethod found, final PsiMethod method) {
\r
77 return !found.hasModifierProperty(PsiModifier.STATIC) &&
\r
78 (!method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) ||
\r
79 JavaPsiFacade.getInstance(found.getProject())
\r
80 .arePackagesTheSame(method.getContainingClass(), found.getContainingClass()));
\r