PY-87889: Fix module root duplication.

Apparently, the result of `createEntitySource` can't be reused.
It acts as a key in a map, so using same source for different modules breaks everything.

Test checks it, and we also need to disable external storage to store files in `.idea`


(cherry picked from commit 796b582d4d3cde9158d9fcfae910cde54886c24b)

IJ-CR-193095

GitOrigin-RevId: 8e117832070c1dff3e5ad6970908eb43208f73c4
This commit is contained in:
Ilya.Kazakevich
2026-02-24 15:12:47 +00:00
committed by intellij-monorepo-bot
parent 83445d4a75
commit bb9eaa515c
2 changed files with 20 additions and 3 deletions
@@ -1,5 +1,6 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:JvmName("ProjectUtilCore")
package com.intellij.openapi.project
import com.intellij.ide.highlighter.ProjectFileType
@@ -18,6 +19,7 @@ import com.intellij.util.PathUtil
import com.intellij.util.PlatformUtils
import com.intellij.util.io.URLUtil
import com.intellij.workspaceModel.ide.presentableName
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.TestOnly
@NlsSafe
@@ -106,6 +108,21 @@ val Project.isExternalStorageEnabled: Boolean
*/
@TestOnly
fun doNotEnableExternalStorageByDefaultInTests(action: () -> Unit) {
doNotEnableExternalStorageByDefaultInTestsImpl(action)
}
/**
* @see [doNotEnableExternalStorageByDefaultInTests]
*/
@ApiStatus.Internal
@TestOnly
suspend fun doNotEnableExternalStorageByDefaultInTestsSuspend(action: suspend () -> Unit) {
doNotEnableExternalStorageByDefaultInTestsImpl {
action()
}
}
private inline fun doNotEnableExternalStorageByDefaultInTestsImpl(action: () -> Unit) {
enableExternalStorageByDefaultInTests = false
try {
action()
@@ -113,4 +130,4 @@ fun doNotEnableExternalStorageByDefaultInTests(action: () -> Unit) {
finally {
enableExternalStorageByDefaultInTests = true
}
}
}
@@ -212,9 +212,8 @@ private suspend fun createProjectModel(
): ImmutableEntityStorage = withContext(Dispatchers.Default) {
val virtualFileUrlManager = project.workspaceModel.getVirtualFileUrlManager()
val storage = MutableEntityStorage.create()
val entitySource = createEntitySource(project)
for (pyProject in graph) {
val moduleEntity = storage addEntity ModuleEntity(pyProject.name.name, emptyList(), entitySource) {
val moduleEntity = storage addEntity ModuleEntity(pyProject.name.name, emptyList(), createEntitySource(project)) {
dependencies += ModuleSourceDependency
for (moduleName in pyProject.dependencies) {
dependencies += ModuleDependency(ModuleId(moduleName.name), true, DependencyScope.COMPILE, false)
@@ -312,6 +311,7 @@ private class ModuleAnchor(moduleEntity: ModuleEntity) {
(theOnlyContentRoot != null && theOnlyContentRoot.url == o.theOnlyContentRoot?.url)
}
// Warning: this entity must be unique for each model, it can't be reused
internal fun createEntitySource(project: Project): EntitySource {
val moduleRoot =
project.stateStore.projectBasePath.resolve(DIRECTORY_STORE_FOLDER).toVirtualFileUrl(project.workspaceModel.getVirtualFileUrlManager())