optimization: return LocalSearchScope.EMPTY instead of GlobalSearchScope.EMPTY_SCOPE explicitly to avoid unnecessary FileBasedIndex accesses during search

GitOrigin-RevId: b7cf8f4b4dec2f79f2231b97b091cc0ed7978473
This commit is contained in:
Alexey Kudravtsev
2021-09-15 17:09:43 +02:00
committed by intellij-monorepo-bot
parent 480b4a18eb
commit a897b7c13c
17 changed files with 46 additions and 40 deletions

View File

@@ -15,7 +15,6 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import com.intellij.psi.presentation.java.ClassPresentationUtil; import com.intellij.psi.presentation.java.ClassPresentationUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch; import com.intellij.psi.search.searches.ClassInheritorsSearch;
@@ -66,8 +65,9 @@ public class ClassHierarchyScopeDescriptor extends ScopeDescriptor {
PsiClass aClass = chooser.getSelected(); PsiClass aClass = chooser.getSelected();
if (aClass == null) { if (aClass == null) {
myCachedScope = GlobalSearchScope.EMPTY_SCOPE; myCachedScope = LocalSearchScope.EMPTY;
} else { }
else {
final List<PsiElement> classesToSearch = new LinkedList<>(); final List<PsiElement> classesToSearch = new LinkedList<>();
classesToSearch.add(aClass); classesToSearch.add(aClass);

View File

@@ -86,7 +86,7 @@ public final class MethodReferencesSearch extends ExtensibleQueryFactory<PsiRefe
public SearchScope getEffectiveSearchScope () { public SearchScope getEffectiveSearchScope () {
SearchScope scope = myEffectiveScope; SearchScope scope = myEffectiveScope;
if (scope == null) { if (scope == null) {
if (!myMethod.isValid()) return GlobalSearchScope.EMPTY_SCOPE; if (!myMethod.isValid()) return LocalSearchScope.EMPTY;
myEffectiveScope = scope = myScope.intersectWith(PsiSearchHelper.getInstance(myMethod.getProject()).getUseScope(myMethod)); myEffectiveScope = scope = myScope.intersectWith(PsiSearchHelper.getInstance(myMethod.getProject()).getUseScope(myMethod));
} }

View File

@@ -24,7 +24,7 @@ public class AllClassesSearchExecutor implements QueryExecutor<PsiClass, AllClas
public boolean execute(@NotNull final AllClassesSearch.SearchParameters queryParameters, @NotNull final Processor<? super PsiClass> consumer) { public boolean execute(@NotNull final AllClassesSearch.SearchParameters queryParameters, @NotNull final Processor<? super PsiClass> consumer) {
SearchScope scope = queryParameters.getScope(); SearchScope scope = queryParameters.getScope();
if (scope == GlobalSearchScope.EMPTY_SCOPE) { if (SearchScope.isEmptyScope(scope)) {
return true; return true;
} }

View File

@@ -49,6 +49,7 @@ import com.intellij.util.containers.MultiMap;
import com.intellij.util.indexing.FileBasedIndex; import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@@ -59,7 +60,7 @@ public final class JavaFunctionalExpressionSearcher extends QueryExecutorBase<Ps
@Override @Override
public void processQuery(@NotNull SearchParameters p, @NotNull Processor<? super PsiFunctionalExpression> consumer) { public void processQuery(@NotNull SearchParameters p, @NotNull Processor<? super PsiFunctionalExpression> consumer) {
if (ReadAction.compute(() -> p.getEffectiveSearchScope()) == GlobalSearchScope.EMPTY_SCOPE) { if (SearchScope.isEmptyScope(ReadAction.compute(() -> p.getEffectiveSearchScope()))) {
return; return;
} }
Session session = ReadAction.compute(() -> new Session(p, consumer)); Session session = ReadAction.compute(() -> new Session(p, consumer));
@@ -474,7 +475,9 @@ public final class JavaFunctionalExpressionSearcher extends QueryExecutorBase<Ps
scope = parameters.getEffectiveSearchScope(); scope = parameters.getEffectiveSearchScope();
} }
public Set<VirtualFile> getFilesLookedInside() { @NotNull
@TestOnly
Set<VirtualFile> getFilesLookedInside() {
return filesLookedInside; return filesLookedInside;
} }

View File

@@ -44,7 +44,7 @@ public class MethodUsagesSearcher extends QueryExecutorBase<PsiReference, Method
SearchRequestCollector collector = p.getOptimizer(); SearchRequestCollector collector = p.getOptimizer();
SearchScope searchScope = DumbService.getInstance(p.getProject()).runReadActionInSmartMode(p::getEffectiveSearchScope); SearchScope searchScope = DumbService.getInstance(p.getProject()).runReadActionInSmartMode(p::getEffectiveSearchScope);
if (searchScope == GlobalSearchScope.EMPTY_SCOPE) { if (SearchScope.isEmptyScope(searchScope)) {
return; return;
} }

View File

@@ -6,10 +6,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiReference; import com.intellij.psi.PsiReference;
import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.*;
import com.intellij.psi.search.SearchRequestCollector;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.UsageSearchContext;
import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PropertyUtilBase; import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.util.Processor; import com.intellij.util.Processor;
@@ -34,7 +31,7 @@ public class SimpleAccessorReferenceSearcher extends QueryExecutorBase<PsiRefere
static void addPropertyAccessUsages(@NotNull PsiMethod method, @NotNull SearchScope scope, @NotNull SearchRequestCollector collector) { static void addPropertyAccessUsages(@NotNull PsiMethod method, @NotNull SearchScope scope, @NotNull SearchRequestCollector collector) {
final String propertyName = PropertyUtilBase.getPropertyName(method); final String propertyName = PropertyUtilBase.getPropertyName(method);
if (StringUtil.isNotEmpty(propertyName)) { if (StringUtil.isNotEmpty(propertyName)) {
SearchScope additional = GlobalSearchScope.EMPTY_SCOPE; SearchScope additional = LocalSearchScope.EMPTY;
for (CustomPropertyScopeProvider provider : CustomPropertyScopeProvider.EP_NAME.getExtensionList()) { for (CustomPropertyScopeProvider provider : CustomPropertyScopeProvider.EP_NAME.getExtensionList()) {
additional = additional.union(provider.getScope(method.getProject())); additional = additional.union(provider.getScope(method.getProject()));
} }

View File

@@ -683,7 +683,7 @@ public class AnalysisScope {
case FILE: case FILE:
return GlobalSearchScope.fileScope((PsiFile)myElement); return GlobalSearchScope.fileScope((PsiFile)myElement);
case INVALID: case INVALID:
return GlobalSearchScope.EMPTY_SCOPE; return LocalSearchScope.EMPTY;
case MODULE: case MODULE:
GlobalSearchScope moduleScope = GlobalSearchScope.moduleScope(myModule); GlobalSearchScope moduleScope = GlobalSearchScope.moduleScope(myModule);
return myIncludeTestSource ? moduleScope : GlobalSearchScope.notScope(GlobalSearchScopesCore.projectTestScope(myModule.getProject())).intersectWith(moduleScope); return myIncludeTestSource ? moduleScope : GlobalSearchScope.notScope(GlobalSearchScopesCore.projectTestScope(myModule.getProject())).intersectWith(moduleScope);
@@ -710,7 +710,7 @@ public class AnalysisScope {
}; };
default: default:
LOG.error("invalid type " + myType); LOG.error("invalid type " + myType);
return GlobalSearchScope.EMPTY_SCOPE; return LocalSearchScope.EMPTY;
} }
} }

View File

@@ -111,10 +111,12 @@ public class DelegatingGlobalSearchScope extends GlobalSearchScope {
return result; return result;
} }
@NotNull
public GlobalSearchScope getDelegate() { public GlobalSearchScope getDelegate() {
return myBaseScope; return myBaseScope;
} }
@NotNull
public GlobalSearchScope unwrap() { public GlobalSearchScope unwrap() {
return myBaseScope instanceof DelegatingGlobalSearchScope ? ((DelegatingGlobalSearchScope)myBaseScope).unwrap() : myBaseScope; return myBaseScope instanceof DelegatingGlobalSearchScope ? ((DelegatingGlobalSearchScope)myBaseScope).unwrap() : myBaseScope;
} }

View File

@@ -112,15 +112,14 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
@Contract(pure = true) @Contract(pure = true)
public SearchScope intersectWith(@NotNull SearchScope scope2) { public SearchScope intersectWith(@NotNull SearchScope scope2) {
if (scope2 instanceof LocalSearchScope) { if (scope2 instanceof LocalSearchScope) {
LocalSearchScope localScope2 = (LocalSearchScope)scope2; return intersectWith((LocalSearchScope)scope2);
return intersectWith(localScope2);
} }
return intersectWith((GlobalSearchScope)scope2); return intersectWith((GlobalSearchScope)scope2);
} }
@NotNull @NotNull
@Contract(pure = true) @Contract(pure = true)
public SearchScope intersectWith(@NotNull LocalSearchScope localScope2) { public LocalSearchScope intersectWith(@NotNull LocalSearchScope localScope2) {
PsiElement[] elements2 = localScope2.getScope(); PsiElement[] elements2 = localScope2.getScope();
List<PsiElement> result = new ArrayList<>(elements2.length); List<PsiElement> result = new ArrayList<>(elements2.length);
for (final PsiElement element2 : elements2) { for (final PsiElement element2 : elements2) {
@@ -128,7 +127,7 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw
result.add(element2); result.add(element2);
} }
} }
return result.isEmpty() ? EMPTY_SCOPE : new LocalSearchScope(result.toArray(PsiElement.EMPTY_ARRAY), null, localScope2.isIgnoreInjectedPsi()); return result.isEmpty() ? LocalSearchScope.EMPTY : new LocalSearchScope(result.toArray(PsiElement.EMPTY_ARRAY), null, localScope2.isIgnoreInjectedPsi());
} }
@Override @Override

View File

@@ -34,12 +34,12 @@ import java.util.Set;
public class NonClasspathDirectoriesScope extends GlobalSearchScope { public class NonClasspathDirectoriesScope extends GlobalSearchScope {
private final Set<VirtualFile> myRoots; private final Set<VirtualFile> myRoots;
public NonClasspathDirectoriesScope(@NotNull Collection<VirtualFile> roots) { public NonClasspathDirectoriesScope(@NotNull Collection<? extends VirtualFile> roots) {
myRoots = new HashSet<>(roots); myRoots = new HashSet<>(roots);
} }
@NotNull @NotNull
public static GlobalSearchScope compose(@NotNull List<VirtualFile> roots) { public static GlobalSearchScope compose(@NotNull List<? extends VirtualFile> roots) {
if (roots.isEmpty()) { if (roots.isEmpty()) {
return EMPTY_SCOPE; return EMPTY_SCOPE;
} }

View File

@@ -64,4 +64,11 @@ public abstract class SearchScope {
@Contract(pure = true) @Contract(pure = true)
public abstract boolean contains(@NotNull VirtualFile file); public abstract boolean contains(@NotNull VirtualFile file);
/**
* @return true if the scope is a special constant denoting an empty GlobalSearchScope or LocalSearchScope
*/
public static boolean isEmptyScope(@NotNull SearchScope scope) {
return scope == GlobalSearchScope.EMPTY_SCOPE || scope == LocalSearchScope.EMPTY;
}
} }

View File

@@ -129,7 +129,7 @@ public class SearchRequestCollector {
if (searchScope instanceof LocalSearchScope && ((LocalSearchScope)searchScope).getScope().length == 0) { if (searchScope instanceof LocalSearchScope && ((LocalSearchScope)searchScope).getScope().length == 0) {
return false; return false;
} }
return searchScope != GlobalSearchScope.EMPTY_SCOPE && !StringUtil.isEmpty(word); return !SearchScope.isEmptyScope(searchScope) && !StringUtil.isEmpty(word);
} }
public void searchQuery(@NotNull QuerySearchRequest request) { public void searchQuery(@NotNull QuerySearchRequest request) {

View File

@@ -107,7 +107,7 @@ public final class ReferencesSearch extends ExtensibleQueryFactory<PsiReference,
SearchScope scope = myEffectiveScope; SearchScope scope = myEffectiveScope;
if (scope == null) { if (scope == null) {
if (!myElementToSearch.isValid()) return GlobalSearchScope.EMPTY_SCOPE; if (!myElementToSearch.isValid()) return LocalSearchScope.EMPTY;
SearchScope useScope = PsiSearchHelper.getInstance(myElementToSearch.getProject()).getUseScope(myElementToSearch); SearchScope useScope = PsiSearchHelper.getInstance(myElementToSearch.getProject()).getUseScope(myElementToSearch);
myEffectiveScope = scope = myScope.intersectWith(useScope); myEffectiveScope = scope = myScope.intersectWith(useScope);

View File

@@ -9,7 +9,7 @@ import com.intellij.model.search.SearchWordQueryBuilder
import com.intellij.model.search.TextOccurrence import com.intellij.model.search.TextOccurrence
import com.intellij.openapi.fileTypes.FileType import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.PsiSearchScopeUtil.restrictScopeTo import com.intellij.psi.search.PsiSearchScopeUtil.restrictScopeTo
import com.intellij.psi.search.PsiSearchScopeUtil.restrictScopeToFileLanguage import com.intellij.psi.search.PsiSearchScopeUtil.restrictScopeToFileLanguage
import com.intellij.psi.search.SearchScope import com.intellij.psi.search.SearchScope
@@ -23,7 +23,7 @@ internal data class SearchWordQueryBuilderImpl(
private val myContainerName: String? = null, private val myContainerName: String? = null,
private val myCaseSensitive: Boolean = true, private val myCaseSensitive: Boolean = true,
private val mySearchContexts: Set<SearchContext> = emptySet(), private val mySearchContexts: Set<SearchContext> = emptySet(),
private val mySearchScope: SearchScope = GlobalSearchScope.EMPTY_SCOPE, private val mySearchScope: SearchScope = LocalSearchScope.EMPTY,
private val myFileTypes: Collection<FileType>? = null, private val myFileTypes: Collection<FileType>? = null,
private val myFileLanguage: LanguageInfo = LanguageInfo.NoLanguage, private val myFileLanguage: LanguageInfo = LanguageInfo.NoLanguage,
private val myInjection: InjectionInfo = InjectionInfo.NoInjection private val myInjection: InjectionInfo = InjectionInfo.NoInjection

View File

@@ -92,13 +92,13 @@ public class PredefinedSearchScopeProviderImpl extends PredefinedSearchScopeProv
result.add(ScratchesSearchScope.getScratchesScope(project)); result.add(ScratchesSearchScope.getScratchesScope(project));
GlobalSearchScope recentFilesScope = recentFilesScope(project, false); SearchScope recentFilesScope = recentFilesScope(project, false);
ContainerUtil.addIfNotNull( ContainerUtil.addIfNotNull(
result, recentFilesScope != GlobalSearchScope.EMPTY_SCOPE ? recentFilesScope : result, !SearchScope.isEmptyScope(recentFilesScope) ? recentFilesScope :
showEmptyScopes ? new LocalSearchScope(PsiElement.EMPTY_ARRAY, getRecentlyViewedFilesScopeName()) : null); showEmptyScopes ? new LocalSearchScope(PsiElement.EMPTY_ARRAY, getRecentlyViewedFilesScopeName()) : null);
GlobalSearchScope recentModFilesScope = recentFilesScope(project, true); SearchScope recentModFilesScope = recentFilesScope(project, true);
ContainerUtil.addIfNotNull( ContainerUtil.addIfNotNull(
result, recentModFilesScope != GlobalSearchScope.EMPTY_SCOPE ? recentModFilesScope : result, !SearchScope.isEmptyScope(recentModFilesScope) ? recentModFilesScope :
showEmptyScopes ? new LocalSearchScope(PsiElement.EMPTY_ARRAY, getRecentlyChangedFilesScopeName()) : null); showEmptyScopes ? new LocalSearchScope(PsiElement.EMPTY_ARRAY, getRecentlyChangedFilesScopeName()) : null);
GlobalSearchScope openFilesScope = GlobalSearchScopes.openFilesScope(project); GlobalSearchScope openFilesScope = GlobalSearchScopes.openFilesScope(project);
ContainerUtil.addIfNotNull( ContainerUtil.addIfNotNull(
@@ -236,13 +236,13 @@ public class PredefinedSearchScopeProviderImpl extends PredefinedSearchScopeProv
} }
@NotNull @NotNull
public static GlobalSearchScope recentFilesScope(@NotNull Project project, boolean changedOnly) { public static SearchScope recentFilesScope(@NotNull Project project, boolean changedOnly) {
String name = changedOnly ? getRecentlyChangedFilesScopeName() : getRecentlyViewedFilesScopeName(); String name = changedOnly ? getRecentlyChangedFilesScopeName() : getRecentlyViewedFilesScopeName();
List<VirtualFile> files = changedOnly ? IdeDocumentHistory.getInstance(project).getChangedFiles() : List<VirtualFile> files = changedOnly ? IdeDocumentHistory.getInstance(project).getChangedFiles() :
JBIterable.from(EditorHistoryManager.getInstance(project).getFileList()) JBIterable.from(EditorHistoryManager.getInstance(project).getFileList())
.append(FileEditorManager.getInstance(project).getOpenFiles()).unique().toList(); .append(FileEditorManager.getInstance(project).getOpenFiles()).unique().toList();
return files.isEmpty() ? GlobalSearchScope.EMPTY_SCOPE : GlobalSearchScope.filesScope(project, files, name); return files.isEmpty() ? LocalSearchScope.EMPTY : GlobalSearchScope.filesScope(project, files, name);
} }
@Nullable @Nullable

View File

@@ -13,6 +13,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*; import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.FileContextUtil; import com.intellij.psi.impl.source.resolve.FileContextUtil;
import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.PsiElementProcessor; import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.SearchScope;
import com.intellij.testFramework.LightVirtualFile; import com.intellij.testFramework.LightVirtualFile;
@@ -346,7 +347,7 @@ public class MockPsiFile extends MockPsiElement implements PsiFile {
@Override @Override
@NotNull @NotNull
public SearchScope getUseScope() { public SearchScope getUseScope() {
return GlobalSearchScope.EMPTY_SCOPE; return LocalSearchScope.EMPTY;
} }
@Override @Override

View File

@@ -7,10 +7,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference; import com.intellij.psi.PsiReference;
import com.intellij.psi.search.DelegatingGlobalSearchScope; import com.intellij.psi.search.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.RequestResultProcessor;
import com.intellij.psi.search.UsageSearchContext;
import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.util.Processor; import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -41,13 +38,13 @@ public class GradlePropertyReferencesSearcher extends QueryExecutorBase<PsiRefer
return; return;
} }
GlobalSearchScope effectiveSearchScope = (GlobalSearchScope)queryParameters.getEffectiveSearchScope(); SearchScope effectiveSearchScope = queryParameters.getEffectiveSearchScope();
if (effectiveSearchScope == GlobalSearchScope.EMPTY_SCOPE) { if (SearchScope.isEmptyScope(effectiveSearchScope)) {
return; return;
} }
final GlobalSearchScope gradleSearchScope = final GlobalSearchScope gradleSearchScope =
new FileByExtensionSearchScope(effectiveSearchScope, GRADLE_DSL_EXTENSION); new FileByExtensionSearchScope((GlobalSearchScope)effectiveSearchScope, GRADLE_DSL_EXTENSION);
final short searchContext = (short)(UsageSearchContext.IN_CODE | UsageSearchContext.IN_STRINGS); final short searchContext = (short)(UsageSearchContext.IN_CODE | UsageSearchContext.IN_STRINGS);
final MyProcessor processor = new MyProcessor(property); final MyProcessor processor = new MyProcessor(property);