diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollectorImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollectorImpl.java index dacfb0fef892..f6c87f0e5e29 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollectorImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexScanRunnableCollectorImpl.java @@ -15,6 +15,9 @@ */ package com.intellij.util.indexing; +import com.intellij.openapi.application.AccessToken; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.FileTypeManager; import com.intellij.openapi.module.Module; @@ -53,74 +56,81 @@ public class FileBasedIndexScanRunnableCollectorImpl extends FileBasedIndexScanR @Override public List collectScanRootRunnables(@NotNull ContentIterator processor, ProgressIndicator indicator) { - if (myProject.isDisposed()) { - return Collections.emptyList(); - } - - List tasks = new ArrayList<>(); - tasks.add(() -> myProjectFileIndex.iterateContent(processor)); - - /* - Module[] modules = ModuleManager.getInstance(project).getModules(); - for(final Module module: modules) { - tasks.add(new Runnable() { - @Override - public void run() { - if (module.isDisposed()) return; - ModuleRootManager.getInstance(module).getFileIndex().iterateContent(processor); - } - }); - }*/ - - final Set visitedRoots = ContainerUtil.newConcurrentSet(); - JBIterable contributedRoots = JBIterable.empty(); - for (IndexableSetContributor contributor : Extensions.getExtensions(IndexableSetContributor.EP_NAME)) { - //important not to depend on project here, to support per-project background reindex - // each client gives a project to FileBasedIndex + try (AccessToken ignore = ReadAction.start()) { if (myProject.isDisposed()) { - return tasks; + return Collections.emptyList(); } - contributedRoots = contributedRoots.append(IndexableSetContributor.getRootsToIndex(contributor)); - contributedRoots = contributedRoots.append(IndexableSetContributor.getProjectRootsToIndex(contributor, myProject)); - } - for (AdditionalLibraryRootsProvider provider : Extensions.getExtensions(AdditionalLibraryRootsProvider.EP_NAME)) { - if (myProject.isDisposed()) { - return tasks; - } - contributedRoots = contributedRoots.append(provider.getAdditionalProjectLibraries(myProject), SyntheticLibrary::getSourceRoots); - } - for (VirtualFile root : contributedRoots) { - if (visitedRoots.add(root)) { - tasks.add(() -> { - if (myProject.isDisposed() || !root.isValid()) return; - FileBasedIndex.iterateRecursively(root, processor, indicator, visitedRoots, null); + + List tasks = new ArrayList<>(); + tasks.add(() -> myProjectFileIndex.iterateContent(processor)); + + /* + Module[] modules = ModuleManager.getInstance(project).getModules(); + for(final Module module: modules) { + tasks.add(new Runnable() { + @Override + public void run() { + if (module.isDisposed()) return; + ModuleRootManager.getInstance(module).getFileIndex().iterateContent(processor); + } }); - } - } + }*/ - // 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) { - if (orderEntry.isValid()) { - 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) { - if (visitedRoots.add(root)) { - tasks.add(() -> { - if (myProject.isDisposed() || module.isDisposed() || !root.isValid()) return; - FileBasedIndex.iterateRecursively(root, processor, indicator, visitedRoots, myProjectFileIndex); - }); + final Set visitedRoots = ContainerUtil.newConcurrentSet(); + JBIterable contributedRoots = JBIterable.empty(); + for (IndexableSetContributor contributor : Extensions.getExtensions(IndexableSetContributor.EP_NAME)) { + //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 = contributedRoots.append(IndexableSetContributor.getRootsToIndex(contributor)); + contributedRoots = contributedRoots.append(IndexableSetContributor.getProjectRootsToIndex(contributor, myProject)); + } + for (AdditionalLibraryRootsProvider provider : Extensions.getExtensions(AdditionalLibraryRootsProvider.EP_NAME)) { + if (myProject.isDisposed()) { + return tasks; + } + contributedRoots = contributedRoots.append(provider.getAdditionalProjectLibraries(myProject), SyntheticLibrary::getSourceRoots); + } + for (VirtualFile root : contributedRoots) { + if (visitedRoots.add(root)) { + tasks.add(() -> { + if (myProject.isDisposed() || !root.isValid()) return; + FileBasedIndex.iterateRecursively(root, processor, indicator, visitedRoots, null); + }); + } + } + + // 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) { + if (orderEntry.isValid()) { + 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) { + if (visitedRoots.add(root)) { + tasks.add(() -> { + if (myProject.isDisposed() || module.isDisposed() || !root.isValid()) return; + FileBasedIndex.iterateRecursively(root, processor, indicator, visitedRoots, myProjectFileIndex); + }); + } } } } } } } + + for(int i = 0, size = tasks.size(); i < size; ++i) { + Runnable runnable = tasks.get(i); + tasks.set(i, () -> ApplicationManager.getApplication().runReadAction(runnable)); + } + return tasks; } - return tasks; } }