diff --git a/platform/platform-impl/src/com/intellij/ide/lightEdit/project/LightEditProjectFileIndex.java b/platform/platform-impl/src/com/intellij/ide/lightEdit/project/LightEditProjectFileIndex.java index 8e5d55df6e1c..87034c923ee5 100644 --- a/platform/platform-impl/src/com/intellij/ide/lightEdit/project/LightEditProjectFileIndex.java +++ b/platform/platform-impl/src/com/intellij/ide/lightEdit/project/LightEditProjectFileIndex.java @@ -8,8 +8,10 @@ import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileFilter; import com.intellij.platform.workspace.jps.entities.LibraryEntity; +import com.intellij.platform.workspace.jps.entities.SdkEntity; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.jps.model.module.JpsModuleSourceRootType; import java.util.Collection; @@ -103,6 +105,11 @@ final class LightEditProjectFileIndex implements ProjectFileIndex { return Collections.emptyList(); } + @Override + public @NotNull @Unmodifiable Collection<@NotNull SdkEntity> findContainingSdks(@NotNull VirtualFile fileOrDir) { + return Collections.emptyList(); + } + @Override public boolean isExcluded(@NotNull VirtualFile file) { return false; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/roots/impl/SdkInProjectFileIndexTest.kt b/platform/platform-tests/testSrc/com/intellij/openapi/roots/impl/SdkInProjectFileIndexTest.kt index 966c2683630d..069b8eea0184 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/roots/impl/SdkInProjectFileIndexTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/openapi/roots/impl/SdkInProjectFileIndexTest.kt @@ -16,6 +16,8 @@ import com.intellij.openapi.roots.impl.ProjectFileIndexScopes.NOT_IN_PROJECT import com.intellij.openapi.roots.impl.ProjectFileIndexScopes.assertScope import com.intellij.openapi.util.registry.Registry import com.intellij.openapi.vfs.VirtualFile +import com.intellij.platform.testFramework.assertion.collectionAssertion.CollectionAssertions.assertEmpty +import com.intellij.platform.testFramework.assertion.collectionAssertion.CollectionAssertions.assertEqualsUnordered import com.intellij.testFramework.junit5.RunInEdt import com.intellij.testFramework.junit5.TestApplication import com.intellij.testFramework.rules.ProjectModelExtension @@ -23,6 +25,7 @@ import com.intellij.testFramework.rules.TempDirectoryExtension import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.RegisterExtension +import kotlin.test.assertEquals @TestApplication @RunInEdt(writeIntent = true) @@ -60,11 +63,30 @@ class SdkInProjectFileIndexTest { it.addRoot(sdkSourcesRoot, OrderRootType.SOURCES) it.addRoot(sdkDocRoot, OrderRootType.DOCUMENTATION) } + assertEmpty(fileIndex.findContainingSdks(sdkRoot)) ModuleRootModificationUtil.setModuleSdk(module, sdk) fileIndex.assertScope(sdkRoot, IN_LIBRARY) fileIndex.assertScope(sdkSourcesRoot, IN_LIBRARY or IN_SOURCE) fileIndex.assertScope(sdkDocRoot, NOT_IN_PROJECT) + assertEquals(sdk.name, fileIndex.findContainingSdks(sdkRoot).single().name) + assertEquals(sdk.name, fileIndex.findContainingSdks(sdkSourcesRoot).single().name) + assertEmpty(fileIndex.findContainingSdks(sdkDocRoot)) + } + + @Test + fun `two sdk with same root`() { + val sdk1 = projectModel.addSdk("sdk1") { + it.addRoot(sdkRoot, OrderRootType.CLASSES) + } + val sdk2 = projectModel.addSdk("sdk2") { + it.addRoot(sdkRoot, OrderRootType.CLASSES) + } + val module2 = projectModel.createModule("module2") + ModuleRootModificationUtil.setModuleSdk(module, sdk1) + assertEquals("sdk1", fileIndex.findContainingSdks(sdkRoot).single().name) + ModuleRootModificationUtil.setModuleSdk(module2, sdk2) + assertEqualsUnordered(listOf("sdk1", "sdk2"), fileIndex.findContainingSdks(sdkRoot).map { it.name }) } @Test diff --git a/platform/projectModel-api/api-dump-experimental.txt b/platform/projectModel-api/api-dump-experimental.txt index d5910e9fd48c..5cf7a7bbfbbc 100644 --- a/platform/projectModel-api/api-dump-experimental.txt +++ b/platform/projectModel-api/api-dump-experimental.txt @@ -47,6 +47,7 @@ com.intellij.openapi.roots.OrderRootsEnumerator com.intellij.openapi.roots.ProjectFileIndex - com.intellij.openapi.roots.FileIndex - *a:findContainingLibraries(com.intellij.openapi.vfs.VirtualFile):java.util.Collection +- *a:findContainingSdks(com.intellij.openapi.vfs.VirtualFile):java.util.Collection - *a:getModulesForFile(com.intellij.openapi.vfs.VirtualFile,Z):java.util.Set *:com.intellij.openapi.roots.ProjectModelElement - *a:getExternalSource():com.intellij.openapi.roots.ProjectModelExternalSource diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java index f6fbbb7f8eac..550db59ad97c 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java @@ -6,6 +6,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.platform.workspace.jps.entities.LibraryEntity; +import com.intellij.platform.workspace.jps.entities.SdkEntity; import com.intellij.util.concurrency.annotations.RequiresReadLock; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -188,6 +189,12 @@ public interface ProjectFileIndex extends FileIndex { @ApiStatus.Experimental @NotNull @Unmodifiable Collection<@NotNull LibraryEntity> findContainingLibraries(@NotNull VirtualFile fileOrDir); + /** + * Returns SDKs used in the project which have {@code fileOrDir} under their classes or source roots. + */ + @ApiStatus.Experimental + @NotNull @Unmodifiable Collection<@NotNull SdkEntity> findContainingSdks(@NotNull VirtualFile fileOrDir); + /** * Checks if the specified file or directory is located under project roots but the file itself or one of its parent directories is ignored * by {@link FileTypeRegistry#isFileIgnored(VirtualFile)}). 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 c69e1480497b..d9c37c7374bc 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 @@ -11,6 +11,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileFilter; import com.intellij.platform.backend.workspace.WorkspaceModel; import com.intellij.platform.workspace.jps.entities.LibraryEntity; +import com.intellij.platform.workspace.jps.entities.SdkEntity; import com.intellij.platform.workspace.storage.ImmutableEntityStorage; import com.intellij.util.SmartList; import com.intellij.util.containers.ContainerUtil; @@ -23,6 +24,7 @@ import kotlin.Pair; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.jps.model.module.JpsModuleSourceRootType; import java.util.*; @@ -78,6 +80,11 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn return myWorkspaceFileIndex.findContainingEntities(fileOrDir, LibraryEntity.class, true, false, false, true, true, false); } + @Override + public @NotNull @Unmodifiable Collection<@NotNull SdkEntity> findContainingSdks(@NotNull VirtualFile fileOrDir) { + return myWorkspaceFileIndex.findContainingEntities(fileOrDir, SdkEntity.class, true, false, false, true, true, false); + } + @Override public boolean isUnderIgnored(@NotNull VirtualFile file) { WorkspaceFileInternalInfo info = myWorkspaceFileIndex.getFileInfo(file, true, true, true, true, true, true);