diff --git a/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java b/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java index 8d1911331416..9877e03ccd82 100644 --- a/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java +++ b/platform/analysis-api/src/com/intellij/psi/search/GlobalSearchScopesCore.java @@ -16,6 +16,8 @@ package com.intellij.psi.search; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; @@ -33,6 +35,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; +import java.util.Collection; import java.util.Collections; import java.util.Objects; import java.util.Set; @@ -158,6 +161,11 @@ public class GlobalSearchScopesCore { return false; } + @Override + public Collection getUnloadedModulesBelongingToScope() { + return ModuleManager.getInstance(ObjectUtils.assertNotNull(getProject())).getUnloadedModuleDescriptions(); + } + @NotNull @Override public String getDisplayName() { diff --git a/platform/core-api/src/com/intellij/openapi/roots/FileIndexFacade.java b/platform/core-api/src/com/intellij/openapi/roots/FileIndexFacade.java index 0bad3e572c25..4b0a997d6b24 100644 --- a/platform/core-api/src/com/intellij/openapi/roots/FileIndexFacade.java +++ b/platform/core-api/src/com/intellij/openapi/roots/FileIndexFacade.java @@ -17,6 +17,7 @@ package com.intellij.openapi.roots; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ModificationTracker; import com.intellij.openapi.vfs.VirtualFile; @@ -24,6 +25,8 @@ import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; + /** * @author yole */ @@ -65,4 +68,7 @@ public abstract class FileIndexFacade { } @NotNull public abstract ModificationTracker getRootModificationTracker(); + + @NotNull + public abstract Collection getUnloadedModuleDescriptions(); } diff --git a/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java b/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java index 1d2a61961d79..89179044fa4b 100644 --- a/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java +++ b/platform/core-api/src/com/intellij/psi/search/DelegatingGlobalSearchScope.java @@ -16,11 +16,13 @@ package com.intellij.psi.search; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import java.util.Arrays; +import java.util.Collection; /** * @author peter @@ -69,6 +71,11 @@ public class DelegatingGlobalSearchScope extends GlobalSearchScope { return myBaseScope.isSearchOutsideRootModel(); } + @Override + public Collection getUnloadedModulesBelongingToScope() { + return myBaseScope.getUnloadedModulesBelongingToScope(); + } + @NotNull @Override public String getDisplayName() { diff --git a/platform/core-api/src/com/intellij/psi/search/EverythingGlobalScope.java b/platform/core-api/src/com/intellij/psi/search/EverythingGlobalScope.java index 191a5a29abb0..8d68e7b3e0a2 100644 --- a/platform/core-api/src/com/intellij/psi/search/EverythingGlobalScope.java +++ b/platform/core-api/src/com/intellij/psi/search/EverythingGlobalScope.java @@ -20,10 +20,15 @@ package com.intellij.psi.search; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.UnloadedModuleDescription; +import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; +import java.util.Collection; +import java.util.Collections; + public class EverythingGlobalScope extends GlobalSearchScope { public EverythingGlobalScope(Project project) { super(project); @@ -62,6 +67,12 @@ public class EverythingGlobalScope extends GlobalSearchScope { return true; } + @Override + public Collection getUnloadedModulesBelongingToScope() { + Project project = getProject(); + return project != null ? FileIndexFacade.getInstance(project).getUnloadedModuleDescriptions() : Collections.emptySet(); + } + @NotNull @Override public GlobalSearchScope union(@NotNull SearchScope scope) { diff --git a/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java b/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java index 70ddadc61b07..f94d07f258fb 100644 --- a/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java +++ b/platform/core-api/src/com/intellij/psi/search/GlobalSearchScope.java @@ -17,6 +17,7 @@ package com.intellij.psi.search; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.Comparing; @@ -82,6 +83,14 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw return false; } + /** + * Returns descriptions of unloaded modules content of whose might be included into this scope if they had been loaded. Actually search in + * unloaded modules isn't performed, so this method is used to determine whether a warning about possible missing results should be shown. + */ + public Collection getUnloadedModulesBelongingToScope() { + return Collections.emptySet(); + } + @NotNull public GlobalSearchScope intersectWith(@NotNull GlobalSearchScope scope) { if (scope == this) return this; @@ -152,6 +161,11 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw return GlobalSearchScope.this.isSearchInLibraries(); } + @Override + public Collection getUnloadedModulesBelongingToScope() { + return GlobalSearchScope.this.getUnloadedModulesBelongingToScope(); + } + @NonNls @Override public String toString() { @@ -429,6 +443,11 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw return myScope1.isSearchOutsideRootModel() && myScope2.isSearchOutsideRootModel(); } + @Override + public Collection getUnloadedModulesBelongingToScope() { + return ContainerUtil.intersection(myScope1.getUnloadedModulesBelongingToScope(), myScope2.getUnloadedModulesBelongingToScope()); + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -493,6 +512,15 @@ public abstract class GlobalSearchScope extends SearchScope implements ProjectAw return ContainerUtil.find(myScopes, scope -> scope.isSearchOutsideRootModel()) != null; } + @Override + public Collection getUnloadedModulesBelongingToScope() { + Set result = new LinkedHashSet<>(); + for (GlobalSearchScope scope : myScopes) { + result.addAll(scope.getUnloadedModulesBelongingToScope()); + } + return result; + } + @Override public int compare(@NotNull final VirtualFile file1, @NotNull final VirtualFile file2) { final int[] result = {0}; diff --git a/platform/core-impl/src/com/intellij/core/CoreProjectScopeBuilder.java b/platform/core-impl/src/com/intellij/core/CoreProjectScopeBuilder.java index 3f4c6e647d2c..33eea8d6a853 100644 --- a/platform/core-impl/src/com/intellij/core/CoreProjectScopeBuilder.java +++ b/platform/core-impl/src/com/intellij/core/CoreProjectScopeBuilder.java @@ -16,6 +16,7 @@ package com.intellij.core; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.vfs.VirtualFile; @@ -25,6 +26,8 @@ import com.intellij.psi.search.ProjectScopeBuilder; import com.intellij.psi.search.ProjectScopeImpl; import org.jetbrains.annotations.NotNull; +import java.util.Collection; + /** * @author yole */ @@ -113,5 +116,10 @@ public class CoreProjectScopeBuilder extends ProjectScopeBuilder { public boolean isSearchInLibraries() { return false; } + + @Override + public Collection getUnloadedModulesBelongingToScope() { + return myFileIndexFacade.getUnloadedModuleDescriptions(); + } } } diff --git a/platform/core-impl/src/com/intellij/mock/MockFileIndexFacade.java b/platform/core-impl/src/com/intellij/mock/MockFileIndexFacade.java index 6a37ba181944..5dea36717ddf 100644 --- a/platform/core-impl/src/com/intellij/mock/MockFileIndexFacade.java +++ b/platform/core-impl/src/com/intellij/mock/MockFileIndexFacade.java @@ -16,6 +16,7 @@ package com.intellij.mock; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.ModificationTracker; @@ -23,8 +24,7 @@ import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; +import java.util.*; /** * @author yole @@ -94,6 +94,12 @@ public class MockFileIndexFacade extends FileIndexFacade { return ModificationTracker.NEVER_CHANGED; } + @NotNull + @Override + public Collection getUnloadedModuleDescriptions() { + return Collections.emptySet(); + } + public void addLibraryRoot(VirtualFile file) { myLibraryRoots.add(file); } diff --git a/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java b/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java index f21c241e966a..4d487c22ed04 100644 --- a/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java +++ b/platform/core-impl/src/com/intellij/psi/search/ProjectScopeImpl.java @@ -17,12 +17,15 @@ package com.intellij.psi.search; import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiBundle; import org.jetbrains.annotations.NotNull; +import java.util.Collection; + public class ProjectScopeImpl extends GlobalSearchScope { private final FileIndexFacade myFileIndex; @@ -66,6 +69,11 @@ public class ProjectScopeImpl extends GlobalSearchScope { return getDisplayName(); } + @Override + public Collection getUnloadedModulesBelongingToScope() { + return myFileIndex.getUnloadedModuleDescriptions(); + } + @NotNull @Override public GlobalSearchScope uniteWith(@NotNull GlobalSearchScope scope) { diff --git a/platform/indexing-api/src/com/intellij/psi/search/ProjectAndLibrariesScope.java b/platform/indexing-api/src/com/intellij/psi/search/ProjectAndLibrariesScope.java index 1f3cf14317bb..58a5c91531ca 100644 --- a/platform/indexing-api/src/com/intellij/psi/search/ProjectAndLibrariesScope.java +++ b/platform/indexing-api/src/com/intellij/psi/search/ProjectAndLibrariesScope.java @@ -17,12 +17,16 @@ package com.intellij.psi.search; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiBundle; import org.jetbrains.annotations.NotNull; +import java.util.Collection; +import java.util.Collections; import java.util.List; public class ProjectAndLibrariesScope extends GlobalSearchScope { @@ -87,6 +91,12 @@ public class ProjectAndLibrariesScope extends GlobalSearchScope { return true; } + @Override + public Collection getUnloadedModulesBelongingToScope() { + Project project = getProject(); + return project != null ? ModuleManager.getInstance(project).getUnloadedModuleDescriptions() : Collections.emptySet(); + } + @NotNull public String getDisplayName() { return myDisplayName; diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java index 46f6f75f8e45..9720e857a935 100644 --- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java +++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java @@ -17,19 +17,23 @@ package com.intellij.openapi.module.impl.scopes; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; +import com.intellij.openapi.roots.impl.DirectoryIndex; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.ProjectScope; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.Queue; import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import java.util.Collection; import java.util.Set; /** @@ -127,6 +131,13 @@ class ModuleWithDependentsScope extends GlobalSearchScope { return false; } + @Override + public Collection getUnloadedModulesBelongingToScope() { + ModuleManager moduleManager = ModuleManager.getInstance(myModule.getProject()); + return ContainerUtil.mapNotNull(DirectoryIndex.getInstance(myModule.getProject()).getDependentUnloadedModules(myModule), + moduleManager::getUnloadedModuleDescription); + } + @NonNls public String toString() { return "Module with dependents:" + myModule.getName(); diff --git a/platform/indexing-impl/src/com/intellij/psi/search/ProjectScopeBuilderImpl.java b/platform/indexing-impl/src/com/intellij/psi/search/ProjectScopeBuilderImpl.java index b586bf60901a..9b6efe2c4673 100644 --- a/platform/indexing-impl/src/com/intellij/psi/search/ProjectScopeBuilderImpl.java +++ b/platform/indexing-impl/src/com/intellij/psi/search/ProjectScopeBuilderImpl.java @@ -18,6 +18,7 @@ package com.intellij.psi.search; import com.intellij.core.CoreProjectScopeBuilder; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.roots.ProjectRootManager; @@ -25,6 +26,9 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiBundle; import org.jetbrains.annotations.NotNull; +import java.util.Collection; +import java.util.Collections; + /** * @author yole */ @@ -49,6 +53,11 @@ public class ProjectScopeBuilderImpl extends ProjectScopeBuilder { public boolean isSearchInModuleContent(@NotNull Module aModule) { return false; } + + @Override + public Collection getUnloadedModulesBelongingToScope() { + return Collections.emptySet(); + } }; result.setDisplayName(PsiBundle.message("psi.search.scope.libraries")); return result; diff --git a/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java b/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java index ee89d6438ed8..a4f3e881ca55 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java +++ b/platform/projectModel-api/src/com/intellij/openapi/module/ModuleManager.java @@ -180,7 +180,11 @@ public abstract class ModuleManager extends SimpleModificationTracker { public abstract Collection getAllModuleDescriptions(); @ApiStatus.Experimental - public abstract Collection getUnloadedModuleDescriptions(); + public abstract Collection getUnloadedModuleDescriptions(); + + @ApiStatus.Experimental + @Nullable + public abstract UnloadedModuleDescription getUnloadedModuleDescription(@NotNull String moduleName); /** * Specify list of modules which will be unloaded from the project. These modules won't be shown in UI, all of their contents will be excluded diff --git a/platform/projectModel-impl/src/com/intellij/openapi/module/EmptyModuleManager.kt b/platform/projectModel-impl/src/com/intellij/openapi/module/EmptyModuleManager.kt index 45e102b62949..a2e67b6bfc73 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/module/EmptyModuleManager.kt +++ b/platform/projectModel-impl/src/com/intellij/openapi/module/EmptyModuleManager.kt @@ -55,4 +55,6 @@ class EmptyModuleManager(project: Project, messageBus: MessageBus) : ModuleManag override fun getAllModuleDescriptions() = emptyList() override fun getUnloadedModuleDescriptions() = emptyList() + + override fun getUnloadedModuleDescription(moduleName: String) = null } \ No newline at end of file diff --git a/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java index 385d67fcec9c..fafd93c175a4 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/module/impl/ModuleManagerImpl.java @@ -992,8 +992,14 @@ public abstract class ModuleManagerImpl extends ModuleManager implements Disposa } @Override - public Collection getUnloadedModuleDescriptions() { - return myUnloadedModules.values(); + public Collection getUnloadedModuleDescriptions() { + return Collections.unmodifiableCollection(myUnloadedModules.values()); + } + + @Nullable + @Override + public UnloadedModuleDescription getUnloadedModuleDescription(@NotNull String moduleName) { + return myUnloadedModules.get(moduleName); } @Override diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexFacade.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexFacade.java index 91fb421177b4..d8fcf3b52b60 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexFacade.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexFacade.java @@ -17,6 +17,8 @@ package com.intellij.openapi.roots.impl; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.roots.ProjectFileIndex; @@ -26,6 +28,8 @@ import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; + /** * @author yole */ @@ -98,4 +102,10 @@ public class ProjectFileIndexFacade extends FileIndexFacade { public ModificationTracker getRootModificationTracker() { return ProjectRootManager.getInstance(myProject); } + + @NotNull + @Override + public Collection getUnloadedModuleDescriptions() { + return ModuleManager.getInstance(myProject).getUnloadedModuleDescriptions(); + } } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/SourceScope.java b/platform/testRunner/src/com/intellij/execution/testframework/SourceScope.java index 63a96e76fca9..90bb29235d60 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/SourceScope.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/SourceScope.java @@ -17,6 +17,7 @@ package com.intellij.execution.testframework; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.search.GlobalSearchScope; @@ -193,6 +194,11 @@ public abstract class SourceScope { return true; } + @Override + public Collection getUnloadedModulesBelongingToScope() { + return myMainScope.getUnloadedModulesBelongingToScope(); + } + @Nullable private GlobalSearchScope findScopeFor(final VirtualFile file) { if (myMainScope.contains(file)) return myMainScope; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultFileIndexFacade.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultFileIndexFacade.java index d4063478d373..e11cdf239d8e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultFileIndexFacade.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/impl/DefaultFileIndexFacade.java @@ -16,6 +16,7 @@ package com.intellij.openapi.vcs.impl; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.UnloadedModuleDescription; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; import com.intellij.openapi.util.ModificationTracker; @@ -24,6 +25,9 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.platform.ProjectBaseDirectory; import org.jetbrains.annotations.NotNull; +import java.util.Collection; +import java.util.Collections; + /** * @author yole */ @@ -85,6 +89,12 @@ public class DefaultFileIndexFacade extends FileIndexFacade { return ModificationTracker.NEVER_CHANGED; } + @NotNull + @Override + public Collection getUnloadedModuleDescriptions() { + return Collections.emptySet(); + } + private VirtualFile getBaseDir() { return ProjectBaseDirectory.getInstance(myProject).getBaseDir(myBaseDir); }