IDEADEV-40311: read action
[fedora-idea.git] / java / java-impl / src / com / intellij / psi / impl / search / MethodUsagesSearcher.java
blob0c13f4e481dfb7f2144b8501f111e880016ba2d9
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.extensions.Extensions;
9 import com.intellij.openapi.fileTypes.StdFileTypes;
10 import com.intellij.openapi.util.Computable;
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.util.Processor;
17 import com.intellij.util.QueryExecutor;
18 import org.jetbrains.annotations.NotNull;
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 final SearchScope searchScope = p.getScope();
27 final PsiManager psiManager = PsiManager.getInstance(method.getProject());
28 final boolean isStrictSignatureSearch = p.isStrictSignatureSearch();
30 final PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
31 public PsiClass compute() {
32 return method.getContainingClass();
34 });
35 if (aClass == null) return true;
37 if (method.isConstructor()) {
38 final ConstructorReferencesSearchHelper helper = new ConstructorReferencesSearchHelper(psiManager);
39 if (!helper.processConstructorReferences(consumer, method, searchScope, !isStrictSignatureSearch, isStrictSignatureSearch)) {
40 return false;
44 final PsiClass parentClass = method.getContainingClass();
45 boolean needStrictSignatureSearch = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
46 public Boolean compute() {
47 return method.isValid() && isStrictSignatureSearch && (parentClass == null
48 || parentClass instanceof PsiAnonymousClass
49 || parentClass.hasModifierProperty(PsiModifier.FINAL)
50 || method.hasModifierProperty(PsiModifier.STATIC)
51 || method.hasModifierProperty(PsiModifier.FINAL)
52 || method.hasModifierProperty(PsiModifier.PRIVATE));
54 }).booleanValue();
55 if (needStrictSignatureSearch) {
56 return ReferencesSearch.search(method, searchScope, false).forEach(new ReadActionProcessor<PsiReference>() {
57 public boolean processInReadAction(final PsiReference psiReference) {
58 return consumer.process(psiReference);
60 });
63 final String textToSearch = method.getName();
64 final PsiMethod[] methods = isStrictSignatureSearch ? new PsiMethod[]{method} : getOverloads(method);
66 SearchScope accessScope = ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
67 public SearchScope compute() {
68 if (!method.isValid()) return searchScope;
69 SearchScope accessScope = methods[0].getUseScope();
70 for (int i = 1; i < methods.length; i++) {
71 PsiMethod method1 = methods[i];
72 accessScope = accessScope.union(method1.getUseScope());
74 return accessScope;
76 });
78 final TextOccurenceProcessor processor1 = new MethodTextOccurenceProcessor(consumer, aClass, isStrictSignatureSearch, methods);
80 final SearchScope restrictedByAccess = searchScope.intersectWith(accessScope);
82 short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES;
83 boolean toContinue = psiManager.getSearchHelper().processElementsWithWord(processor1,
84 restrictedByAccess,
85 textToSearch,
86 searchContext, true);
87 if (!toContinue) return false;
89 final String propertyName = ApplicationManager.getApplication().runReadAction(new Computable<String>(){
90 public String compute() {
91 if (!method.isValid()) return null;
92 return PropertyUtil.getPropertyName(method);
94 });
95 if (propertyName != null) {
96 final SearchScope scope = ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
97 public SearchScope compute() {
98 SearchScope additional = GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(psiManager.getProject()),
99 StdFileTypes.JSP, StdFileTypes.JSPX,
100 StdFileTypes.XML, StdFileTypes.XHTML);
102 for (CustomPropertyScopeProvider provider : Extensions.getExtensions(CustomPropertyScopeProvider.EP_NAME)) {
103 SearchScope s = provider.getScope(psiManager.getProject());
104 additional = additional.union(s);
107 return restrictedByAccess.intersectWith(additional);
110 toContinue = psiManager.getSearchHelper().processElementsWithWord(processor1,
111 scope,
112 propertyName,
113 UsageSearchContext.IN_FOREIGN_LANGUAGES, true);
114 if (!toContinue) return false;
117 return true;
120 @NotNull
121 private static PsiMethod[] getOverloads(final PsiMethod method) {
122 return ApplicationManager.getApplication().runReadAction(new Computable<PsiMethod[]>() {
123 public PsiMethod[] compute() {
124 if (!method.isValid()) return PsiMethod.EMPTY_ARRAY;
125 PsiClass aClass = method.getContainingClass();
126 if (aClass == null) return new PsiMethod[]{method};
127 return aClass.findMethodsByName(method.getName(), false);