[IJPL-166430] Refactor com.intellij.openapi.module.ModuleUtilCore#collectModulesDependsOn

introduce WorkspaceModelLegacyBridge; collectModulesDependsOn via WSM edition

Merge-request: IJ-MR-148336
Merged-by: Kirill Bochkarev <podockonnik@gmail.com>

(cherry picked from commit fab2218a8b90eac677c3c9408af4319a842cf3fb)

IJ-CR-149781

GitOrigin-RevId: ee7277e9ddb6587d445ca7029ba4f89eb905ee86
This commit is contained in:
Kirill Bochkarev
2024-11-11 17:27:05 +00:00
committed by intellij-monorepo-bot
parent 89e0d237d4
commit 5f38ba337c
8 changed files with 90 additions and 21 deletions

View File

@@ -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

View File

@@ -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<Module> KEY_MODULE = new Key<>("Module");
@@ -169,33 +178,30 @@ public class ModuleUtilCore {
}
/**
* collect transitive module dependants
* <h3>Obsolescence notice</h3>
* This method uses
* {@link com.intellij.platform.workspace.jps.entities.ExtensionsKt#collectTransitivelyDependentModules(ModuleEntity, EntityStorage)},
* and remains for compatibility.
* <p>
*
* 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<? super Module> 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<Module> 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);
}
}

View File

@@ -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?
}

View File

@@ -29,6 +29,8 @@
serviceImplementation="com.intellij.openapi.roots.impl.libraries.LibraryTablesRegistrarImpl"/>
<applicationService serviceInterface="com.intellij.workspaceModel.ide.legacyBridge.SourceRootTypeRegistry"
serviceImplementation="com.intellij.workspaceModel.ide.impl.legacyBridge.module.roots.SourceRootTypeRegistryImpl"/>
<projectService serviceInterface="com.intellij.workspaceModel.ide.legacyBridge.WorkspaceModelLegacyBridge"
serviceImplementation="com.intellij.workspaceModel.ide.legacyBridge.WorkspaceModelLegacyBridgeImpl"/>
<!-- Global Workspace Model -->
<applicationService serviceInterface="com.intellij.workspaceModel.ide.JpsGlobalModelSynchronizer"
serviceImplementation="com.intellij.workspaceModel.ide.impl.jps.serialization.JpsGlobalModelSynchronizerImpl"/>

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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<SourceRootEntity>
get() = contentRoots.flatMap { it.sourceRoots }
@@ -14,3 +15,20 @@ fun ModuleEntity.getModuleLibraries(storage: EntityStorage): Sequence<LibraryEnt
val EntityStorage.projectLibraries: Sequence<LibraryEntity>
get() = entities(LibraryEntity::class.java).filter { it.symbolicId.tableId == LibraryTableId.ProjectLibraryTableId }
fun ModuleEntity.collectTransitivelyDependentModules(storage: EntityStorage): Set<ModuleEntity> {
val result = mutableSetOf(this)
fun collectDependentModulesRecursively(module: ModuleEntity) {
for (referrer in storage.referrers<ModuleEntity>(module.symbolicId)) {
val dependency = referrer.dependencies.filterIsInstance<ModuleDependency>().find { it.module == module.symbolicId } ?: continue
val added = result.add(referrer)
if (added && dependency.exported) {
collectDependentModulesRecursively(referrer)
}
}
}
collectDependentModulesRecursively(this)
return result
}

View File

@@ -59,6 +59,13 @@ public inline fun <reified E: WorkspaceEntity> EntityStorage.entities(): Sequenc
return this.entities(E::class.java)
}
/**
* Kotlin shortcut for `EntityStorage.referrers(id, E::class.java)`.
*/
public inline fun <reified E: WorkspaceEntityWithSymbolicId> EntityStorage.referrers(id: SymbolicEntityId<E>): Sequence<E> {
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.