inject el seam
[fedora-idea.git] / source / com / intellij / psi / impl / search / MethodUsagesSearcher.java
blob02c8dbf192ada2deac605aa7aaa5d426455ebd24
1 /*
2 * Copyright (c) 2005 Your Corporation. All Rights Reserved.
3 */
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;
20 /**
21 * @author max
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)) {
33 return false;
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))
44 ) {
45 return ReferencesSearch.search(method, searchScope, false).forEach(new ReadActionProcessor<PsiReference>() {
46 public boolean processInReadAction(final PsiReference psiReference) {
47 return consumer.process(psiReference);
49 });
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;
63 return accessScope;
65 });
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;
105 return true;
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,
113 searchScope,
114 text,
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,
123 StdFileTypes.JSP,
124 StdFileTypes.JSPX,
125 StdFileTypes.XML
127 toContinue = psiManager.getSearchHelper().processElementsWithWord(processor1,
128 restrictedSeachScope,
129 propertyName,
130 UsageSearchContext.IN_FOREIGN_LANGUAGES, true);
131 } else {
132 toContinue = psiManager.getSearchHelper().processElementsWithWord(processor1,
133 searchScope,
134 propertyName,
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,
144 searchScope,
145 propertyName,
146 UsageSearchContext.IN_FOREIGN_LANGUAGES, true);
147 if (!toContinue) return false;
150 return true;
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);