diff --git a/platform/projectModel-api/api-dump.txt b/platform/projectModel-api/api-dump.txt index 6152b5441a63..273967dd0576 100644 --- a/platform/projectModel-api/api-dump.txt +++ b/platform/projectModel-api/api-dump.txt @@ -1023,3 +1023,6 @@ com.intellij.workspaceModel.ide.legacyBridge.SourceRootTypeRegistry - s:getInstance():com.intellij.workspaceModel.ide.legacyBridge.SourceRootTypeRegistry f:com.intellij.workspaceModel.ide.legacyBridge.SourceRootTypeRegistry$Companion - f:getInstance():com.intellij.workspaceModel.ide.legacyBridge.SourceRootTypeRegistry +com.intellij.workspaceModel.ide.legacyBridge.WorkspaceModelLegacyBridge +- a:findLegacyModule(com.intellij.platform.workspace.jps.entities.ModuleEntity):com.intellij.openapi.module.Module +- a:findModuleEntity(com.intellij.openapi.module.Module):com.intellij.platform.workspace.jps.entities.ModuleEntity diff --git a/platform/projectModel-api/src/com/intellij/openapi/module/ModuleUtilCore.java b/platform/projectModel-api/src/com/intellij/openapi/module/ModuleUtilCore.java index 55d5242813ea..6b956cdc7e5c 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/module/ModuleUtilCore.java +++ b/platform/projectModel-api/src/com/intellij/openapi/module/ModuleUtilCore.java @@ -2,22 +2,31 @@ package com.intellij.openapi.module; import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.*; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.platform.backend.workspace.WorkspaceModel; +import com.intellij.platform.workspace.jps.entities.ModuleEntity; +import com.intellij.platform.workspace.storage.EntityStorage; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileSystemItem; import com.intellij.util.PathUtilRt; import com.intellij.util.concurrency.annotations.RequiresBackgroundThread; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.graph.Graph; +import com.intellij.workspaceModel.ide.legacyBridge.WorkspaceModelLegacyBridge; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.stream.Collectors; + +import static com.intellij.platform.workspace.jps.entities.ExtensionsKt.collectTransitivelyDependentModules; public class ModuleUtilCore { public static final Key KEY_MODULE = new Key<>("Module"); @@ -169,33 +178,30 @@ public class ModuleUtilCore { } /** - * collect transitive module dependants + *

Obsolescence notice

+ * This method uses + * {@link com.intellij.platform.workspace.jps.entities.ExtensionsKt#collectTransitivelyDependentModules(ModuleEntity, EntityStorage)}, + * and remains for compatibility. + *

+ * + * Collect transitive dependent modules. * * @param module to find dependencies on * @param result resulted set */ + @ApiStatus.Obsolete(since = "2025.1") public static void collectModulesDependsOn(@NotNull Module module, @NotNull Set result) { - if (!result.add(module)) { - return; - } + var project = module.getProject(); + var legacyBridge = project.getService(WorkspaceModelLegacyBridge.class); + var moduleEntity = legacyBridge.findModuleEntity(module); + if (moduleEntity == null) return; // error? - ModuleManager moduleManager = ModuleManager.getInstance(module.getProject()); - List dependentModules = moduleManager.getModuleDependentModules(module); - for (Module dependentModule : dependentModules) { - OrderEntry[] orderEntries = ModuleRootManager.getInstance(dependentModule).getOrderEntries(); - for (OrderEntry o : orderEntries) { - if (o instanceof ModuleOrderEntry orderEntry) { - if (orderEntry.getModule() == module) { - if (orderEntry.isExported()) { - collectModulesDependsOn(dependentModule, result); - } - else { - result.add(dependentModule); - } - break; - } - } - } + var tmpSet = collectTransitivelyDependentModules(moduleEntity, WorkspaceModel.getInstance(project).getCurrentSnapshot()); + ProgressManager.checkCanceled(); + for (var dependentModule : tmpSet) { + var legacyModule = legacyBridge.findLegacyModule(dependentModule); + if (legacyModule != null) + result.add(legacyModule); } } diff --git a/platform/projectModel-api/src/com/intellij/workspaceModel/ide/legacyBridge/WorkspaceModelLegacyBridge.kt b/platform/projectModel-api/src/com/intellij/workspaceModel/ide/legacyBridge/WorkspaceModelLegacyBridge.kt new file mode 100644 index 000000000000..e96e5b698fc8 --- /dev/null +++ b/platform/projectModel-api/src/com/intellij/workspaceModel/ide/legacyBridge/WorkspaceModelLegacyBridge.kt @@ -0,0 +1,14 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.workspaceModel.ide.legacyBridge + +import com.intellij.openapi.module.Module +import com.intellij.platform.workspace.jps.entities.ModuleEntity +import com.intellij.platform.workspace.storage.EntityStorage +import org.jetbrains.annotations.ApiStatus + +@ApiStatus.Obsolete +interface WorkspaceModelLegacyBridge { + fun findModuleEntity(module: Module): ModuleEntity? + + fun findLegacyModule(moduleEntity: ModuleEntity): Module? +} diff --git a/platform/projectModel-impl/resources/META-INF/ProjectModelImpl.xml b/platform/projectModel-impl/resources/META-INF/ProjectModelImpl.xml index c117eeaecbe4..a31d284a6e1e 100644 --- a/platform/projectModel-impl/resources/META-INF/ProjectModelImpl.xml +++ b/platform/projectModel-impl/resources/META-INF/ProjectModelImpl.xml @@ -29,6 +29,8 @@ serviceImplementation="com.intellij.openapi.roots.impl.libraries.LibraryTablesRegistrarImpl"/> + diff --git a/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/legacyBridge/WorkspaceModelLegacyBridgeImpl.kt b/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/legacyBridge/WorkspaceModelLegacyBridgeImpl.kt new file mode 100644 index 000000000000..ba91f192836d --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/legacyBridge/WorkspaceModelLegacyBridgeImpl.kt @@ -0,0 +1,18 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.workspaceModel.ide.legacyBridge + +import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project +import com.intellij.platform.backend.workspace.workspaceModel +import com.intellij.platform.workspace.jps.entities.ModuleEntity +import org.jetbrains.annotations.ApiStatus + +@ApiStatus.Obsolete +internal class WorkspaceModelLegacyBridgeImpl(private val project: Project): WorkspaceModelLegacyBridge { + override fun findModuleEntity(module: Module): ModuleEntity? = + module.findModuleEntity(project.workspaceModel.currentSnapshot) + + override fun findLegacyModule(moduleEntity: ModuleEntity): Module? = + moduleEntity.findModule(project.workspaceModel.currentSnapshot) + +} diff --git a/platform/workspace/jps/api-dump.txt b/platform/workspace/jps/api-dump.txt index c77f4cce4949..bdae79c92661 100644 --- a/platform/workspace/jps/api-dump.txt +++ b/platform/workspace/jps/api-dump.txt @@ -684,6 +684,7 @@ f:com.intellij.platform.workspace.jps.entities.ExcludeUrlEntity$Companion - f:create(com.intellij.platform.workspace.storage.url.VirtualFileUrl,com.intellij.platform.workspace.storage.EntitySource,kotlin.jvm.functions.Function1):com.intellij.platform.workspace.jps.entities.ExcludeUrlEntity$Builder - bs:create$default(com.intellij.platform.workspace.jps.entities.ExcludeUrlEntity$Companion,com.intellij.platform.workspace.storage.url.VirtualFileUrl,com.intellij.platform.workspace.storage.EntitySource,kotlin.jvm.functions.Function1,I,java.lang.Object):com.intellij.platform.workspace.jps.entities.ExcludeUrlEntity$Builder f:com.intellij.platform.workspace.jps.entities.ExtensionsKt +- sf:collectTransitivelyDependentModules(com.intellij.platform.workspace.jps.entities.ModuleEntity,com.intellij.platform.workspace.storage.EntityStorage):java.util.Set - sf:getModuleLibraries(com.intellij.platform.workspace.jps.entities.ModuleEntity,com.intellij.platform.workspace.storage.EntityStorage):kotlin.sequences.Sequence - sf:getProjectLibraries(com.intellij.platform.workspace.storage.EntityStorage):kotlin.sequences.Sequence - sf:getSourceRoots(com.intellij.platform.workspace.jps.entities.ModuleEntity):java.util.List diff --git a/platform/workspace/jps/src/com/intellij/platform/workspace/jps/entities/extensions.kt b/platform/workspace/jps/src/com/intellij/platform/workspace/jps/entities/extensions.kt index 3dd1232e5351..e6d00ed011bd 100644 --- a/platform/workspace/jps/src/com/intellij/platform/workspace/jps/entities/extensions.kt +++ b/platform/workspace/jps/src/com/intellij/platform/workspace/jps/entities/extensions.kt @@ -2,6 +2,7 @@ package com.intellij.platform.workspace.jps.entities import com.intellij.platform.workspace.storage.EntityStorage +import com.intellij.platform.workspace.storage.referrers val ModuleEntity.sourceRoots: List get() = contentRoots.flatMap { it.sourceRoots } @@ -14,3 +15,20 @@ fun ModuleEntity.getModuleLibraries(storage: EntityStorage): Sequence get() = entities(LibraryEntity::class.java).filter { it.symbolicId.tableId == LibraryTableId.ProjectLibraryTableId } + +fun ModuleEntity.collectTransitivelyDependentModules(storage: EntityStorage): Set { + val result = mutableSetOf(this) + + fun collectDependentModulesRecursively(module: ModuleEntity) { + for (referrer in storage.referrers(module.symbolicId)) { + val dependency = referrer.dependencies.filterIsInstance().find { it.module == module.symbolicId } ?: continue + val added = result.add(referrer) + if (added && dependency.exported) { + collectDependentModulesRecursively(referrer) + } + } + } + + collectDependentModulesRecursively(this) + return result +} diff --git a/platform/workspace/storage/src/com/intellij/platform/workspace/storage/EntityStorage.kt b/platform/workspace/storage/src/com/intellij/platform/workspace/storage/EntityStorage.kt index 4fdcc6150b77..4896ffbfd746 100644 --- a/platform/workspace/storage/src/com/intellij/platform/workspace/storage/EntityStorage.kt +++ b/platform/workspace/storage/src/com/intellij/platform/workspace/storage/EntityStorage.kt @@ -59,6 +59,13 @@ public inline fun EntityStorage.entities(): Sequenc return this.entities(E::class.java) } +/** + * Kotlin shortcut for `EntityStorage.referrers(id, E::class.java)`. + */ +public inline fun EntityStorage.referrers(id: SymbolicEntityId): Sequence { + return this.referrers(id, E::class.java) +} + /** * An immutable snapshot of the storage state. * It isn't affected by the further modifications of the storage.