2 * Copyright (c) 2005 Your Corporation. All Rights Reserved.
4 package com
.intellij
.psi
.impl
.search
;
6 import com
.intellij
.openapi
.application
.ApplicationManager
;
7 import com
.intellij
.openapi
.application
.ReadActionProcessor
;
8 import com
.intellij
.openapi
.fileTypes
.StdFileTypes
;
9 import com
.intellij
.openapi
.util
.Computable
;
10 import com
.intellij
.openapi
.extensions
.Extensions
;
11 import com
.intellij
.psi
.*;
12 import com
.intellij
.psi
.search
.*;
13 import com
.intellij
.psi
.search
.searches
.MethodReferencesSearch
;
14 import com
.intellij
.psi
.search
.searches
.ReferencesSearch
;
15 import com
.intellij
.psi
.util
.PropertyUtil
;
16 import com
.intellij
.psi
.util
.TypeConversionUtil
;
17 import com
.intellij
.util
.Processor
;
18 import com
.intellij
.util
.QueryExecutor
;
23 public class MethodUsagesSearcher
implements QueryExecutor
<PsiReference
, MethodReferencesSearch
.SearchParameters
> {
24 public boolean execute(final MethodReferencesSearch
.SearchParameters p
, final Processor
<PsiReference
> consumer
) {
25 final PsiMethod method
= p
.getMethod();
26 SearchScope searchScope
= p
.getScope();
27 PsiManager psiManager
= PsiManager
.getInstance(method
.getProject());
28 final boolean isStrictSignatureSearch
= p
.isStrictSignatureSearch();
30 if (method
.isConstructor()) {
31 final ConstructorReferencesSearchHelper helper
= new ConstructorReferencesSearchHelper(psiManager
);
32 if (!helper
.processConstructorReferences(consumer
, method
, searchScope
, !isStrictSignatureSearch
, isStrictSignatureSearch
)) {
37 PsiClass parentClass
= method
.getContainingClass();
38 if (isStrictSignatureSearch
&& (parentClass
== null
39 || parentClass
instanceof PsiAnonymousClass
40 || parentClass
.hasModifierProperty(PsiModifier
.FINAL
)
41 || method
.hasModifierProperty(PsiModifier
.STATIC
)
42 || method
.hasModifierProperty(PsiModifier
.FINAL
)
43 || method
.hasModifierProperty(PsiModifier
.PRIVATE
))
45 return ReferencesSearch
.search(method
, searchScope
, false).forEach(new ReadActionProcessor
<PsiReference
>() {
46 public boolean processInReadAction(final PsiReference psiReference
) {
47 return consumer
.process(psiReference
);
52 final String text
= method
.getName();
53 final PsiMethod
[] methods
= isStrictSignatureSearch ?
new PsiMethod
[]{method
} : getOverloads(method
);
55 SearchScope accessScope
= ApplicationManager
.getApplication().runReadAction(new Computable
<SearchScope
>() {
56 public SearchScope
compute() {
57 SearchScope accessScope
= methods
[0].getUseScope();
58 for (int i
= 1; i
< methods
.length
; i
++) {
59 PsiMethod method1
= methods
[i
];
60 SearchScope someScope
= PsiSearchScopeUtil
.scopesUnion(accessScope
, method1
.getUseScope());
61 accessScope
= someScope
== null ? accessScope
: someScope
;
67 final TextOccurenceProcessor processor1
= new TextOccurenceProcessor() {
68 public boolean execute(PsiElement element
, int offsetInElement
) {
69 final PsiClass aClass
= method
.getContainingClass();
70 if (aClass
== null) return true;
71 final PsiReference
[] refs
= element
.getReferences();
72 for (PsiReference ref
: refs
) {
73 if (ref
.getRangeInElement().contains(offsetInElement
)) {
74 for (PsiMethod method
: methods
) {
75 if (ref
.isReferenceTo(method
)) {
76 return consumer
.process(ref
);
78 PsiElement refElement
= ref
.resolve();
80 if (refElement
instanceof PsiMethod
) {
81 PsiMethod refMethod
= (PsiMethod
)refElement
;
82 PsiClass refMethodClass
= refMethod
.getContainingClass();
83 if (refMethodClass
== null) continue;
85 if (!refMethod
.hasModifierProperty(PsiModifier
.STATIC
)) {
86 PsiSubstitutor substitutor
= TypeConversionUtil
.getClassSubstitutor(aClass
, refMethodClass
, PsiSubstitutor
.EMPTY
);
87 if (substitutor
!= null) {
88 if (refMethod
.getSignature(PsiSubstitutor
.EMPTY
).equals(method
.getSignature(substitutor
))) {
89 if (!consumer
.process(ref
)) return false;
94 if (!isStrictSignatureSearch
) {
95 PsiManager manager
= method
.getManager();
96 if (manager
.areElementsEquivalent(refMethodClass
, aClass
)) {
97 if (!consumer
.process(ref
)) return false;
109 searchScope
= searchScope
.intersectWith(accessScope
);
111 short searchContext
= UsageSearchContext
.IN_CODE
| UsageSearchContext
.IN_COMMENTS
| UsageSearchContext
.IN_FOREIGN_LANGUAGES
;
112 boolean toContinue
= psiManager
.getSearchHelper().processElementsWithWord(processor1
,
115 searchContext
, true);
116 if (!toContinue
) return false;
118 final String propertyName
= PropertyUtil
.getPropertyName(method
);
119 if (propertyName
!= null) {
120 if (searchScope
instanceof GlobalSearchScope
) {
121 GlobalSearchScope restrictedSeachScope
= GlobalSearchScope
.getScopeRestrictedByFileTypes(
122 (GlobalSearchScope
)searchScope
,
127 toContinue
= psiManager
.getSearchHelper().processElementsWithWord(processor1
,
128 restrictedSeachScope
,
130 UsageSearchContext
.IN_FOREIGN_LANGUAGES
, true);
132 toContinue
= psiManager
.getSearchHelper().processElementsWithWord(processor1
,
135 UsageSearchContext
.IN_FOREIGN_LANGUAGES
, true);
137 if (!toContinue
) return false;
139 final CustomPropertyScopeProvider
[] providers
= Extensions
.getExtensions(CustomPropertyScopeProvider
.EP_NAME
);
140 for (CustomPropertyScopeProvider provider
: providers
) {
141 searchScope
.intersectWith(provider
.getScope(psiManager
.getProject()));
143 toContinue
= psiManager
.getSearchHelper().processElementsWithWord(processor1
,
146 UsageSearchContext
.IN_FOREIGN_LANGUAGES
, true);
147 if (!toContinue
) return false;
153 private static PsiMethod
[] getOverloads(final PsiMethod method
) {
154 return ApplicationManager
.getApplication().runReadAction(new Computable
<PsiMethod
[]>() {
155 public PsiMethod
[] compute() {
156 PsiClass aClass
= method
.getContainingClass();
157 if (aClass
== null) return new PsiMethod
[]{method
};
158 return aClass
.findMethodsByName(method
.getName(), false);