From 89d8ec16e55c0a333fd94d26bd1fa409d0cc6551 Mon Sep 17 00:00:00 2001 From: Sergey Patrikeev Date: Tue, 28 Jan 2020 00:11:07 +0300 Subject: [PATCH] Indexes roots collecting re-implemented. Instead of collecting Runnables that iterate over all indexable files let's expose roots from where to start iteration. This will allow to prioritize roots by some predicate. This commit was reviewed in IDEA-CR-57771 GitOrigin-RevId: 8162e759fb27b1bdf64fc24e1a13d454b9a28d5d --- .../util/indexing/FileBasedIndexEx.java | 87 +++++++++++-- .../FileBasedIndexProjectHandler.java | 18 ++- .../FileBasedIndexScanRunnableCollector.java | 41 ++++-- ...leBasedIndexScanRunnableCollectorImpl.java | 119 ------------------ .../indexing/roots/IndexableRootsProvider.kt | 12 ++ .../IndexableSetContributorRootsProvider.kt | 24 ++++ ...ryOrSdkOrderEntryIndexableRootsProvider.kt | 19 +++ .../roots/ModuleIndexableRootsProvider.kt | 17 +++ .../SyntheticLibraryIndexableRootsProvider.kt | 15 +++ .../src/META-INF/LangExtensions.xml | 3 - .../openapi/roots/ModuleFileIndex.java | 11 ++ .../roots/impl/ModuleFileIndexImpl.java | 3 +- .../roots/impl/ProjectFileIndexImpl.java | 2 +- 13 files changed, 222 insertions(+), 149 deletions(-) delete mode 100644 platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollectorImpl.java create mode 100644 platform/lang-impl/src/com/intellij/util/indexing/roots/IndexableRootsProvider.kt create mode 100644 platform/lang-impl/src/com/intellij/util/indexing/roots/IndexableSetContributorRootsProvider.kt create mode 100644 platform/lang-impl/src/com/intellij/util/indexing/roots/LibraryOrSdkOrderEntryIndexableRootsProvider.kt create mode 100644 platform/lang-impl/src/com/intellij/util/indexing/roots/ModuleIndexableRootsProvider.kt create mode 100644 platform/lang-impl/src/com/intellij/util/indexing/roots/SyntheticLibraryIndexableRootsProvider.kt diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexEx.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexEx.java index c9200bcf2f48..b69871a8c5c4 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexEx.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexEx.java @@ -1,10 +1,15 @@ // 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.util.indexing; +import com.intellij.ide.lightEdit.LightEditUtil; +import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.roots.*; import com.intellij.openapi.roots.impl.PushedFilePropertiesUpdaterImpl; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; @@ -16,6 +21,7 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.impl.InvertedIndexValueIterator; +import com.intellij.util.indexing.roots.*; import gnu.trove.THashSet; import gnu.trove.TIntHashSet; import org.jetbrains.annotations.ApiStatus; @@ -315,21 +321,82 @@ public abstract class FileBasedIndexEx extends FileBasedIndex { } @Override - public void iterateIndexableFilesConcurrently(@NotNull ContentIterator processor, @NotNull Project project, @NotNull ProgressIndicator indicator) { - PushedFilePropertiesUpdaterImpl.invokeConcurrentlyIfPossible(collectScanRootRunnables(processor, project, indicator)); + public void iterateIndexableFilesConcurrently(@NotNull ContentIterator processor, + @NotNull Project project, + @NotNull ProgressIndicator indicator) { + List tasks = collectIndexableFilesIterateTasks(processor, project, indicator); + if (!tasks.isEmpty()) { + PushedFilePropertiesUpdaterImpl.invokeConcurrentlyIfPossible(tasks); + } } @Override - public void iterateIndexableFiles(@NotNull ContentIterator processor, @NotNull Project project, ProgressIndicator indicator) { - for(Runnable r: collectScanRootRunnables(processor, project, indicator)) r.run(); + public void iterateIndexableFiles(@NotNull ContentIterator processor, @NotNull Project project, @Nullable ProgressIndicator indicator) { + final ProgressIndicator finalIndicator = indicator == null ? new EmptyProgressIndicator() : indicator; + List tasks = collectIndexableFilesIterateTasks(processor, project, finalIndicator); + for (Runnable task : tasks) { + task.run(); + } } @NotNull - private static List collectScanRootRunnables(@NotNull final ContentIterator processor, - @NotNull final Project project, - ProgressIndicator indicator) { - FileBasedIndexScanRunnableCollector collector = FileBasedIndexScanRunnableCollector.getInstance(project); - return collector.collectScanRootRunnables(processor, indicator); + private static List collectIndexableFilesIterateTasks(@NotNull ContentIterator processor, + @NotNull Project project, + @NotNull ProgressIndicator indicator) { + if (LightEditUtil.isLightEditProject(project)) { + return Collections.emptyList(); + } + @NotNull List providers = getIndexableRootsProvider(project); + ProjectFileIndex projectFileIndex = ProjectFileIndex.getInstance(project); + Set visitedRoots = ContainerUtil.newConcurrentSet(); + return ContainerUtil.map(providers, provider -> () -> { + Set rootsToIndex = provider.getRootsToIndex(); + for (VirtualFile root : rootsToIndex) { + if (visitedRoots.add(root)) { + FileBasedIndex.iterateRecursively(root, processor, indicator, visitedRoots, projectFileIndex); + } + } + }); + } + + @NotNull + private static List getIndexableRootsProvider(@NotNull Project project) { + return ReadAction.compute(() -> { + if (project.isDisposed()) { + return Collections.emptyList(); + } + + List providers = new ArrayList<>(); + Module[] modules = ModuleManager.getInstance(project).getModules(); + for (Module module : modules) { + if (module.isDisposed()) continue; + providers.add(new ModuleIndexableRootsProvider(module)); + + // iterate associated libraries + OrderEntry[] orderEntries = ModuleRootManager.getInstance(module).getOrderEntries(); + for (OrderEntry orderEntry : orderEntries) { + if (!(orderEntry instanceof LibraryOrSdkOrderEntry) || !orderEntry.isValid()) { + continue; + } + + final LibraryOrSdkOrderEntry entry = (LibraryOrSdkOrderEntry)orderEntry; + providers.add(new LibraryOrSdkOrderEntryIndexableRootsProvider(entry)); + } + } + + for (IndexableSetContributor contributor : IndexableSetContributor.EP_NAME.getExtensionList()) { + providers.add(new IndexableSetContributorRootsProvider(contributor, project)); + } + + // iterate synthetic project libraries + for (AdditionalLibraryRootsProvider provider : AdditionalLibraryRootsProvider.EP_NAME.getExtensionList()) { + for (SyntheticLibrary library : provider.getAdditionalProjectLibraries(project)) { + providers.add(new SyntheticLibraryIndexableRootsProvider(library)); + } + } + + return providers; + }); } @Nullable diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexProjectHandler.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexProjectHandler.java index 828eb888132d..9667b6d16f65 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexProjectHandler.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexProjectHandler.java @@ -8,12 +8,15 @@ package com.intellij.util.indexing; import com.google.common.annotations.VisibleForTesting; import com.intellij.diagnostic.PerformanceWatcher; import com.intellij.ide.IdeBundle; +import com.intellij.ide.lightEdit.LightEditUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.Service; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.*; import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.impl.PushedFilePropertiesUpdater; import com.intellij.openapi.startup.StartupActivity; import com.intellij.openapi.util.Disposer; @@ -32,13 +35,14 @@ import java.util.Collection; @Service public final class FileBasedIndexProjectHandler implements IndexableFileSet { private static final Logger LOG = Logger.getInstance(FileBasedIndexProjectHandler.class); - - private final FileBasedIndexScanRunnableCollector myCollector; + private final Project myProject; + private final @NotNull ProjectFileIndex myProjectFileIndex; private boolean isRemoved; private FileBasedIndexProjectHandler(@NotNull Project project) { - myCollector = FileBasedIndexScanRunnableCollector.getInstance(project); + myProject = project; + myProjectFileIndex = ProjectFileIndex.getInstance(myProject); } static final class FileBasedIndexProjectHandlerStartupActivity implements StartupActivity { @@ -86,7 +90,13 @@ public final class FileBasedIndexProjectHandler implements IndexableFileSet { @Override public boolean isInSet(@NotNull final VirtualFile file) { - return myCollector.shouldCollect(file); + if (LightEditUtil.isLightEditProject(myProject)) { + return false; + } + if (myProjectFileIndex.isInContent(file) || myProjectFileIndex.isInLibrary(file)) { + return !FileTypeManager.getInstance().isFileIgnored(file); + } + return false; } @Override diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollector.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollector.java index 8fad94b85e4a..2e979d46d260 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollector.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollector.java @@ -1,23 +1,42 @@ // 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.util.indexing; -import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.ide.lightEdit.LightEditUtil; +import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ContentIterator; +import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; -import java.util.List; +/** + * @deprecated Use {@link FileBasedIndexRootsCollector} instead. + */ +@Deprecated +public final class FileBasedIndexScanRunnableCollector { -public abstract class FileBasedIndexScanRunnableCollector { - public static FileBasedIndexScanRunnableCollector getInstance(@NotNull Project project) { - return ServiceManager.getService(project, FileBasedIndexScanRunnableCollector.class); + private final Project myProject; + private final @NotNull ProjectFileIndex myProjectFileIndex; + + public FileBasedIndexScanRunnableCollector(Project project) { + myProject = project; + myProjectFileIndex = ProjectFileIndex.getInstance(project); } - // Returns true if file should be indexed - public abstract boolean shouldCollect(@NotNull final VirtualFile file); + public static FileBasedIndexScanRunnableCollector getInstance(@NotNull Project project) { + return new FileBasedIndexScanRunnableCollector(project); + } - // Collect all roots for indexing - public abstract List collectScanRootRunnables(@NotNull final ContentIterator processor, final ProgressIndicator indicator); + /** + * @deprecated Use ProjectFileIndex directly. + */ + @Deprecated + public final boolean shouldCollect(@NotNull final VirtualFile file) { + if (LightEditUtil.isLightEditProject(myProject)) { + return false; + } + if (myProjectFileIndex.isInContent(file) || myProjectFileIndex.isInLibrary(file)) { + return !FileTypeManager.getInstance().isFileIgnored(file); + } + return false; + } } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollectorImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollectorImpl.java deleted file mode 100644 index f8074b3a60f2..000000000000 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollectorImpl.java +++ /dev/null @@ -1,119 +0,0 @@ -// 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.util.indexing; - -import com.intellij.ide.lightEdit.LightEditUtil; -import com.intellij.openapi.application.ReadAction; -import com.intellij.openapi.fileTypes.FileTypeManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.*; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NotNull; - -import java.util.*; - -final class FileBasedIndexScanRunnableCollectorImpl extends FileBasedIndexScanRunnableCollector { - private final Project myProject; - private final ProjectFileIndex myProjectFileIndex; - private final boolean myDisabled; - - FileBasedIndexScanRunnableCollectorImpl(@NotNull Project project) { - myProject = project; - myProjectFileIndex = ProjectFileIndex.getInstance(myProject); - myDisabled = LightEditUtil.isLightEditProject(myProject); - } - - @Override - public boolean shouldCollect(@NotNull VirtualFile file) { - if (myDisabled) return false; - if (myProjectFileIndex.isInContent(file) || myProjectFileIndex.isInLibrary(file)) { - return !FileTypeManager.getInstance().isFileIgnored(file); - } - return false; - } - - @Override - public List collectScanRootRunnables(@NotNull ContentIterator processor, ProgressIndicator indicator) { - if (myDisabled) { - return Collections.emptyList(); - } - return ReadAction.compute(() -> { - if (myProject.isDisposed()) { - return Collections.emptyList(); - } - - List tasks = new ArrayList<>(); - final Set visitedRoots = ContainerUtil.newConcurrentSet(); - - tasks.add(() -> myProjectFileIndex.iterateContent(processor, file -> !file.isDirectory() || visitedRoots.add(file))); - - Set contributedRoots = new LinkedHashSet<>(); - for (IndexableSetContributor contributor : IndexableSetContributor.EP_NAME.getExtensionList()) { - //important not to depend on project here, to support per-project background reindex - // each client gives a project to FileBasedIndex - if (myProject.isDisposed()) { - return tasks; - } - contributedRoots.addAll(IndexableSetContributor.getRootsToIndex(contributor)); - contributedRoots.addAll(IndexableSetContributor.getProjectRootsToIndex(contributor, myProject)); - } - for (VirtualFile root : contributedRoots) { - // do not try to visit under-content-roots because the first task took care of that already - if (!myProjectFileIndex.isInContent(root) && visitedRoots.add(root)) { - tasks.add(() -> { - if (myProject.isDisposed() || !root.isValid()) return; - FileBasedIndex.iterateRecursively(root, processor, indicator, visitedRoots, null); - }); - } - } - - // iterate synthetic project libraries - for (AdditionalLibraryRootsProvider provider : AdditionalLibraryRootsProvider.EP_NAME.getExtensionList()) { - if (myProject.isDisposed()) { - return tasks; - } - for (SyntheticLibrary library : provider.getAdditionalProjectLibraries(myProject)) { - for (VirtualFile root : library.getAllRoots()) { - // do not try to visit under-content-roots because the first task took care of that already - if (!myProjectFileIndex.isInContent(root) && visitedRoots.add(root)) { - tasks.add(() -> { - if (myProject.isDisposed() || !root.isValid()) return; - FileBasedIndex.iterateRecursively(root, processor, indicator, visitedRoots, myProjectFileIndex); - }); - } - } - } - } - - // iterate associated libraries - for (final Module module : ModuleManager.getInstance(myProject).getModules()) { - OrderEntry[] orderEntries = ModuleRootManager.getInstance(module).getOrderEntries(); - for (OrderEntry orderEntry : orderEntries) { - if (!(orderEntry instanceof LibraryOrSdkOrderEntry) || !orderEntry.isValid()) { - continue; - } - - final LibraryOrSdkOrderEntry entry = (LibraryOrSdkOrderEntry)orderEntry; - final VirtualFile[] libSources = entry.getRootFiles(OrderRootType.SOURCES); - final VirtualFile[] libClasses = entry.getRootFiles(OrderRootType.CLASSES); - for (VirtualFile[] roots : new VirtualFile[][]{libSources, libClasses}) { - for (final VirtualFile root : roots) { - // do not try to visit under-content-roots because the first task took care of that already - if (!myProjectFileIndex.isInContent(root) && visitedRoots.add(root)) { - tasks.add(() -> { - if (myProject.isDisposed() || module.isDisposed() || !root.isValid()) return; - FileBasedIndex.iterateRecursively(root, processor, indicator, visitedRoots, myProjectFileIndex); - }); - } - } - } - } - } - - return tasks; - }); - } -} diff --git a/platform/lang-impl/src/com/intellij/util/indexing/roots/IndexableRootsProvider.kt b/platform/lang-impl/src/com/intellij/util/indexing/roots/IndexableRootsProvider.kt new file mode 100644 index 000000000000..906447182743 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/util/indexing/roots/IndexableRootsProvider.kt @@ -0,0 +1,12 @@ +// Copyright 2000-2020 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.util.indexing.roots + +import com.intellij.openapi.vfs.VirtualFile +import org.jetbrains.annotations.ApiStatus + +@ApiStatus.Internal +interface IndexableRootsProvider { + val presentableName: String + + fun getRootsToIndex(): Set +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/util/indexing/roots/IndexableSetContributorRootsProvider.kt b/platform/lang-impl/src/com/intellij/util/indexing/roots/IndexableSetContributorRootsProvider.kt new file mode 100644 index 000000000000..7e18f0718d6a --- /dev/null +++ b/platform/lang-impl/src/com/intellij/util/indexing/roots/IndexableSetContributorRootsProvider.kt @@ -0,0 +1,24 @@ +// Copyright 2000-2020 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.util.indexing.roots + +import com.intellij.openapi.application.runReadAction +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.util.indexing.IndexableSetContributor + +data class IndexableSetContributorRootsProvider( + val indexableSetContributor: IndexableSetContributor, + val project: Project +) : IndexableRootsProvider { + + override val presentableName + get() = "Additional roots" + + override fun getRootsToIndex() = runReadAction { + val roots = linkedSetOf() + roots += indexableSetContributor.getAdditionalProjectRootsToIndex(project) + roots += indexableSetContributor.additionalRootsToIndex + roots + } + +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/util/indexing/roots/LibraryOrSdkOrderEntryIndexableRootsProvider.kt b/platform/lang-impl/src/com/intellij/util/indexing/roots/LibraryOrSdkOrderEntryIndexableRootsProvider.kt new file mode 100644 index 000000000000..03e953ddd949 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/util/indexing/roots/LibraryOrSdkOrderEntryIndexableRootsProvider.kt @@ -0,0 +1,19 @@ +// Copyright 2000-2020 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.util.indexing.roots + +import com.intellij.openapi.application.runReadAction +import com.intellij.openapi.roots.LibraryOrSdkOrderEntry +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.vfs.VirtualFile + +data class LibraryOrSdkOrderEntryIndexableRootsProvider(val orderEntry: LibraryOrSdkOrderEntry) : IndexableRootsProvider { + override val presentableName + get() = "Roots of ${orderEntry.presentableName}" + + override fun getRootsToIndex() = runReadAction { + val roots = linkedSetOf() + roots += orderEntry.getRootFiles(OrderRootType.SOURCES) + roots += orderEntry.getRootFiles(OrderRootType.CLASSES) + roots + } +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/util/indexing/roots/ModuleIndexableRootsProvider.kt b/platform/lang-impl/src/com/intellij/util/indexing/roots/ModuleIndexableRootsProvider.kt new file mode 100644 index 000000000000..5195bdbf2fb9 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/util/indexing/roots/ModuleIndexableRootsProvider.kt @@ -0,0 +1,17 @@ +// Copyright 2000-2020 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.util.indexing.roots + +import com.intellij.openapi.application.runReadAction +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.ModuleRootManager +import com.intellij.openapi.vfs.VirtualFile + +data class ModuleIndexableRootsProvider(val module: Module) : IndexableRootsProvider { + override val presentableName + get() = "Roots of module ${module.name}" + + override fun getRootsToIndex(): Set = runReadAction { + ModuleRootManager.getInstance(module).fileIndex.moduleRootsToIterate + } + +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/util/indexing/roots/SyntheticLibraryIndexableRootsProvider.kt b/platform/lang-impl/src/com/intellij/util/indexing/roots/SyntheticLibraryIndexableRootsProvider.kt new file mode 100644 index 000000000000..8a3393058d00 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/util/indexing/roots/SyntheticLibraryIndexableRootsProvider.kt @@ -0,0 +1,15 @@ +// Copyright 2000-2020 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.util.indexing.roots + +import com.intellij.navigation.ItemPresentation +import com.intellij.openapi.application.runReadAction +import com.intellij.openapi.roots.SyntheticLibrary + +data class SyntheticLibraryIndexableRootsProvider(val syntheticLibrary: SyntheticLibrary) : IndexableRootsProvider { + override val presentableName + get() = "Roots of " + if (syntheticLibrary is ItemPresentation) syntheticLibrary.presentableText else "synthetic library" + + override fun getRootsToIndex() = runReadAction { + syntheticLibrary.allRoots.toSet() + } +} \ No newline at end of file diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index d98ede4bd19d..9e7cbae38951 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -115,9 +115,6 @@ - - diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleFileIndex.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleFileIndex.java index 56967f9c365b..f39cabcbb809 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleFileIndex.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ModuleFileIndex.java @@ -16,11 +16,13 @@ package com.intellij.openapi.roots; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileFilter; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Set; /** * Provides information about files contained in a module. Should be used from a read action. @@ -50,4 +52,13 @@ public interface ModuleFileIndex extends FileIndex { * @return the list of order entries to which the file or directory belongs. */ @NotNull List getOrderEntriesForFile(@NotNull VirtualFile fileOrDir); + + /** + * Returns content roots of the module (skipping excluded and ignored files and directories) + * that will be recursively iterated when one of the iterate methods is called. + * + * @see #iterateContent(ContentIterator) + * @see #iterateContent(ContentIterator, VirtualFileFilter) + */ + @NotNull Set getModuleRootsToIterate(); } diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java index 3c58191a618c..e6ea8044ef94 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleFileIndexImpl.java @@ -35,8 +35,9 @@ public class ModuleFileIndexImpl extends FileIndexBase implements ModuleFileInde } + @Override @NotNull - Set getModuleRootsToIterate() { + public Set getModuleRootsToIterate() { return ReadAction.compute(() -> { if (myModule.isDisposed()) return Collections.emptySet(); Set result = new LinkedHashSet<>(); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java index 9928d97e1fb4..800165f47158 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java @@ -59,7 +59,7 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn return ReadAction.compute(() -> { if (module.isDisposed()) return Collections.emptySet(); - ModuleFileIndexImpl moduleFileIndex = (ModuleFileIndexImpl)ModuleRootManager.getInstance(module).getFileIndex(); + ModuleFileIndex moduleFileIndex = ModuleRootManager.getInstance(module).getFileIndex(); Set result = moduleFileIndex.getModuleRootsToIterate(); for (Iterator iterator = result.iterator(); iterator.hasNext(); ) {