private IntersectionScope(
     @NotNull GlobalSearchScope scope1, @NotNull GlobalSearchScope scope2, String displayName) {
   super(scope1.getProject() == null ? scope2.getProject() : scope1.getProject());
   myScope1 = scope1;
   myScope2 = scope2;
   myDisplayName = displayName;
 }
 private boolean containsScope(@NotNull GlobalSearchScope scope) {
   if (myScope1.equals(scope) || myScope2.equals(scope) || equals(scope)) return true;
   if (myScope1 instanceof IntersectionScope
       && ((IntersectionScope) myScope1).containsScope(scope)) return true;
   if (myScope2 instanceof IntersectionScope
       && ((IntersectionScope) myScope2).containsScope(scope)) return true;
   return false;
 }
    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof IntersectionScope)) return false;

      IntersectionScope that = (IntersectionScope) o;

      return myScope1.equals(that.myScope1) && myScope2.equals(that.myScope2);
    }
 @NotNull
 @Override
 public String getDisplayName() {
   if (myDisplayName == null) {
     return PsiBundle.message(
         "psi.search.scope.intersection", myScope1.getDisplayName(), myScope2.getDisplayName());
   }
   return myDisplayName;
 }
    @Override
    public int compare(@NotNull VirtualFile file1, @NotNull VirtualFile file2) {
      int res1 = myScope1.compare(file1, file2);
      int res2 = myScope2.compare(file1, file2);

      if (res1 == 0) return res2;
      if (res2 == 0) return res1;

      res1 /= Math.abs(res1);
      res2 /= Math.abs(res2);
      if (res1 == res2) return res1;

      return 0;
    }
 @NotNull
 static SearchScope getScopeFromModel(@NotNull Project project, @NotNull FindModel findModel) {
   SearchScope customScope = findModel.getCustomScope();
   VirtualFile directory = getDirectory(findModel);
   Module module =
       findModel.getModuleName() == null
           ? null
           : ModuleManager.getInstance(project).findModuleByName(findModel.getModuleName());
   return findModel.isCustomScope() && customScope != null
       ? customScope.intersectWith(GlobalSearchScope.allScope(project))
       :
       // we don't have to check for myProjectFileIndex.isExcluded(file) here like
       // FindInProjectTask.collectFilesInScope() does
       // because all found usages are guaranteed to be not in excluded dir
       directory != null
           ? forDirectory(project, findModel.isWithSubdirectories(), directory)
           : module != null
               ? module.getModuleContentScope()
               : findModel.isProjectScope()
                   ? ProjectScope.getContentScope(project)
                   : GlobalSearchScope.allScope(project);
 }
Пример #7
0
 @Nullable
 private static SearchScope getSelectedFilesScope(
     final Project project, @Nullable DataContext dataContext) {
   final VirtualFile[] filesOrDirs =
       dataContext == null ? null : CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
   if (filesOrDirs != null) {
     final List<VirtualFile> selectedFiles =
         ContainerUtil.filter(filesOrDirs, file -> !file.isDirectory());
     if (!selectedFiles.isEmpty()) {
       return GlobalSearchScope.filesScope(project, selectedFiles, "Selected Files");
     }
   }
   return null;
 }
