From 897e6a555b61c5530709f6693987eec61c6b4055 Mon Sep 17 00:00:00 2001 From: Lev Leontev Date: Mon, 11 Aug 2025 19:03:50 +0200 Subject: [PATCH] BAZEL-2297: search in non-indexable files should skip excluded dirs Cherry-picked from IJ-CR-172078 GitOrigin-RevId: 1a780c083ebb56b116580e5d07169e7bcc3e7118 --- .../util/indexing/NonIndexableFilesUtils.kt | 19 +++++++++++++++++-- .../intellij/find/SearchInNonIndexableTest.kt | 6 ++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/platform/indexing-impl/src/com/intellij/util/indexing/NonIndexableFilesUtils.kt b/platform/indexing-impl/src/com/intellij/util/indexing/NonIndexableFilesUtils.kt index 209cfb59f5f3..fbbd6428fa97 100644 --- a/platform/indexing-impl/src/com/intellij/util/indexing/NonIndexableFilesUtils.kt +++ b/platform/indexing-impl/src/com/intellij/util/indexing/NonIndexableFilesUtils.kt @@ -19,6 +19,7 @@ import com.intellij.workspaceModel.core.fileIndex.WorkspaceFileKind import com.intellij.workspaceModel.core.fileIndex.WorkspaceFileSet import com.intellij.workspaceModel.core.fileIndex.WorkspaceFileSetWithCustomData import com.intellij.workspaceModel.core.fileIndex.impl.WorkspaceFileIndexEx +import com.intellij.workspaceModel.core.fileIndex.impl.WorkspaceFileInternalInfo.NonWorkspace import org.jetbrains.annotations.ApiStatus @@ -51,17 +52,29 @@ private fun WorkspaceFileIndex.allIndexableFileSets(root: VirtualFile): AllFileS } }.let { (recursive, nonRecursive) -> AllFileSets(recursive, nonRecursive) } +private fun WorkspaceFileIndexEx.isExcludedOrInvalid(file: VirtualFile): Boolean = runReadAction { + val info = getFileInfo(file, true, true, true, true, true, true) + when (info) { + NonWorkspace.EXCLUDED -> true + NonWorkspace.IGNORED -> true + NonWorkspace.INVALID -> true + NonWorkspace.NOT_UNDER_ROOTS -> true + else -> false + } +} + @RequiresBackgroundThread -private fun WorkspaceFileIndex.iterateNonIndexableFilesImpl(roots: Set, filter: VirtualFileFilter, processor: ContentIterator): Boolean { +private fun WorkspaceFileIndexEx.iterateNonIndexableFilesImpl(roots: Set, filter: VirtualFileFilter, processor: ContentIterator): Boolean { for (root in roots) { val res = VfsUtilCore.visitChildrenRecursively(root, object : VirtualFileVisitor() { override fun visitFileEx(file: VirtualFile): Result { ProgressManager.checkCanceled() + if (isExcludedOrInvalid(file)) return SKIP_CHILDREN val currentIndexableFileSets = allIndexableFileSets(root = file) return when { - !filter.accept(file) -> SKIP_CHILDREN currentIndexableFileSets.recursive.isNotEmpty() -> SKIP_CHILDREN currentIndexableFileSets.nonRecursive.isNotEmpty() -> CONTINUE // skip only the current file, children can be non-indexable + !filter.accept(file) -> SKIP_CHILDREN !processor.processFile(file) -> skipTo(root) // terminate processing else -> CONTINUE } @@ -107,6 +120,8 @@ private class NonIndexableFilesDequeImpl(private val project: Project, private v if (file in visitedRoots) continue if (file in roots) visitedRoots.add(file) + val workspaceFileIndex = WorkspaceFileIndexEx.getInstance(project) + if (workspaceFileIndex.isExcludedOrInvalid(file)) continue val indexableFileSets = WorkspaceFileIndexEx.getInstance(project).allIndexableFileSets(file) if (indexableFileSets.recursive.isNotEmpty()) continue // skip the current file and their children diff --git a/platform/lang-impl/testSources/com/intellij/find/SearchInNonIndexableTest.kt b/platform/lang-impl/testSources/com/intellij/find/SearchInNonIndexableTest.kt index 44f6030762b0..e015728d02e9 100644 --- a/platform/lang-impl/testSources/com/intellij/find/SearchInNonIndexableTest.kt +++ b/platform/lang-impl/testSources/com/intellij/find/SearchInNonIndexableTest.kt @@ -53,7 +53,6 @@ class SearchInNonIndexableTest() { val nonIndexable = baseDir.newVirtualDirectory("non-indexable").toVirtualFileUrl(urlManager) baseDir.newVirtualFile("non-indexable/file1", "this is a file with some data".toByteArray()) - baseDir.newVirtualFile("non-indexable/file2", "this is a file with some ".toByteArray()) val indexable = baseDir.newVirtualDirectory("indexable").toVirtualFileUrl(urlManager) @@ -62,9 +61,12 @@ class SearchInNonIndexableTest() { val indexableNonRecursive = baseDir.newVirtualDirectory("non-indexable/indexable-non-recursive").toVirtualFileUrl(urlManager) baseDir.newVirtualFile("non-indexable/indexable-non-recursive/non-indexable-beats-non-recursive-content", "this is a file with some data".toByteArray()) + val excluded = baseDir.newVirtualDirectory("non-indexable/excluded").toVirtualFileUrl(urlManager) + baseDir.newVirtualFile("non-indexable/excluded/file-in-excluded", "this is a file inside an excluded directory".toByteArray()) + project.workspaceModel.update("add non-indexable root") { storage -> storage.addEntity(NonIndexableTestEntity(nonIndexable, NonPersistentEntitySource)) - storage.addEntity(IndexingTestEntity(listOf(indexable), emptyList(), NonPersistentEntitySource)) + storage.addEntity(IndexingTestEntity(listOf(indexable), listOf(excluded), NonPersistentEntitySource)) storage.addEntity(NonRecursiveTestEntity(indexableNonRecursive, NonPersistentEntitySource)) } VfsTestUtil.syncRefresh()