From 0aabd5399938895ab5b210ac9533b7cb37ec3fdc Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Tue, 2 Apr 2019 20:34:46 +0300 Subject: [PATCH] DBE-8080 Introduce All Data Sources and per-Data Source search scopes --- .../psi/search/SearchScopeProvider.java | 21 +++- .../util/scopeChooser/ScopeChooserCombo.java | 41 ++----- .../search/DefaultSearchScopeProviders.java | 112 ++++++++++++++++++ .../PredefinedSearchScopeProviderImpl.java | 39 +----- .../src/META-INF/LangExtensionPoints.xml | 2 +- .../src/META-INF/LangExtensions.xml | 5 + 6 files changed, 151 insertions(+), 69 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/psi/search/DefaultSearchScopeProviders.java diff --git a/platform/analysis-impl/src/com/intellij/psi/search/SearchScopeProvider.java b/platform/analysis-impl/src/com/intellij/psi/search/SearchScopeProvider.java index aedcbac7c864..d131f762cbce 100644 --- a/platform/analysis-impl/src/com/intellij/psi/search/SearchScopeProvider.java +++ b/platform/analysis-impl/src/com/intellij/psi/search/SearchScopeProvider.java @@ -2,15 +2,32 @@ package com.intellij.psi.search; import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.List; public interface SearchScopeProvider { - ExtensionPointName EP = ExtensionPointName.create("com.intellij.searchScopesProvider"); + ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.searchScopesProvider"); + + @Nullable + default String getDisplayName() { + return null; + } + + @NotNull + default List getSearchScopes(@NotNull Project project) { + return Collections.emptyList(); + } /** * General project scopes are added after 'Project', 'Everything' but before 'Production', 'Tests', etc. * @see PredefinedSearchScopeProvider + * @param project */ - List getGeneralProjectScopes(); + default List getGeneralSearchScopes(@NotNull Project project) { + return Collections.emptyList(); + } } diff --git a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java index b2334620889d..fe8c49ad973f 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java +++ b/platform/lang-impl/src/com/intellij/ide/util/scopeChooser/ScopeChooserCombo.java @@ -7,18 +7,18 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; import com.intellij.openapi.util.Condition; -import com.intellij.packageDependencies.ChangeListsScopesProvider; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.packageDependencies.DependencyValidationManager; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.search.GlobalSearchScopesCore; import com.intellij.psi.search.PredefinedSearchScopeProvider; import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.SearchScopeProvider; import com.intellij.psi.search.scope.packageSet.NamedScope; import com.intellij.psi.search.scope.packageSet.NamedScopeManager; import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; import com.intellij.ui.ComboboxSpeedSearch; import com.intellij.ui.ComboboxWithBrowseButton; import com.intellij.ui.ListCellRendererWrapper; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.awt.event.ActionListener; -import java.util.ArrayList; +import java.util.Comparator; import java.util.List; public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Disposable { @@ -156,35 +156,18 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo @NotNull private DefaultComboBoxModel createModel() { - final DefaultComboBoxModel model = new DefaultComboBoxModel<>(); - + DefaultComboBoxModel model = new DefaultComboBoxModel<>(); createPredefinedScopeDescriptors(model); - final List changeLists = ChangeListsScopesProvider.getInstance(myProject).getFilteredScopes(); - if (!changeLists.isEmpty()) { - model.addElement(new ScopeSeparator("VCS Scopes")); - for (NamedScope changeListScope : changeLists) { - final GlobalSearchScope scope = GlobalSearchScopesCore.filterScope(myProject, changeListScope); - addScopeDescriptor(model, new ScopeDescriptor(scope)); + for (SearchScopeProvider each : SearchScopeProvider.EP_NAME.getExtensions()) { + if (StringUtil.isEmpty(each.getDisplayName())) continue; + List scopes = each.getSearchScopes(myProject); + if (scopes.isEmpty()) continue; + model.addElement(new ScopeSeparator(each.getDisplayName())); + for (SearchScope scope : ContainerUtil.sorted(scopes, Comparator.comparing(SearchScope::getDisplayName))) { + model.addElement(new ScopeDescriptor(scope)); } } - - final List customScopes = new ArrayList<>(); - final NamedScopesHolder[] holders = NamedScopesHolder.getAllNamedScopeHolders(myProject); - for (NamedScopesHolder holder : holders) { - final NamedScope[] scopes = holder.getEditableScopes(); // predefined scopes already included - for (NamedScope scope : scopes) { - final GlobalSearchScope searchScope = GlobalSearchScopesCore.filterScope(myProject, scope); - customScopes.add(new ScopeDescriptor(searchScope)); - } - } - if (!customScopes.isEmpty()) { - model.addElement(new ScopeSeparator("Custom Scopes")); - for (ScopeDescriptor scope : customScopes) { - addScopeDescriptor(model, scope); - } - } - return model; } diff --git a/platform/lang-impl/src/com/intellij/psi/search/DefaultSearchScopeProviders.java b/platform/lang-impl/src/com/intellij/psi/search/DefaultSearchScopeProviders.java new file mode 100644 index 000000000000..a125e4c8a98b --- /dev/null +++ b/platform/lang-impl/src/com/intellij/psi/search/DefaultSearchScopeProviders.java @@ -0,0 +1,112 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.psi.search; + +import com.intellij.ide.favoritesTreeView.FavoritesManager; +import com.intellij.ide.projectView.impl.AbstractUrl; +import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.packageDependencies.ChangeListsScopesProvider; +import com.intellij.psi.search.scope.packageSet.NamedScope; +import com.intellij.psi.search.scope.packageSet.NamedScopesHolder; +import com.intellij.util.TreeItem; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * @author gregsh + */ +public class DefaultSearchScopeProviders { + private DefaultSearchScopeProviders() {} + + public static class Favorites implements SearchScopeProvider { + @Override + public String getDisplayName() { + return "Favorites"; + } + + @NotNull + @Override + public List getSearchScopes(@NotNull Project project) { + FavoritesManager favoritesManager = FavoritesManager.getInstance(project); + if (favoritesManager == null) return Collections.emptyList(); + List result = new ArrayList<>(); + for (String favorite : favoritesManager.getAvailableFavoritesListNames()) { + Collection>> 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 VirtualFile file) { + return ReadAction.compute(() -> favoritesManager.contains(favorite, file)); + } + + @Override + public boolean isSearchInModuleContent(@NotNull Module aModule) { + return true; + } + + @Override + public boolean isSearchInLibraries() { + return true; + } + }); + } + return result; + } + } + + public static class ChangeLists implements SearchScopeProvider { + @Override + public String getDisplayName() { + return "Local Changes"; + } + + @NotNull + @Override + public List getSearchScopes(@NotNull Project project) { + List result = new ArrayList<>(); + List changeLists = ChangeListsScopesProvider.getInstance(project).getFilteredScopes(); + if (!changeLists.isEmpty()) { + for (NamedScope changeListScope : changeLists) { + GlobalSearchScope scope = GlobalSearchScopesCore.filterScope(project, changeListScope); + result.add(scope); + } + } + return result; + } + } + + public static class CustomNamed implements SearchScopeProvider { + @Override + public String getDisplayName() { + return "Other"; + } + + @NotNull + @Override + public List getSearchScopes(@NotNull Project project) { + List result = new ArrayList<>(); + NamedScopesHolder[] holders = NamedScopesHolder.getAllNamedScopeHolders(project); + for (NamedScopesHolder holder : holders) { + NamedScope[] scopes = holder.getEditableScopes(); // predefined scopes already included + for (NamedScope scope : scopes) { + GlobalSearchScope searchScope = GlobalSearchScopesCore.filterScope(project, scope); + result.add(searchScope); + } + } + return result; + } + } +} diff --git a/platform/lang-impl/src/com/intellij/psi/search/PredefinedSearchScopeProviderImpl.java b/platform/lang-impl/src/com/intellij/psi/search/PredefinedSearchScopeProviderImpl.java index 3ad483131d13..16f43c741604 100644 --- a/platform/lang-impl/src/com/intellij/psi/search/PredefinedSearchScopeProviderImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/search/PredefinedSearchScopeProviderImpl.java @@ -2,22 +2,18 @@ package com.intellij.psi.search; import com.intellij.ide.IdeBundle; -import com.intellij.ide.favoritesTreeView.FavoritesManager; import com.intellij.ide.hierarchy.HierarchyBrowserBase; -import com.intellij.ide.projectView.impl.AbstractUrl; import com.intellij.ide.scratch.ScratchesSearchScope; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.module.*; import com.intellij.openapi.project.DumbUnawareHider; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindow; @@ -36,7 +32,6 @@ import com.intellij.usages.UsageView; import com.intellij.usages.UsageViewManager; import com.intellij.usages.rules.PsiElementUsage; import com.intellij.util.PlatformUtils; -import com.intellij.util.TreeItem; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -62,8 +57,8 @@ public class PredefinedSearchScopeProviderImpl extends PredefinedSearchScopeProv result.add(GlobalSearchScope.allScope(project)); } - for (SearchScopeProvider each : SearchScopeProvider.EP.getExtensions(project)) { - result.addAll(each.getGeneralProjectScopes()); + for (SearchScopeProvider each : SearchScopeProvider.EP_NAME.getExtensions()) { + result.addAll(each.getGeneralSearchScopes(project)); } if (ModuleUtil.hasTestSourceRoots(project)) { @@ -207,36 +202,6 @@ public class PredefinedSearchScopeProviderImpl extends PredefinedSearchScopeProv } } - final FavoritesManager favoritesManager = FavoritesManager.getInstance(project); - if (favoritesManager != null) { - for (final String favorite : favoritesManager.getAvailableFavoritesListNames()) { - final Collection>> 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 ReadAction.compute(() -> favoritesManager.contains(favorite, file)); - } - - @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); diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 2a4bcec1ad1a..3380b1e7f27e 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -267,7 +267,7 @@ - + diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 17b06018313b..b8300ec15cb5 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -502,6 +502,11 @@ + + + + +