mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-79486: (WIP) Fix backend call to detect modules, show icon for pythons.
It is not possible to use topics to access the backend. Only RPC API must be used. Moreover, registry settings require restart. GitOrigin-RevId: 965ed41d17350ab0b24b36eb53edf23fba95c4af
This commit is contained in:
committed by
intellij-monorepo-bot
parent
13adc74931
commit
7a97e9f027
-4
@@ -16,10 +16,6 @@
|
||||
<rpc.backend.remoteApiProvider implementation="com.intellij.python.sdkConfigurator.backend.impl.rpcBridge.ApiProvider"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<platform.rpc.projectRemoteTopicListener
|
||||
implementation="com.intellij.python.sdkConfigurator.backend.impl.rpcBridge.BackendTopicListener"/>
|
||||
</extensions>
|
||||
<actions>
|
||||
<action class="com.intellij.python.sdkConfigurator.backend.impl.platformBridge.ConfigureSDKAction" id="ConfigureSDKAction"/>
|
||||
</actions>
|
||||
|
||||
@@ -30,9 +30,20 @@ import kotlinx.coroutines.withContext
|
||||
|
||||
private val askUserMutex = Mutex()
|
||||
|
||||
// TODO: DOC
|
||||
internal fun configureSdkAskingUser(project: Project) {
|
||||
/**
|
||||
* Same as [configureSdkAutomatically] but in a separate coroutine
|
||||
*/
|
||||
internal fun configureSdkAskingUserBg(project: Project) {
|
||||
project.service<MyService>().scope.launch(Dispatchers.Default) {
|
||||
configureSdkAskingUser(project)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask user for list of modules and configure them
|
||||
*/
|
||||
internal suspend fun configureSdkAskingUser(project: Project) {
|
||||
withContext(Dispatchers.Default) {
|
||||
askUserMutex.withLock {
|
||||
val moduleToSuggestedSdk = getModulesWithoutSDK(project)
|
||||
if (moduleToSuggestedSdk.modules.isNotEmpty()) {
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@ import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUser
|
||||
import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUserBg
|
||||
import com.intellij.python.sdkConfigurator.common.enableSDKAutoConfigurator
|
||||
|
||||
internal class ConfigureSDKAction : AnAction() {
|
||||
@@ -13,7 +14,7 @@ internal class ConfigureSDKAction : AnAction() {
|
||||
if (!enableSDKAutoConfigurator) {
|
||||
return
|
||||
}
|
||||
configureSdkAskingUser(project)
|
||||
configureSdkAskingUserBg(project)
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
|
||||
+2
-3
@@ -3,9 +3,8 @@ package com.intellij.python.sdkConfigurator.backend.impl.platformBridge
|
||||
import com.intellij.openapi.extensions.ExtensionNotApplicableException
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.python.pyproject.model.api.ModelRebuiltListener
|
||||
import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUser
|
||||
import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUserBg
|
||||
import com.intellij.python.sdkConfigurator.common.enableSDKAutoConfigurator
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
|
||||
internal class ModelRebuiltListenerImpl : ModelRebuiltListener {
|
||||
init {
|
||||
@@ -15,7 +14,7 @@ internal class ModelRebuiltListenerImpl : ModelRebuiltListener {
|
||||
}
|
||||
|
||||
override fun modelRebuilt(project: Project) {
|
||||
configureSdkAskingUser(project)
|
||||
configureSdkAskingUserBg(project)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.intellij.python.sdkConfigurator.backend.impl.rpcBridge
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.platform.rpc.topics.ProjectRemoteTopic
|
||||
import com.intellij.platform.rpc.topics.ProjectRemoteTopicListener
|
||||
import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUser
|
||||
import com.intellij.python.sdkConfigurator.common.impl.DETECT_SDK_FOR_MODULES
|
||||
|
||||
internal class BackendTopicListener : ProjectRemoteTopicListener<Unit> {
|
||||
override val topic: ProjectRemoteTopic<Unit> = DETECT_SDK_FOR_MODULES
|
||||
|
||||
override fun handleEvent(project: Project, event: Unit) {
|
||||
configureSdkAskingUser(project)
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.intellij.python.sdkConfigurator.backend.impl.rpcBridge
|
||||
|
||||
import com.intellij.platform.project.ProjectId
|
||||
import com.intellij.platform.project.findProject
|
||||
import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAskingUser
|
||||
import com.intellij.python.sdkConfigurator.backend.impl.configureSdkAutomatically
|
||||
import com.intellij.python.sdkConfigurator.common.impl.ModuleName
|
||||
import com.intellij.python.sdkConfigurator.common.impl.SdkConfiguratorBackEndApi
|
||||
@@ -10,4 +11,8 @@ internal object SdkConfiguratorApiImpl : SdkConfiguratorBackEndApi {
|
||||
override suspend fun configureSdkAutomatically(projectId: ProjectId, onlyModules: Set<ModuleName>) {
|
||||
configureSdkAutomatically(projectId.findProject(), onlyModules)
|
||||
}
|
||||
|
||||
override suspend fun configureAskingUser(projectId: ProjectId) {
|
||||
configureSdkAskingUser(projectId.findProject())
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<registryKey defaultValue="false" description="Configure SDK for modules which lack thereof in automatic manner" key="intellij.python.sdkConfigurator.auto" restartRequired="false"/>
|
||||
<registryKey defaultValue="false" description="Configure SDK for modules which lack thereof in automatic manner" key="intellij.python.sdkConfigurator.auto" restartRequired="true"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.intellij.python.sdkConfigurator.common.impl
|
||||
|
||||
import com.intellij.platform.project.ProjectId
|
||||
import com.intellij.platform.rpc.RemoteApiProviderService
|
||||
import com.intellij.platform.rpc.topics.ProjectRemoteTopic
|
||||
import fleet.rpc.RemoteApi
|
||||
import fleet.rpc.Rpc
|
||||
import fleet.rpc.remoteApiDescriptor
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
@@ -12,9 +14,14 @@ import kotlinx.serialization.Serializable
|
||||
@Rpc
|
||||
interface SdkConfiguratorBackEndApi : RemoteApi<Unit> {
|
||||
/***
|
||||
* Configure SDK for all modules in [projectId] if their names in [onlyModules]
|
||||
* Configure SDK for all modules in [projectId] if their names in [onlyModules] unconditionally
|
||||
*/
|
||||
suspend fun configureSdkAutomatically(projectId: ProjectId, onlyModules: Set<ModuleName>)
|
||||
|
||||
/**
|
||||
* Ask user about modules, then call [configureSdkAutomatically]
|
||||
*/
|
||||
suspend fun configureAskingUser(projectId: ProjectId)
|
||||
}
|
||||
|
||||
typealias ModuleName = String
|
||||
@@ -29,4 +36,9 @@ val SHOW_SDK_CONFIG_UI_TOPIC: ProjectRemoteTopic<ModulesDTO> = ProjectRemoteTopi
|
||||
*/
|
||||
@Serializable
|
||||
data class ModulesDTO(val modules: Map<ModuleName, ModuleName?>) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [SdkConfiguratorBackEndApi] instance
|
||||
*/
|
||||
suspend fun SdkConfiguratorBackEndApi(): SdkConfiguratorBackEndApi = RemoteApiProviderService.resolve(remoteApiDescriptor<SdkConfiguratorBackEndApi>())
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.intellij.python.sdkConfigurator.common.impl
|
||||
|
||||
import com.intellij.platform.rpc.topics.ProjectRemoteTopic
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
/**
|
||||
* Backend listens for this topic to start SDK detection process
|
||||
*/
|
||||
val DETECT_SDK_FOR_MODULES: ProjectRemoteTopic<Unit> = ProjectRemoteTopic("PySDKConfigurationDetectSDKTopic", Unit.serializer())
|
||||
|
||||
@@ -2,8 +2,8 @@ package com.intellij.python.sdkConfigurator.common
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.platform.rpc.topics.sendToClient
|
||||
import com.intellij.python.sdkConfigurator.common.impl.DETECT_SDK_FOR_MODULES
|
||||
import com.intellij.platform.project.projectId
|
||||
import com.intellij.python.sdkConfigurator.common.impl.SdkConfiguratorBackEndApi
|
||||
|
||||
|
||||
/**
|
||||
@@ -11,14 +11,10 @@ import com.intellij.python.sdkConfigurator.common.impl.DETECT_SDK_FOR_MODULES
|
||||
*/
|
||||
val enableSDKAutoConfigurator: Boolean get() = Registry.`is`("intellij.python.sdkConfigurator.auto")
|
||||
|
||||
|
||||
/**
|
||||
* Check if [enableSDKAutoConfigurator] (return `false` if not) and start detecting process.
|
||||
* it might ask user for list of modules and then detect them
|
||||
* it might ask user for list of modules and then detect SDK for them
|
||||
*/
|
||||
fun detectSdkForModulesIn(project: Project): Boolean {
|
||||
if (!enableSDKAutoConfigurator) {
|
||||
return false
|
||||
}
|
||||
DETECT_SDK_FOR_MODULES.sendToClient(project, Unit)
|
||||
return true
|
||||
suspend fun detectSdkForModulesIn(project: Project) {
|
||||
SdkConfiguratorBackEndApi().configureAskingUser(project.projectId())
|
||||
}
|
||||
|
||||
+4
-1
@@ -1 +1,4 @@
|
||||
python.sdk.configurator.frontend.choose.modules.title=Choose Modules to Configure SDK For
|
||||
python.sdk.configurator.frontend.choose.modules.title=Configure Modules Environment
|
||||
python.sdk.configurator.frontend.choose.modules.text=Pick the ones you want to use to run code and set up environment for them
|
||||
python.sdk.configurator.frontend.choose.modules.project.structure=Project Structure
|
||||
python.sdk.configurator.frontend.choose.modules.environment=Environment
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
package com.intellij.python.sdkConfigurator.frontend.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableIntState
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.snapshots.SnapshotStateSet
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.intellij.python.sdkConfigurator.frontend.ModuleInfo
|
||||
import kotlinx.collections.immutable.ImmutableMap
|
||||
import org.jetbrains.jewel.ui.component.Checkbox
|
||||
import org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.jewel.foundation.theme.JewelTheme
|
||||
import org.jetbrains.jewel.ui.component.CheckboxRow
|
||||
import org.jetbrains.jewel.ui.component.Text
|
||||
import org.jetbrains.jewel.ui.component.VerticallyScrollableContainer
|
||||
|
||||
@@ -21,23 +22,42 @@ internal fun ModuleList(
|
||||
moduleItems: ImmutableMap<String, ModuleInfo>,
|
||||
checked: SnapshotStateSet<String>,
|
||||
onCheckChange: (String, Boolean) -> Unit,
|
||||
topLabel: @Nls String,
|
||||
projectStructureLabel: @Nls String,
|
||||
environmentLabel: @Nls String,
|
||||
) {
|
||||
VerticallyScrollableContainer {
|
||||
Column(Modifier.width(500.dp)) {
|
||||
for ((moduleName, moduleInfo) in moduleItems) {
|
||||
val (parent, pythons) = moduleInfo
|
||||
Row(Modifier.padding(2.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
val checked = moduleName in checked
|
||||
val elementToChange = parent ?: moduleName
|
||||
Checkbox(
|
||||
checked = checked,
|
||||
onCheckedChange = {
|
||||
onCheckChange(elementToChange, it)
|
||||
},
|
||||
)
|
||||
Text(moduleName, Modifier.padding(start = 1.dp).clickable(true, onClick = { onCheckChange(elementToChange, !checked) }))
|
||||
Spacer(Modifier.weight(1f))
|
||||
PythonsDropDown(pythons, Modifier.width(200.dp))
|
||||
val ts = JewelTheme.defaultTextStyle
|
||||
val padding = 2.dp
|
||||
val longestItemChars = remember { (listOf(projectStructureLabel) + moduleItems.keys).maxBy { it.length } }
|
||||
val leftColumnMinSize = measureText(longestItemChars, ts)
|
||||
val spaceBetweenCols = 16.dp
|
||||
Column(Modifier.padding(padding), verticalArrangement = Arrangement.spacedBy(padding)) {
|
||||
Text(topLabel, Modifier.padding(bottom = 10.dp))
|
||||
Row(Modifier, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween) {
|
||||
Text(projectStructureLabel, Modifier.width(leftColumnMinSize + spaceBetweenCols + padding + 26.dp)) //~ checkbox size
|
||||
Text(environmentLabel, textAlign = TextAlign.End)
|
||||
}
|
||||
val moduleItems = remember { moduleItems.entries.sortedBy { it.key } }
|
||||
VerticallyScrollableContainer {
|
||||
Column(Modifier, horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.spacedBy(padding)) {
|
||||
for ((moduleName, moduleInfo) in moduleItems) {
|
||||
val (parent, pythons) = moduleInfo
|
||||
Row(Modifier.padding(padding), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(spaceBetweenCols)) {
|
||||
val checked = moduleName in checked
|
||||
val elementToChange = parent ?: moduleName // TODO: move logic out of UI
|
||||
CheckboxRow(
|
||||
moduleName,
|
||||
checked = checked,
|
||||
onCheckedChange = {
|
||||
onCheckChange(elementToChange, it)
|
||||
},
|
||||
textStyle = ts,
|
||||
textModifier = Modifier.width(leftColumnMinSize)
|
||||
)
|
||||
if (parent == null) {
|
||||
PythonsDropDown(pythons)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,40 @@
|
||||
package com.intellij.python.sdkConfigurator.frontend.components
|
||||
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import org.jetbrains.jewel.foundation.ExperimentalJewelApi
|
||||
import org.jetbrains.jewel.foundation.theme.JewelTheme
|
||||
import org.jetbrains.jewel.ui.component.ListComboBox
|
||||
import org.jetbrains.jewel.ui.component.SimpleListItem
|
||||
import org.jetbrains.jewel.ui.icons.AllIconsKeys.Language.Python
|
||||
|
||||
@OptIn(ExperimentalJewelApi::class)
|
||||
@Composable
|
||||
internal fun PythonsDropDown(pythons: ImmutableList<String>, modifier: Modifier = Modifier) {
|
||||
internal fun PythonsDropDown(pythons: ImmutableList<String>, grayedOut: Boolean = false, modifier: Modifier = Modifier) {
|
||||
val ts = JewelTheme.defaultTextStyle
|
||||
val longestPython = remember { pythons.maxBy { it.length } }
|
||||
val padding = 100.dp
|
||||
val width = measureText(longestPython, ts) + padding // Padding
|
||||
var i by remember { mutableIntStateOf(0) }
|
||||
ListComboBox(pythons, i, { i = it }, modifier)
|
||||
ListComboBox(
|
||||
items = pythons,
|
||||
selectedIndex = i,
|
||||
modifier = modifier.widthIn(min = width, max = width + padding),
|
||||
onSelectedItemChange = { i = it },
|
||||
itemKeys = { index, _ -> index },
|
||||
itemContent = { item, isSelected, isActive ->
|
||||
SimpleListItem(
|
||||
text = item,
|
||||
selected = isSelected,
|
||||
active = isActive,
|
||||
icon = Python,
|
||||
colorFilter = if (grayedOut) ColorFilter.tint(Color.Gray) else null,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.intellij.python.sdkConfigurator.frontend.components
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.rememberTextMeasurer
|
||||
import androidx.compose.ui.unit.Dp
|
||||
|
||||
@Composable
|
||||
internal fun measureText(text: String, textStyle: TextStyle): Dp {
|
||||
val textMeasurer = rememberTextMeasurer()
|
||||
return with(LocalDensity.current) {
|
||||
textMeasurer.measure(text, textStyle).size.width.toDp()
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
/**
|
||||
* Front-end implementation, do not access directly
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
package com.intellij.python.sdkConfigurator.frontend;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.intellij.platform.rpc.topics.ProjectRemoteTopic
|
||||
import com.intellij.platform.rpc.topics.ProjectRemoteTopicListener
|
||||
import com.intellij.python.sdkConfigurator.common.impl.ModulesDTO
|
||||
import com.intellij.python.sdkConfigurator.common.impl.SHOW_SDK_CONFIG_UI_TOPIC
|
||||
import com.intellij.python.sdkConfigurator.common.impl.SdkConfiguratorBackEndApi
|
||||
import com.intellij.python.sdkConfigurator.frontend.askUser
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -22,7 +23,7 @@ internal class FrontendTopicListener : ProjectRemoteTopicListener<ModulesDTO> {
|
||||
// Ask user to choose modules, then ask backend to configure it
|
||||
askUser(project, event) { modulesChosenByUser ->
|
||||
scope.launch {
|
||||
getBackendApi().configureSdkAutomatically(project.projectId(), modulesChosenByUser)
|
||||
SdkConfiguratorBackEndApi().configureSdkAutomatically(project.projectId(), modulesChosenByUser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package com.intellij.python.sdkConfigurator.frontend.rpcBridge
|
||||
|
||||
import com.intellij.platform.rpc.RemoteApiProviderService
|
||||
import com.intellij.python.sdkConfigurator.common.impl.SdkConfiguratorBackEndApi
|
||||
import fleet.rpc.remoteApiDescriptor
|
||||
|
||||
|
||||
internal suspend fun getBackendApi() = RemoteApiProviderService.resolve(remoteApiDescriptor<SdkConfiguratorBackEndApi>())
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
import com.intellij.python.sdkConfigurator.common.impl.ModuleName
|
||||
import com.intellij.python.sdkConfigurator.common.impl.ModulesDTO
|
||||
import com.intellij.python.sdkConfigurator.frontend.PySdkConfiguratorFrontendBundle.message
|
||||
import com.intellij.python.sdkConfigurator.frontend.components.ModuleList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -28,7 +29,8 @@ internal suspend fun askUser(project: Project, modules: ModulesDTO, onResult: (S
|
||||
private class MyDialog(project: Project, private val viewModel: ModulesViewModel) : DialogWrapper(project) {
|
||||
|
||||
init {
|
||||
title = PySdkConfiguratorFrontendBundle.message("python.sdk.configurator.frontend.choose.modules.title")
|
||||
title = message("python.sdk.configurator.frontend.choose.modules.title")
|
||||
isResizable = false
|
||||
init()
|
||||
}
|
||||
|
||||
@@ -36,7 +38,10 @@ private class MyDialog(project: Project, private val viewModel: ModulesViewModel
|
||||
override fun createCenterPanel(): JComponent {
|
||||
enableNewSwingCompositing()
|
||||
return compose(focusOnClickInside = true, content = {
|
||||
ModuleList(viewModel.checkBoxItems, viewModel.checked, viewModel::clicked)
|
||||
ModuleList(viewModel.checkBoxItems, viewModel.checked, viewModel::clicked,
|
||||
topLabel = message("python.sdk.configurator.frontend.choose.modules.text"),
|
||||
projectStructureLabel = message("python.sdk.configurator.frontend.choose.modules.project.structure"),
|
||||
environmentLabel = message("python.sdk.configurator.frontend.choose.modules.environment"))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.intellij.python.sdkConfigurator.common.PublicApiKt.detectSdkForModulesIn;
|
||||
import static com.jetbrains.python.inspections.PyInterpreterInspectionExKt.detectSdkForModulesForJvmIn;
|
||||
import static com.jetbrains.python.inspections.PyInterpreterInspectionExKt.findAllSortedForModuleForJvm;
|
||||
|
||||
|
||||
@@ -343,7 +343,7 @@ public final class PyInterpreterInspection extends PyInspection {
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
if (!detectSdkForModulesIn(project)) {
|
||||
if (!detectSdkForModulesForJvmIn(project)) {
|
||||
PyProjectSdkConfiguration.INSTANCE.configureSdkUsingCreateSdkInfo(myModule, myCreateSdkInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,37 @@
|
||||
// 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.inspections
|
||||
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.progress.runBlockingMaybeCancellable
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.python.sdkConfigurator.common.detectSdkForModulesIn
|
||||
import com.intellij.python.sdkConfigurator.common.enableSDKAutoConfigurator
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
import com.jetbrains.python.sdk.configuration.CreateSdkInfo
|
||||
import com.jetbrains.python.sdk.configuration.PyProjectSdkConfigurationExtension
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
/**
|
||||
* To be used by [PyInterpreterInspection] only
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
internal fun detectSdkForModulesForJvmIn(project: Project): Boolean {
|
||||
if (!enableSDKAutoConfigurator) {
|
||||
return false
|
||||
}
|
||||
project.service<MyService>().scope.launch {
|
||||
detectSdkForModulesIn(project)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@Service(Service.Level.PROJECT)
|
||||
private class MyService(val scope: CoroutineScope)
|
||||
|
||||
/**
|
||||
* To be used by [PyInterpreterInspection] only
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user