From a97aba849831fe8c4e190ddb03b2fdd827fa8298 Mon Sep 17 00:00:00 2001 From: Liudmila Kornilova Date: Tue, 18 Nov 2025 13:40:47 +0100 Subject: [PATCH] [WSM] IJPL-218899 PythonFacetConfiguration may try to search for an SDK in ProjectJdkTable before SDKs were applied to the project WSM GitOrigin-RevId: 9b6a750172c7e87994288d2ec28713f2193fc899 --- .../module/ModuleBridgeLoaderService.kt | 14 ++++++++++++-- .../module/ModuleManagerComponentBridge.kt | 4 +++- .../legacyBridge/module/ModuleManagerBridgeImpl.kt | 5 +++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleBridgeLoaderService.kt b/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleBridgeLoaderService.kt index b6e8c53db0c1..980500203cc0 100644 --- a/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleBridgeLoaderService.kt +++ b/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleBridgeLoaderService.kt @@ -31,6 +31,7 @@ import com.intellij.workspaceModel.ide.impl.jpsMetrics import com.intellij.workspaceModel.ide.impl.legacyBridge.library.ProjectLibraryTableBridgeImpl import com.intellij.workspaceModel.ide.impl.legacyBridge.project.ProjectRootManagerBridge import io.opentelemetry.api.metrics.Meter +import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch @@ -65,6 +66,7 @@ private class ModuleBridgeLoaderService : InitProjectActivity { val start = Milliseconds.now() if (workspaceModel.loadedFromCache) { + val globalWsmAppliedToProjectWsm = CompletableDeferred() span("modules loading with cache") { if (projectModelSynchronizer.hasNoSerializedJpsModules()) { LOG.warn("Loaded from cache, but no serialized modules found. " + @@ -78,11 +80,17 @@ private class ModuleBridgeLoaderService : InitProjectActivity { targetUnloadedEntitiesBuilder = null, loadedFromCache = workspaceModel.loadedFromCache, workspaceModel = workspaceModel, + globalWsmAppliedToProjectWsm = globalWsmAppliedToProjectWsm, ) } val globalWorkspaceModel = GlobalWorkspaceModel.getInstanceAsync(project.getEelDescriptor().machine) backgroundWriteAction { - globalWorkspaceModel.applyStateToProject(project) + try { + globalWorkspaceModel.applyStateToProject(project) + } + finally { + globalWsmAppliedToProjectWsm.complete(project) + } } } else { @@ -137,6 +145,7 @@ private suspend fun loadModules( targetBuilder: MutableEntityStorage?, targetUnloadedEntitiesBuilder: MutableEntityStorage?, loadedFromCache: Boolean, + globalWsmAppliedToProjectWsm: CompletableDeferred? = null, ) { span("modules instantiation") { val moduleManager = project.serviceAsync() as ModuleManagerComponentBridge @@ -153,7 +162,8 @@ private suspend fun loadModules( moduleManager.loadModules(loadedEntities = entities, unloadedEntities = unloadedEntities, targetBuilder = targetBuilder, - initializeFacets = loadedFromCache) + initializeFacets = loadedFromCache, + globalWsmAppliedToProjectWsm) } span("libraries instantiation") { diff --git a/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerComponentBridge.kt b/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerComponentBridge.kt index 92847c629604..a071ce1feb76 100644 --- a/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerComponentBridge.kt +++ b/platform/lang-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerComponentBridge.kt @@ -41,6 +41,7 @@ import com.intellij.workspaceModel.ide.impl.legacyBridge.module.roots.ModuleRoot import com.intellij.workspaceModel.ide.impl.legacyBridge.project.ModuleRootListenerBridgeImpl import com.intellij.workspaceModel.ide.legacyBridge.ModuleBridge import com.intellij.workspaceModel.ide.toPath +import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -169,8 +170,9 @@ open class ModuleManagerComponentBridge(private val project: Project, coroutineS return moduleEntity } - final override fun initFacets(modules: Collection>) { + final override fun initFacets(modules: Collection>, globalWsmAppliedToProjectWsm: CompletableDeferred?) { coroutineScope.launch(CoroutineName("init facets")) { + globalWsmAppliedToProjectWsm?.await() // PythonFacetConfiguration expects to find an SDK by its name in ProjectJdkTable (which looks it up in project WSM) ModuleBridgeImpl.initFacets(modules = modules, project = project) } } diff --git a/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerBridgeImpl.kt b/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerBridgeImpl.kt index 5beb98890a7d..86ca8d201dbf 100644 --- a/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerBridgeImpl.kt +++ b/platform/projectModel-impl/src/com/intellij/workspaceModel/ide/impl/legacyBridge/module/ModuleManagerBridgeImpl.kt @@ -187,6 +187,7 @@ abstract class ModuleManagerBridgeImpl( unloadedEntities: List, targetBuilder: MutableEntityStorage?, initializeFacets: Boolean, + globalWsmAppliedToProjectWsm: CompletableDeferred?, ): Unit = loadAllModulesTimeMs.addMeasuredTime { LOG.debug { "Loading modules for ${loadedEntities.size} entities: [${loadedEntities.joinToString { it.name }}]" } @@ -218,7 +219,7 @@ abstract class ModuleManagerBridgeImpl( // Facets that are loaded from the cache do not generate "EntityAdded" event and aren't initialized // We initialize the facets manually here (after modules loading). if (initializeFacets) { - initFacets(result) + initFacets(result, globalWsmAppliedToProjectWsm) } coroutineScope.launch { @@ -247,7 +248,7 @@ abstract class ModuleManagerBridgeImpl( } } - protected open fun initFacets(modules: Collection>) { + protected open fun initFacets(modules: Collection>, globalWsmAppliedToProjectWsm: CompletableDeferred?) { } final override fun calculateUnloadModules(