Пример #8
0
  @NotNull
  @Override
  public List<SearchScope> getPredefinedScopes(
      @NotNull final Project project,
      @Nullable final DataContext dataContext,
      boolean suggestSearchInLibs,
      boolean prevSearchFiles,
      boolean currentSelection,
      boolean usageView,
      boolean showEmptyScopes) {
    Collection<SearchScope> result = ContainerUtil.newLinkedHashSet();
    result.add(GlobalSearchScope.projectScope(project));
    if (suggestSearchInLibs) {
      result.add(GlobalSearchScope.allScope(project));
    }

    if (ModuleUtil.isSupportedRootType(project, JavaSourceRootType.TEST_SOURCE)) {
      result.add(GlobalSearchScopesCore.projectProductionScope(project));
      result.add(GlobalSearchScopesCore.projectTestScope(project));
    }

    final GlobalSearchScope openFilesScope = GlobalSearchScopes.openFilesScope(project);
    if (openFilesScope != GlobalSearchScope.EMPTY_SCOPE) {
      result.add(openFilesScope);
    } else if (showEmptyScopes) {
      result.add(
          new LocalSearchScope(PsiElement.EMPTY_ARRAY, IdeBundle.message("scope.open.files")));
    }

    final Editor selectedTextEditor =
        ApplicationManager.getApplication().isDispatchThread()
            ? FileEditorManager.getInstance(project).getSelectedTextEditor()
            : null;
    final PsiFile psiFile =
        (selectedTextEditor != null)
            ? PsiDocumentManager.getInstance(project).getPsiFile(selectedTextEditor.getDocument())
            : null;
    PsiFile currentFile = psiFile;

    if (dataContext != null) {
      PsiElement dataContextElement = CommonDataKeys.PSI_FILE.getData(dataContext);
      if (dataContextElement == null) {
        dataContextElement = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
      }

      if (dataContextElement == null && psiFile != null) {
        dataContextElement = psiFile;
      }

      if (dataContextElement != null) {
        if (!PlatformUtils.isCidr()) { // TODO: have an API to disable module scopes.
          Module module = ModuleUtilCore.findModuleForPsiElement(dataContextElement);
          if (module == null) {
            module = LangDataKeys.MODULE.getData(dataContext);
          }
          if (module != null && !(ModuleType.get(module) instanceof InternalModuleType)) {
            result.add(module.getModuleScope());
          }
        }
        if (currentFile == null) {
          currentFile = dataContextElement.getContainingFile();
        }
      }
    }

    if (currentFile != null || showEmptyScopes) {
      PsiElement[] scope =
          currentFile != null ? new PsiElement[] {currentFile} : PsiElement.EMPTY_ARRAY;
      result.add(new LocalSearchScope(scope, IdeBundle.message("scope.current.file")));
    }

    if (currentSelection && selectedTextEditor != null && psiFile != null) {
      SelectionModel selectionModel = selectedTextEditor.getSelectionModel();
      if (selectionModel.hasSelection()) {
        int start = selectionModel.getSelectionStart();
        final PsiElement startElement = psiFile.findElementAt(start);
        if (startElement != null) {
          int end = selectionModel.getSelectionEnd();
          final PsiElement endElement = psiFile.findElementAt(end);
          if (endElement != null) {
            final PsiElement parent = PsiTreeUtil.findCommonParent(startElement, endElement);
            if (parent != null) {
              final List<PsiElement> elements = new ArrayList<PsiElement>();
              final PsiElement[] children = parent.getChildren();
              TextRange selection = new TextRange(start, end);
              for (PsiElement child : children) {
                if (!(child instanceof PsiWhiteSpace)
                    && child.getContainingFile() != null
                    && selection.contains(child.getTextOffset())) {
                  elements.add(child);
                }
              }
              if (!elements.isEmpty()) {
                SearchScope local =
                    new LocalSearchScope(
                        PsiUtilCore.toPsiElementArray(elements),
                        IdeBundle.message("scope.selection"));
                result.add(local);
              }
            }
          }
        }
      }
    }

    if (usageView) {
      addHierarchyScope(project, result);
      UsageView selectedUsageView = UsageViewManager.getInstance(project).getSelectedUsageView();
      if (selectedUsageView != null && !selectedUsageView.isSearchInProgress()) {
        final Set<Usage> usages = ContainerUtil.newTroveSet(selectedUsageView.getUsages());
        usages.removeAll(selectedUsageView.getExcludedUsages());
        final List<PsiElement> results = new ArrayList<PsiElement>(usages.size());

        if (prevSearchFiles) {
          final Set<VirtualFile> files = collectFiles(usages, true);
          if (!files.isEmpty()) {
            GlobalSearchScope prev =
                new GlobalSearchScope(project) {
                  private Set<VirtualFile> myFiles = null;

                  @NotNull
                  @Override
                  public String getDisplayName() {
                    return IdeBundle.message("scope.files.in.previous.search.result");
                  }

                  @Override
                  public synchronized boolean contains(@NotNull VirtualFile file) {
                    if (myFiles == null) {
                      myFiles = collectFiles(usages, false);
                    }
                    return myFiles.contains(file);
                  }

                  @Override
                  public int compare(@NotNull VirtualFile file1, @NotNull VirtualFile file2) {
                    return 0;
                  }

                  @Override
                  public boolean isSearchInModuleContent(@NotNull Module aModule) {
                    return true;
                  }

                  @Override
                  public boolean isSearchInLibraries() {
                    return true;
                  }
                };
            result.add(prev);
          }
        } else {
          for (Usage usage : usages) {
            if (usage instanceof PsiElementUsage) {
              final PsiElement element = ((PsiElementUsage) usage).getElement();
              if (element != null && element.isValid() && element.getContainingFile() != null) {
                results.add(element);
              }
            }
          }

          if (!results.isEmpty()) {
            result.add(
                new LocalSearchScope(
                    PsiUtilCore.toPsiElementArray(results),
                    IdeBundle.message("scope.previous.search.results")));
          }
        }
      }
    }

    final FavoritesManager favoritesManager = FavoritesManager.getInstance(project);
    if (favoritesManager != null) {
      for (final String favorite : favoritesManager.getAvailableFavoritesListNames()) {
        final Collection<TreeItem<Pair<AbstractUrl, String>>> rootUrls =
            favoritesManager.getFavoritesListRootUrls(favorite);
        if (rootUrls.isEmpty()) continue; // ignore unused root
        result.add(
            new GlobalSearchScope(project) {
              @NotNull
              @Override
              public String getDisplayName() {
                return "Favorite \'" + favorite + "\'";
              }

              @Override
              public boolean contains(@NotNull final VirtualFile file) {
                return ApplicationManager.getApplication()
                    .runReadAction(
                        (Computable<Boolean>) () -> favoritesManager.contains(favorite, file));
              }

              @Override
              public int compare(
                  @NotNull final VirtualFile file1, @NotNull final VirtualFile file2) {
                return 0;
              }

              @Override
              public boolean isSearchInModuleContent(@NotNull final Module aModule) {
                return true;
              }

              @Override
              public boolean isSearchInLibraries() {
                return true;
              }
            });
      }
    }

    ContainerUtil.addIfNotNull(result, getSelectedFilesScope(project, dataContext));

    return ContainerUtil.newArrayList(result);
  }
  @NotNull
  private Collection<PsiFile> collectFilesInScope(
      @NotNull final Set<PsiFile> alreadySearched, final boolean skipIndexed) {
    SearchScope customScope = myFindModel.getCustomScope();
    final GlobalSearchScope globalCustomScope = toGlobal(customScope);

    final ProjectFileIndex fileIndex = ProjectFileIndex.SERVICE.getInstance(myProject);
    final boolean hasTrigrams = hasTrigrams(myFindModel.getStringToFind());

    class EnumContentIterator implements ContentIterator {
      final Set<PsiFile> myFiles = new LinkedHashSet<PsiFile>();

      @Override
      public boolean processFile(@NotNull final VirtualFile virtualFile) {
        ApplicationManager.getApplication()
            .runReadAction(
                new Runnable() {
                  @Override
                  public void run() {
                    ProgressManager.checkCanceled();
                    if (virtualFile.isDirectory()
                        || !virtualFile.isValid()
                        || !myFileMask.value(virtualFile)
                        || globalCustomScope != null && !globalCustomScope.contains(virtualFile)) {
                      return;
                    }

                    if (skipIndexed
                        && isCoveredByIndex(virtualFile)
                        && (fileIndex.isInContent(virtualFile)
                            || fileIndex.isInLibraryClasses(virtualFile)
                            || fileIndex.isInLibrarySource(virtualFile))) {
                      return;
                    }

                    PsiFile psiFile = myPsiManager.findFile(virtualFile);
                    if (psiFile != null
                        && !(psiFile instanceof PsiBinaryFile)
                        && !alreadySearched.contains(psiFile)) {
                      PsiFile sourceFile = (PsiFile) psiFile.getNavigationElement();
                      if (sourceFile != null) psiFile = sourceFile;
                      if (!psiFile.getFileType().isBinary()) {
                        myFiles.add(psiFile);
                      }
                    }
                  }

                  final FileBasedIndexImpl fileBasedIndex =
                      (FileBasedIndexImpl) FileBasedIndex.getInstance();

                  private boolean isCoveredByIndex(VirtualFile file) {
                    FileType fileType = file.getFileType();
                    if (hasTrigrams) {
                      return TrigramIndex.isIndexable(fileType)
                          && fileBasedIndex.isIndexingCandidate(file, TrigramIndex.INDEX_ID);
                    }
                    return IdIndex.isIndexable(fileType)
                        && fileBasedIndex.isIndexingCandidate(file, IdIndex.NAME);
                  }
                });
        return true;
      }

      @NotNull
      private Collection<PsiFile> getFiles() {
        return myFiles;
      }
    }

    final EnumContentIterator iterator = new EnumContentIterator();

    if (customScope instanceof LocalSearchScope) {
      for (VirtualFile file : getLocalScopeFiles((LocalSearchScope) customScope)) {
        iterator.processFile(file);
      }
    } else if (customScope
        instanceof
        Iterable) { // GlobalSearchScope can span files out of project roots e.g. FileScope /
                    // FilesScope
      //noinspection unchecked
      for (VirtualFile file : (Iterable<VirtualFile>) customScope) {
        iterator.processFile(file);
      }
    } else if (myPsiDirectory != null) {
      ApplicationManager.getApplication()
          .runReadAction(
              new Runnable() {
                @Override
                public void run() {
                  if (myPsiDirectory.isValid()) {
                    addFilesUnderDirectory(myPsiDirectory, iterator);
                  }
                }
              });

      myFileIndex.iterateContentUnderDirectory(myPsiDirectory.getVirtualFile(), iterator);
    } else {
      boolean success = myFileIndex.iterateContent(iterator);
      if (success && globalCustomScope != null && globalCustomScope.isSearchInLibraries()) {
        final VirtualFile[] librarySources =
            ApplicationManager.getApplication()
                .runReadAction(
                    new Computable<VirtualFile[]>() {
                      @Override
                      public VirtualFile[] compute() {
                        OrderEnumerator enumerator =
                            myModule == null
                                ? OrderEnumerator.orderEntries(myProject)
                                : OrderEnumerator.orderEntries(myModule);
                        return enumerator
                            .withoutModuleSourceEntries()
                            .withoutDepModules()
                            .getSourceRoots();
                      }
                    });
        iterateAll(librarySources, globalCustomScope, iterator);
      }
    }
    return iterator.getFiles();
  }
  public static List<SearchScope> getPredefinedScopes(
      @NotNull final Project project,
      @Nullable final DataContext dataContext,
      boolean suggestSearchInLibs,
      boolean prevSearchFiles,
      boolean currentSelection,
      boolean usageView) {
    ArrayList<SearchScope> result = new ArrayList<SearchScope>();
    result.add(GlobalSearchScope.projectScope(project));
    if (suggestSearchInLibs) {
      result.add(GlobalSearchScope.allScope(project));
    }

    if (!PlatformUtils.isCidr()
        && ModuleUtil.isSupportedRootType(
            project, JavaSourceRootType.TEST_SOURCE)) { // TODO: fix these scopes in AppCode
      result.add(GlobalSearchScopes.projectProductionScope(project));
      result.add(GlobalSearchScopes.projectTestScope(project));
    }

    result.add(GlobalSearchScopes.openFilesScope(project));

    if (dataContext != null) {
      PsiElement dataContextElement = CommonDataKeys.PSI_FILE.getData(dataContext);
      if (dataContextElement == null) {
        dataContextElement = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
      }
      if (dataContextElement != null) {
        if (!PlatformUtils.isCidr()) { // TODO: have an API to disable module scopes.
          Module module = ModuleUtilCore.findModuleForPsiElement(dataContextElement);
          if (module == null) {
            module = LangDataKeys.MODULE.getData(dataContext);
          }
          if (module != null) {
            result.add(module.getModuleScope());
          }
        }
        if (dataContextElement.getContainingFile() != null) {
          result.add(
              new LocalSearchScope(dataContextElement, IdeBundle.message("scope.current.file")));
        }
      }
    }

    if (currentSelection) {
      FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
      final Editor selectedTextEditor = fileEditorManager.getSelectedTextEditor();
      if (selectedTextEditor != null) {
        final PsiFile psiFile =
            PsiDocumentManager.getInstance(project).getPsiFile(selectedTextEditor.getDocument());
        if (psiFile != null) {
          if (selectedTextEditor.getSelectionModel().hasSelection()) {
            final PsiElement startElement =
                psiFile.findElementAt(selectedTextEditor.getSelectionModel().getSelectionStart());
            if (startElement != null) {
              final PsiElement endElement =
                  psiFile.findElementAt(selectedTextEditor.getSelectionModel().getSelectionEnd());
              if (endElement != null) {
                final PsiElement parent = PsiTreeUtil.findCommonParent(startElement, endElement);
                if (parent != null) {
                  final List<PsiElement> elements = new ArrayList<PsiElement>();
                  final PsiElement[] children = parent.getChildren();
                  for (PsiElement child : children) {
                    if (!(child instanceof PsiWhiteSpace) && child.getContainingFile() != null) {
                      elements.add(child);
                    }
                  }
                  if (!elements.isEmpty()) {
                    SearchScope local =
                        new LocalSearchScope(
                            PsiUtilCore.toPsiElementArray(elements),
                            IdeBundle.message("scope.selection"));
                    result.add(local);
                  }
                }
              }
            }
          }
        }
      }
    }

    if (usageView) {
      UsageView selectedUsageView = UsageViewManager.getInstance(project).getSelectedUsageView();
      if (selectedUsageView != null && !selectedUsageView.isSearchInProgress()) {
        final Set<Usage> usages = selectedUsageView.getUsages();
        final List<PsiElement> results = new ArrayList<PsiElement>(usages.size());

        if (prevSearchFiles) {
          final Set<VirtualFile> files = new HashSet<VirtualFile>();
          for (Usage usage : usages) {
            if (usage instanceof PsiElementUsage) {
              PsiElement psiElement = ((PsiElementUsage) usage).getElement();
              if (psiElement != null && psiElement.isValid()) {
                PsiFile psiFile = psiElement.getContainingFile();
                if (psiFile != null) {
                  VirtualFile file = psiFile.getVirtualFile();
                  if (file != null) files.add(file);
                }
              }
            }
          }
          if (!files.isEmpty()) {
            GlobalSearchScope prev =
                new GlobalSearchScope(project) {
                  @Override
                  public String getDisplayName() {
                    return IdeBundle.message("scope.files.in.previous.search.result");
                  }

                  @Override
                  public boolean contains(@NotNull VirtualFile file) {
                    return files.contains(file);
                  }

                  @Override
                  public int compare(@NotNull VirtualFile file1, @NotNull VirtualFile file2) {
                    return 0;
                  }

                  @Override
                  public boolean isSearchInModuleContent(@NotNull Module aModule) {
                    return true;
                  }

                  @Override
                  public boolean isSearchInLibraries() {
                    return true;
                  }
                };
            result.add(prev);
          }
        } else {
          for (Usage usage : usages) {
            if (usage instanceof PsiElementUsage) {
              final PsiElement element = ((PsiElementUsage) usage).getElement();
              if (element != null && element.isValid() && element.getContainingFile() != null) {
                results.add(element);
              }
            }
          }

          if (!results.isEmpty()) {
            result.add(
                new LocalSearchScope(
                    PsiUtilCore.toPsiElementArray(results),
                    IdeBundle.message("scope.previous.search.results")));
          }
        }
      }
    }

    final FavoritesManager favoritesManager = FavoritesManager.getInstance(project);
    if (favoritesManager != null) {
      for (final String favorite : favoritesManager.getAvailableFavoritesListNames()) {
        final Collection<TreeItem<Pair<AbstractUrl, String>>> rootUrls =
            favoritesManager.getFavoritesListRootUrls(favorite);
        if (rootUrls.isEmpty()) continue; // ignore unused root
        result.add(
            new GlobalSearchScope(project) {
              @Override
              public String getDisplayName() {
                return "Favorite \'" + favorite + "\'";
              }

              @Override
              public boolean contains(@NotNull final VirtualFile file) {
                return favoritesManager.contains(favorite, file);
              }

              @Override
              public int compare(
                  @NotNull final VirtualFile file1, @NotNull final VirtualFile file2) {
                return 0;
              }

              @Override
              public boolean isSearchInModuleContent(@NotNull final Module aModule) {
                return true;
              }

              @Override
              public boolean isSearchInLibraries() {
                return true;
              }
            });
      }
    }

    if (dataContext != null) {
      final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
      if (files != null) {
        final List<VirtualFile> openFiles = Arrays.asList(files);
        result.add(
            new DelegatingGlobalSearchScope(GlobalSearchScope.filesScope(project, openFiles)) {
              @Override
              public String getDisplayName() {
                return "Selected Files";
              }
            });
      }
    }

    return result;
  }
 @Override
 public int hashCode() {
   return 31 * myScope1.hashCode() + myScope2.hashCode();
 }
 @Override
 public boolean isSearchOutsideRootModel() {
   return myScope1.isSearchOutsideRootModel() && myScope2.isSearchOutsideRootModel();
 }
 @Override
 public boolean isSearchInLibraries() {
   return myScope1.isSearchInLibraries() && myScope2.isSearchInLibraries();
 }
 @Override
 public boolean isSearchInModuleContent(
     @NotNull final Module aModule, final boolean testSources) {
   return myScope1.isSearchInModuleContent(aModule, testSources)
       && myScope2.isSearchInModuleContent(aModule, testSources);
 }
 @Override
 public boolean isSearchInModuleContent(@NotNull Module aModule) {
   return myScope1.isSearchInModuleContent(aModule) && myScope2.isSearchInModuleContent(aModule);
 }
 @Override
 public boolean contains(@NotNull VirtualFile file) {
   return myScope1.contains(file) && myScope2.contains(file);
 }