From 4d3376bd64f86b0864630bf64143d0b785510457 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Wed, 14 May 2025 19:47:00 +0300 Subject: [PATCH] PY-79488 Get rid of the "Module" term in the API names "External Project" is a better name. IJ Module is an implementation detail. It could easily be another entity. GitOrigin-RevId: d263f110d2851d11fb411ef93d973e5e05eeff05 --- .../projectModel/BaseProjectModelService.kt | 7 +++--- .../poetry/PoetryProjectModelResolver.kt | 18 +++++++-------- .../python/projectModel/projectModel.kt | 22 +++++++++---------- .../projectModel/uv/UvProjectModelResolver.kt | 20 ++++++++--------- 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/python/src/com/jetbrains/python/projectModel/BaseProjectModelService.kt b/python/src/com/jetbrains/python/projectModel/BaseProjectModelService.kt index 63e0c1bb9064..fdae5691fab1 100644 --- a/python/src/com/jetbrains/python/projectModel/BaseProjectModelService.kt +++ b/python/src/com/jetbrains/python/projectModel/BaseProjectModelService.kt @@ -6,7 +6,6 @@ import com.intellij.openapi.util.NlsSafe import com.intellij.platform.backend.workspace.workspaceModel import com.intellij.platform.ide.progress.withBackgroundProgress import com.intellij.platform.workspace.jps.entities.* -import com.intellij.platform.workspace.jps.entities.ModuleDependency import com.intellij.platform.workspace.storage.EntitySource import com.intellij.platform.workspace.storage.EntityStorage import com.intellij.platform.workspace.storage.MutableEntityStorage @@ -78,7 +77,7 @@ abstract class BaseProjectModelService { if (graph.isEmpty()) { return } - val allModules = graph.flatMap { it.modules } + val allModules = graph.flatMap { it.projects } val storage = createProjectModel(project, allModules, source) project.workspaceModel.update("$systemName sync at ${projectRoot}") { mutableStorage -> // Fake module entity is added by default if nothing was discovered @@ -95,7 +94,7 @@ abstract class BaseProjectModelService { private fun createProjectModel( project: Project, - graph: List, + graph: List, source: EntitySource, ): EntityStorage { val fileUrlManager = project.workspaceModel.getVirtualFileUrlManager() @@ -112,7 +111,7 @@ abstract class BaseProjectModelService { storage addEntity ModuleEntity(module.name, emptyList(), source) { dependencies += sdkDependency dependencies += ModuleSourceDependency - for (moduleName in module.moduleDependencies) { + for (moduleName in module.dependencies) { dependencies += ModuleDependency(ModuleId(moduleName.name), true, DependencyScope.COMPILE, false) } contentRoots = listOf(ContentRootEntity(module.root.toVirtualFileUrl(fileUrlManager), emptyList(), source)) diff --git a/python/src/com/jetbrains/python/projectModel/poetry/PoetryProjectModelResolver.kt b/python/src/com/jetbrains/python/projectModel/poetry/PoetryProjectModelResolver.kt index 839e3e72f31d..fecf69e34b87 100644 --- a/python/src/com/jetbrains/python/projectModel/poetry/PoetryProjectModelResolver.kt +++ b/python/src/com/jetbrains/python/projectModel/poetry/PoetryProjectModelResolver.kt @@ -1,9 +1,9 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.jetbrains.python.projectModel.poetry -import com.jetbrains.python.projectModel.ModuleDependency -import com.jetbrains.python.projectModel.ModuleDescriptor -import com.jetbrains.python.projectModel.ProjectModelGraph +import com.jetbrains.python.projectModel.ExternalProject +import com.jetbrains.python.projectModel.ExternalProjectDependency +import com.jetbrains.python.projectModel.ExternalProjectGraph import com.jetbrains.python.projectModel.PythonProjectModelResolver import org.apache.tuweni.toml.Toml import org.apache.tuweni.toml.TomlTable @@ -12,7 +12,7 @@ import kotlin.io.path.* @OptIn(ExperimentalPathApi::class) object PoetryProjectModelResolver : PythonProjectModelResolver { - override fun discoverProjectRootSubgraph(root: Path): ProjectModelGraph? { + override fun discoverProjectRootSubgraph(root: Path): ExternalProjectGraph? { if (!root.resolve(PoetryConstants.PYPROJECT_TOML).exists()) { return null } @@ -23,16 +23,16 @@ object PoetryProjectModelResolver : PythonProjectModelResolver { if (poetryProjects.isNotEmpty()) { val modules = poetryProjects .map { - ModuleDescriptor( + ExternalProject( name = it.projectName, root = it.root, - moduleDependencies = it.editablePathDependencies.map { entry -> - ModuleDependency(entry.key, entry.value) + dependencies = it.editablePathDependencies.map { entry -> + ExternalProjectDependency(entry.key, entry.value) }) } - return ProjectModelGraph( + return ExternalProjectGraph( root = root, - modules = modules + projects = modules ) } return null diff --git a/python/src/com/jetbrains/python/projectModel/projectModel.kt b/python/src/com/jetbrains/python/projectModel/projectModel.kt index d5504dacbd67..67ee98a81fc8 100644 --- a/python/src/com/jetbrains/python/projectModel/projectModel.kt +++ b/python/src/com/jetbrains/python/projectModel/projectModel.kt @@ -12,15 +12,15 @@ import kotlin.io.path.visitFileTree * These modules might depend on each other, but it's not a requirement. * The root itself can be a valid module root, but it's not a requirement. */ -data class ProjectModelGraph(val root: Path, val modules: List) +data class ExternalProjectGraph(val root: Path, val projects: List) /** * Defines a project module in a particular directory with its unique name, and a set of module dependencies * (usually editable Python path dependencies to other modules in the same IJ project). */ -data class ModuleDescriptor(val name: String, val root: Path, val moduleDependencies: List) +data class ExternalProject(val name: String, val root: Path, val dependencies: List) -data class ModuleDependency(val name: String, val path: Path) +data class ExternalProjectDependency(val name: String, val path: Path) interface PythonProjectModelResolver { /** @@ -41,7 +41,7 @@ interface PythonProjectModelResolver { * this method should return `null` for `libs/` but module graphs containing *only* modules `project1` and `project2` * for the directories `project1/` and `project2` respectively, even if there is a dependency between them. */ - fun discoverProjectRootSubgraph(root: Path): ProjectModelGraph? + fun discoverProjectRootSubgraph(root: Path): ExternalProjectGraph? /** * Find all project model graphs within the given directory (presumably the root directory of an IJ project). @@ -61,8 +61,8 @@ interface PythonProjectModelResolver { * If these two projects are independents, there will be two graphs for `project1` and `project2` respectively. */ @OptIn(ExperimentalPathApi::class) - fun discoverIndependentProjectGraphs(root: Path): List { - val graphs = mutableListOf() + fun discoverIndependentProjectGraphs(root: Path): List { + val graphs = mutableListOf() root.visitFileTree { onPreVisitDirectory { dir, _ -> val buildSystemRoot = discoverProjectRootSubgraph(dir) @@ -91,22 +91,22 @@ interface ProjectModelSyncListener { fun onFinish(projectRoot: Path): Unit = Unit } -private fun mergeRootsReferringToEachOther(roots: MutableList): List { +private fun mergeRootsReferringToEachOther(roots: MutableList): List { fun commonAncestorPath(paths: Iterable): Path { val normalized = paths.map { it.normalize() } return normalized.reduce { p1, p2 -> FileUtil.findAncestor(p1, p2)!! } } val expandedProjectRoots = roots.map { root -> - val allModuleRootsAndDependencies = root.modules.asSequence() - .flatMap { module -> listOf(module.root) + module.moduleDependencies.map { it.path } } + val allModuleRootsAndDependencies = root.projects.asSequence() + .flatMap { module -> listOf(module.root) + module.dependencies.map { it.path } } .distinct() .toList() root.copy(root = commonAncestorPath(allModuleRootsAndDependencies)) } val expandedProjectRootsByRootPath = expandedProjectRoots.sortedBy { it.root } - val mergedProjectRoots = mutableListOf() + val mergedProjectRoots = mutableListOf() for (root in expandedProjectRootsByRootPath) { if (mergedProjectRoots.isEmpty()) { mergedProjectRoots.add(root) @@ -114,7 +114,7 @@ private fun mergeRootsReferringToEachOther(roots: MutableList else { val lastCluster = mergedProjectRoots.last() if (root.root.startsWith(lastCluster.root)) { - mergedProjectRoots[mergedProjectRoots.lastIndex] = lastCluster.copy(modules = lastCluster.modules + root.modules) + mergedProjectRoots[mergedProjectRoots.lastIndex] = lastCluster.copy(projects = lastCluster.projects + root.projects) } else { mergedProjectRoots.add(root) diff --git a/python/src/com/jetbrains/python/projectModel/uv/UvProjectModelResolver.kt b/python/src/com/jetbrains/python/projectModel/uv/UvProjectModelResolver.kt index 1d320afe41c3..e1ddef05eb5d 100644 --- a/python/src/com/jetbrains/python/projectModel/uv/UvProjectModelResolver.kt +++ b/python/src/com/jetbrains/python/projectModel/uv/UvProjectModelResolver.kt @@ -2,9 +2,9 @@ package com.jetbrains.python.projectModel.uv import com.intellij.openapi.util.getPathMatcher -import com.jetbrains.python.projectModel.ModuleDependency -import com.jetbrains.python.projectModel.ModuleDescriptor -import com.jetbrains.python.projectModel.ProjectModelGraph +import com.jetbrains.python.projectModel.ExternalProject +import com.jetbrains.python.projectModel.ExternalProjectDependency +import com.jetbrains.python.projectModel.ExternalProjectGraph import com.jetbrains.python.projectModel.PythonProjectModelResolver import org.apache.tuweni.toml.Toml import org.apache.tuweni.toml.TomlTable @@ -15,7 +15,7 @@ private const val DEFAULT_VENV_DIR = ".venv" @OptIn(ExperimentalPathApi::class) object UvProjectModelResolver : PythonProjectModelResolver { - override fun discoverProjectRootSubgraph(root: Path): ProjectModelGraph? { + override fun discoverProjectRootSubgraph(root: Path): ExternalProjectGraph? { if (!root.resolve(UvConstants.PYPROJECT_TOML).exists()) { return null } @@ -48,20 +48,20 @@ object UvProjectModelResolver : PythonProjectModelResolver { }.associateBy { it.projectName } } - return ProjectModelGraph( + return ExternalProjectGraph( root = root, - modules = allUvProjects + projects = allUvProjects .map { uvProject -> - val pathDependencies = uvProject.editablePathDependencies.map { ModuleDependency(it.key, it.value) } + val pathDependencies = uvProject.editablePathDependencies.map { ExternalProjectDependency(it.key, it.value) } val resolvedWorkspaceDependencies = uvProject.workspaceDependencies.mapNotNull { val workspaceMember = workspaceMembers[it] - if (workspaceMember != null) ModuleDependency(it, workspaceMember.root) + if (workspaceMember != null) ExternalProjectDependency(it, workspaceMember.root) else null } - ModuleDescriptor( + ExternalProject( name = uvProject.projectName, root =uvProject.root, - moduleDependencies = pathDependencies + resolvedWorkspaceDependencies + dependencies = pathDependencies + resolvedWorkspaceDependencies ) } )