5fa0879e18e8ffb8b531bf38dc1c7e3015d02dd9
[idea/community.git] / platform / lang-api / src / com / intellij / psi / search / GlobalSearchScopes.java
1 /*
2  * Copyright 2000-2011 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.psi.search;
17
18 import com.intellij.openapi.module.Module;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.roots.ProjectFileIndex;
21 import com.intellij.openapi.roots.ProjectRootManager;
22 import com.intellij.openapi.util.Comparing;
23 import com.intellij.openapi.vfs.VfsUtilCore;
24 import com.intellij.openapi.vfs.VirtualFile;
25 import com.intellij.psi.PsiBundle;
26 import com.intellij.psi.PsiDirectory;
27 import com.intellij.psi.PsiFile;
28 import com.intellij.psi.PsiManager;
29 import com.intellij.psi.search.scope.packageSet.*;
30 import org.jetbrains.annotations.NotNull;
31
32 import java.util.Collection;
33
34 /**
35  * @author yole
36  */
37 public class GlobalSearchScopes {
38   private GlobalSearchScopes() {
39   }
40
41   public static GlobalSearchScope projectProductionScope(@NotNull Project project) {
42     return new GlobalSearchScope.IntersectionScope(GlobalSearchScope.projectScope(project),
43                                  new ProductionScopeFilter(project),
44                                  PsiBundle.message("psi.search.scope.production.files"));
45   }
46
47   public static GlobalSearchScope projectTestScope(@NotNull Project project) {
48     return new GlobalSearchScope.IntersectionScope(GlobalSearchScope.projectScope(project),
49                                  new TestScopeFilter(project),
50                                  PsiBundle.message("psi.search.scope.test.files"));
51   }
52
53   public static GlobalSearchScope directoryScope(@NotNull PsiDirectory directory, final boolean withSubdirectories) {
54     return new DirectoryScope(directory, withSubdirectories);
55   }
56
57   public static GlobalSearchScope directoryScope(@NotNull Project project, @NotNull VirtualFile directory, final boolean withSubdirectories) {
58     return new DirectoryScope(project, directory, withSubdirectories);
59   }
60
61   public static GlobalSearchScope fileScope(@NotNull PsiFile psiFile) {
62     return new FileScope(psiFile.getProject(), psiFile.getVirtualFile());
63   }
64
65   public static GlobalSearchScope fileScope(final Project project, final VirtualFile virtualFile) {
66     return new FileScope(project, virtualFile);
67   }
68
69   public static GlobalSearchScope filesScope(final Project project, final Collection<VirtualFile> files) {
70     if (files.isEmpty()) return GlobalSearchScope.EMPTY_SCOPE;
71     return files.size() == 1? fileScope(project, files.iterator().next()) : new FilesScope(project, files);
72   }
73
74   private static class FilterScopeAdapter extends GlobalSearchScope {
75     private final NamedScope mySet;
76     private final PsiManager myManager;
77
78     private FilterScopeAdapter(@NotNull Project project, @NotNull NamedScope set) {
79       super(project);
80       mySet = set;
81       myManager = PsiManager.getInstance(project);
82     }
83
84     public boolean contains(VirtualFile file) {
85       NamedScopesHolder holder = NamedScopeManager.getInstance(getProject());
86       final PackageSet packageSet = mySet.getValue();
87       if (packageSet != null) {
88         if (packageSet instanceof PackageSetBase) return ((PackageSetBase)packageSet).contains(file, holder);
89         PsiFile psiFile = myManager.findFile(file);
90         if (psiFile == null) return false;
91         return packageSet.contains(psiFile, holder);
92       }
93       return false;
94     }
95
96     public String getDisplayName() {
97       return mySet.getName();
98     }
99
100     public int compare(VirtualFile file1, VirtualFile file2) {
101       return 0;
102
103     }
104
105     public boolean isSearchInModuleContent(@NotNull Module aModule) {
106       return true; //TODO (optimization?)
107     }
108
109     public boolean isSearchInLibraries() {
110       return true; //TODO (optimization?)
111     }
112   }
113
114   public static GlobalSearchScope filterScope(@NotNull Project project, @NotNull NamedScope set) {
115     return new FilterScopeAdapter(project, set);
116   }
117
118   private static class ProductionScopeFilter extends GlobalSearchScope {
119     private final ProjectFileIndex myFileIndex;
120
121     private ProductionScopeFilter(@NotNull Project project) {
122       super(project);
123       myFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
124     }
125
126     public boolean contains(VirtualFile file) {
127       return myFileIndex.isInSourceContent(file) && !myFileIndex.isInTestSourceContent(file);
128     }
129
130     public int compare(VirtualFile file1, VirtualFile file2) {
131       return 0;
132     }
133
134     public boolean isSearchInModuleContent(@NotNull Module aModule) {
135       return true;
136     }
137
138     public boolean isSearchInModuleContent(@NotNull final Module aModule, final boolean testSources) {
139       return !testSources;
140     }
141
142     public boolean isSearchInLibraries() {
143       return false;
144     }
145   }
146
147   private static class TestScopeFilter extends GlobalSearchScope {
148     private final ProjectFileIndex myFileIndex;
149
150     private TestScopeFilter(@NotNull Project project) {
151       super(project);
152       myFileIndex = ProjectRootManager.getInstance(project).getFileIndex();
153     }
154
155     public boolean contains(VirtualFile file) {
156       return myFileIndex.isInTestSourceContent(file);
157     }
158
159     public int compare(VirtualFile file1, VirtualFile file2) {
160       return 0;
161     }
162
163     public boolean isSearchInModuleContent(@NotNull Module aModule) {
164       return true;
165     }
166
167     public boolean isSearchInModuleContent(@NotNull final Module aModule, final boolean testSources) {
168       return testSources;
169     }
170
171     public boolean isSearchInLibraries() {
172       return false;
173     }
174   }
175
176   private static class DirectoryScope extends GlobalSearchScope {
177     private final VirtualFile myDirectory;
178     private final boolean myWithSubdirectories;
179
180     private DirectoryScope(@NotNull PsiDirectory directory, final boolean withSubdirectories) {
181       super(directory.getProject());
182       myWithSubdirectories = withSubdirectories;
183       myDirectory = directory.getVirtualFile();
184     }
185
186     private DirectoryScope(@NotNull Project project, @NotNull VirtualFile directory, final boolean withSubdirectories) {
187       super(project);
188       myWithSubdirectories = withSubdirectories;
189       myDirectory = directory;
190     }
191
192     public boolean contains(VirtualFile file) {
193       if (myWithSubdirectories) {
194         return VfsUtilCore.isAncestor(myDirectory, file, false);
195       }
196       else {
197         return myDirectory.equals(file.getParent());
198       }
199     }
200
201     public int compare(VirtualFile file1, VirtualFile file2) {
202       return 0;
203     }
204
205     public boolean isSearchInModuleContent(@NotNull Module aModule) {
206       return true;
207     }
208
209     public boolean isSearchInLibraries() {
210       return false;
211     }
212
213     public String toString() {
214       //noinspection HardCodedStringLiteral
215       return "directory scope: " + myDirectory + "; withSubdirs:"+myWithSubdirectories;
216     }
217   }
218
219   private static class FileScope extends GlobalSearchScope {
220     private final VirtualFile myVirtualFile;
221     private final Module myModule;
222
223     private FileScope(final Project project, final VirtualFile virtualFile) {
224       super(project);
225       myVirtualFile = virtualFile;
226       ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
227       myModule = myVirtualFile != null ? fileIndex.getModuleForFile(myVirtualFile) : null;
228     }
229
230     public boolean contains(VirtualFile file) {
231       return Comparing.equal(myVirtualFile, file);
232     }
233
234     public int compare(VirtualFile file1, VirtualFile file2) {
235       return 0;
236     }
237
238     public boolean isSearchInModuleContent(@NotNull Module aModule) {
239       return aModule == myModule;
240     }
241
242     public boolean isSearchInLibraries() {
243       return myModule == null;
244     }
245   }
246
247   private static class FilesScope extends GlobalSearchScope {
248     private final Collection<VirtualFile> myFiles;
249
250     public FilesScope(final Project project, final Collection<VirtualFile> files) {
251       super(project);
252       myFiles = files;
253     }
254
255     @Override
256     public boolean contains(final VirtualFile file) {
257       return myFiles.contains(file);
258     }
259
260     @Override
261     public int compare(final VirtualFile file1, final VirtualFile file2) {
262       return 0;
263     }
264
265     @Override
266     public boolean isSearchInModuleContent(@NotNull Module aModule) {
267       return true;
268     }
269
270     @Override
271     public boolean isSearchInLibraries() {
272       return false;
273     }
274
275     @Override
276     public boolean equals(Object o) {
277       if (this == o) return true;
278       if (!(o instanceof FilesScope)) return false;
279
280       return myFiles.equals(((FilesScope)o).myFiles);
281     }
282
283     @Override
284     public int hashCode() {
285       return myFiles.hashCode();
286     }
287   }
288 }