2 * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
4 package com
.intellij
.find
.findUsages
;
6 import com
.intellij
.openapi
.application
.ApplicationManager
;
7 import com
.intellij
.openapi
.application
.ReadActionProcessor
;
8 import com
.intellij
.openapi
.project
.Project
;
9 import com
.intellij
.openapi
.util
.Computable
;
10 import com
.intellij
.openapi
.util
.TextRange
;
11 import com
.intellij
.psi
.PsiElement
;
12 import com
.intellij
.psi
.PsiNamedElement
;
13 import com
.intellij
.psi
.PsiReference
;
14 import com
.intellij
.psi
.util
.PsiUtilBase
;
15 import com
.intellij
.psi
.search
.GlobalSearchScope
;
16 import com
.intellij
.psi
.search
.SearchScope
;
17 import com
.intellij
.psi
.search
.searches
.ReferencesSearch
;
18 import com
.intellij
.refactoring
.util
.TextOccurrencesUtil
;
19 import com
.intellij
.usageView
.UsageInfo
;
20 import com
.intellij
.util
.Processor
;
21 import org
.jetbrains
.annotations
.NotNull
;
23 import java
.util
.Collection
;
28 public abstract class FindUsagesHandler
{
29 // return this handler if you want to cancel the search
30 public static final FindUsagesHandler NULL_HANDLER
= new FindUsagesHandler(PsiUtilBase
.NULL_PSI_ELEMENT
){};
32 private final PsiElement myPsiElement
;
34 protected FindUsagesHandler(@NotNull PsiElement psiElement
) {
35 myPsiElement
= psiElement
;
39 public AbstractFindUsagesDialog
getFindUsagesDialog(boolean isSingleFile
, boolean toShowInNewTab
, boolean mustOpenInNewTab
) {
40 return new CommonFindUsagesDialog(myPsiElement
, getProject(), getFindUsagesOptions(), toShowInNewTab
, mustOpenInNewTab
, isSingleFile
, this);
43 public final PsiElement
getPsiElement() {
48 public final Project
getProject() {
49 return myPsiElement
.getProject();
53 public PsiElement
[] getPrimaryElements() {
54 return new PsiElement
[]{myPsiElement
};
58 public PsiElement
[] getSecondaryElements() {
59 return PsiElement
.EMPTY_ARRAY
;
62 public static FindUsagesOptions
createFindUsagesOptions(final Project project
) {
63 FindUsagesOptions findUsagesOptions
= new FindUsagesOptions(project
, null);
64 findUsagesOptions
.isUsages
= true;
65 findUsagesOptions
.isIncludeOverloadUsages
= false;
66 findUsagesOptions
.isIncludeSubpackages
= true;
67 findUsagesOptions
.isReadAccess
= true;
68 findUsagesOptions
.isWriteAccess
= true;
69 findUsagesOptions
.isCheckDeepInheritance
= true;
70 findUsagesOptions
.isSearchForTextOccurences
= true;
71 return findUsagesOptions
;
75 public FindUsagesOptions
getFindUsagesOptions() {
76 FindUsagesOptions options
= createFindUsagesOptions(getProject());
77 options
.isSearchForTextOccurences
&= isSearchForTextOccurencesAvailable(getPsiElement(), false);
81 public void processElementUsages(@NotNull final PsiElement element
, @NotNull final Processor
<UsageInfo
> processor
, @NotNull FindUsagesOptions options
) {
82 if (options
.isUsages
) {
83 ReferencesSearch
.search(element
, options
.searchScope
, false).forEach(new ReadActionProcessor
<PsiReference
>() {
84 public boolean processInReadAction(final PsiReference ref
) {
85 TextRange rangeInElement
= ref
.getRangeInElement();
86 return processor
.process(new UsageInfo(ref
.getElement(), rangeInElement
.getStartOffset(), rangeInElement
.getEndOffset(), false));
91 if (options
.isSearchForTextOccurences
&& options
.searchScope
instanceof GlobalSearchScope
) {
92 processUsages(element
, processor
, options
);
96 public void processUsages(@NotNull final PsiElement element
, @NotNull Processor
<UsageInfo
> processor
, @NotNull FindUsagesOptions options
) {
97 String stringToSearch
= getStringToSearch(element
);
98 if (stringToSearch
!= null) {
99 final TextRange elementTextRange
= ApplicationManager
.getApplication().runReadAction(new Computable
<TextRange
>() {
100 public TextRange
compute() {
101 if (!element
.isValid()) return null;
102 return element
.getTextRange();
105 TextOccurrencesUtil
.UsageInfoFactory factory
= new TextOccurrencesUtil
.UsageInfoFactory() {
106 public UsageInfo
createUsageInfo(@NotNull PsiElement usage
, int startOffset
, int endOffset
) {
107 if (elementTextRange
!= null
108 && usage
.getContainingFile() == element
.getContainingFile()
109 && elementTextRange
.contains(startOffset
)
110 && elementTextRange
.contains(endOffset
)) {
113 return new UsageInfo(usage
, startOffset
, endOffset
, true);
116 TextOccurrencesUtil
.processTextOccurences(element
, stringToSearch
, (GlobalSearchScope
)options
.searchScope
, processor
, factory
);
120 protected String
getStringToSearch(final PsiElement element
) {
121 if (element
instanceof PsiNamedElement
) {
122 return ((PsiNamedElement
)element
).getName();
125 return element
.getText();
128 protected boolean isSearchForTextOccurencesAvailable(PsiElement psiElement
, boolean isSingleFile
) {
132 public Collection
<PsiReference
> findReferencesToHighlight(PsiElement target
, SearchScope searchScope
) {
133 return ReferencesSearch
.search(target
, searchScope
, false).findAll();