2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com
.intellij
.packageDependencies
;
19 import com
.intellij
.analysis
.AnalysisScopeBundle
;
20 import com
.intellij
.openapi
.progress
.ProcessCanceledException
;
21 import com
.intellij
.openapi
.progress
.ProgressIndicator
;
22 import com
.intellij
.openapi
.progress
.ProgressManager
;
23 import com
.intellij
.openapi
.vfs
.VirtualFile
;
24 import com
.intellij
.psi
.PsiElement
;
25 import com
.intellij
.psi
.PsiFile
;
26 import com
.intellij
.usageView
.UsageInfo
;
27 import org
.jetbrains
.annotations
.Nullable
;
31 public class FindDependencyUtil
{
32 private FindDependencyUtil() {}
34 public static UsageInfo
[] findDependencies(@Nullable final List
<DependenciesBuilder
> builders
, Set
<PsiFile
> searchIn
, Set
<PsiFile
> searchFor
) {
35 final List
<UsageInfo
> usages
= new ArrayList
<UsageInfo
>();
36 ProgressIndicator indicator
= ProgressManager
.getInstance().getProgressIndicator();
37 int totalCount
= searchIn
.size();
40 nextFile
: for (final PsiFile psiFile
: searchIn
) {
41 count
= updateIndicator(indicator
, totalCount
, count
, psiFile
);
43 if (!psiFile
.isValid()) continue;
45 final Set
<PsiFile
> precomputedDeps
;
46 if (builders
!= null) {
47 final Set
<PsiFile
> depsByFile
= new HashSet
<PsiFile
>();
48 for (DependenciesBuilder builder
: builders
) {
49 final Set
<PsiFile
> deps
= builder
.getDependencies().get(psiFile
);
51 depsByFile
.addAll(deps
);
54 precomputedDeps
= new HashSet
<PsiFile
>(depsByFile
);
55 precomputedDeps
.retainAll(searchFor
);
56 if (precomputedDeps
.isEmpty()) continue nextFile
;
59 precomputedDeps
= Collections
.unmodifiableSet(searchFor
);
62 DependenciesBuilder
.analyzeFileDependencies(psiFile
, new DependenciesBuilder
.DependencyProcessor() {
63 public void process(PsiElement place
, PsiElement dependency
) {
64 PsiFile dependencyFile
= dependency
.getContainingFile();
65 if (precomputedDeps
.contains(dependencyFile
)) {
66 usages
.add(new UsageInfo(place
));
72 return usages
.toArray(new UsageInfo
[usages
.size()]);
75 public static UsageInfo
[] findBackwardDependencies(final List
<DependenciesBuilder
> builders
, final Set
<PsiFile
> searchIn
, final Set
<PsiFile
> searchFor
) {
76 final List
<UsageInfo
> usages
= new ArrayList
<UsageInfo
>();
77 ProgressIndicator indicator
= ProgressManager
.getInstance().getProgressIndicator();
80 final Set
<PsiFile
> deps
= new HashSet
<PsiFile
>();
81 for (PsiFile psiFile
: searchFor
) {
82 for (DependenciesBuilder builder
: builders
) {
83 final Set
<PsiFile
> depsByBuilder
= builder
.getDependencies().get(psiFile
);
84 if (depsByBuilder
!= null) {
85 deps
.addAll(depsByBuilder
);
89 deps
.retainAll(searchIn
);
90 if (deps
.isEmpty()) return new UsageInfo
[0];
92 int totalCount
= deps
.size();
94 for (final PsiFile psiFile
: deps
) {
95 count
= updateIndicator(indicator
, totalCount
, count
, psiFile
);
97 DependenciesBuilder
.analyzeFileDependencies(psiFile
, new DependenciesBuilder
.DependencyProcessor() {
98 public void process(PsiElement place
, PsiElement dependency
) {
99 PsiFile dependencyFile
= dependency
.getContainingFile();
100 if (searchFor
.contains(dependencyFile
)) {
101 usages
.add(new UsageInfo(place
));
107 return usages
.toArray(new UsageInfo
[usages
.size()]);
110 private static int updateIndicator(final ProgressIndicator indicator
, final int totalCount
, int count
, final PsiFile psiFile
) {
111 if (indicator
!= null) {
112 if (indicator
.isCanceled()) throw new ProcessCanceledException();
113 indicator
.setFraction(((double)++count
) / totalCount
);
114 final VirtualFile virtualFile
= psiFile
.getVirtualFile();
115 if (virtualFile
!= null) {
116 indicator
.setText(AnalysisScopeBundle
.message("find.dependencies.progress.text", virtualFile
.getPresentableUrl()));
122 public static UsageInfo
[] findDependencies(final DependenciesBuilder builder
, final Set
<PsiFile
> searchIn
, final Set
<PsiFile
> searchFor
) {
123 return findDependencies(Collections
.singletonList(builder
), searchIn
, searchFor
);
126 public static UsageInfo
[] findBackwardDependencies(final DependenciesBuilder builder
, final Set
<PsiFile
> searchIn
, final Set
<PsiFile
> searchFor
) {
127 return findBackwardDependencies(Collections
.singletonList(builder
), searchIn
, searchFor
);