[kotlin] Corrected Kotlin Configuration Version chooser dialog threading

^KTIJ-27832 fixed


Merge-request: IJ-MR-119874
Merged-by: Frederik Haselmeier <Frederik.Haselmeier@jetbrains.com>

GitOrigin-RevId: 0727223e9e6587c74b1bf1ae049d18e907057ff3
This commit is contained in:
Frederik Haselmeier
2023-11-27 18:09:34 +00:00
committed by intellij-monorepo-bot
parent dd6cd0454c
commit aaa1229644
3 changed files with 42 additions and 25 deletions
@@ -38,5 +38,6 @@
<orderEntry type="module" module-name="intellij.gradle.java" />
<orderEntry type="module" module-name="intellij.platform.vcs.impl" />
<orderEntry type="module" module-name="intellij.platform.diff.impl" />
<orderEntry type="module" module-name="intellij.platform.core" />
</component>
</module>
@@ -4,12 +4,12 @@ package org.jetbrains.kotlin.idea.framework.ui
import com.google.common.io.Closeables
import com.google.gson.JsonParser
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.module.Module
import com.intellij.openapi.observable.properties.AtomicProperty
import com.intellij.openapi.observable.util.transform
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.openapi.util.Disposer
import com.intellij.ui.dsl.builder.AlignX
import com.intellij.ui.dsl.builder.bindText
import com.intellij.ui.dsl.builder.panel
@@ -34,7 +34,8 @@ class ConfigureDialogWithModulesAndVersion(
minimumVersion: String
) : DialogWrapper(project) {
private val chooseModulePanel = ChooseModulePanel(project, configurator, excludedModules)
private val kotlinVersionChooser = KotlinVersionChooser(project, minimumVersion)
private val kotlinVersionChooser =
KotlinVersionChooser(project, minimumVersion, disposable, ModalityState.stateForComponent(window))
private val listOfKotlinVersionsAndModulesText = AtomicProperty("")
private val jvmModulesTargetingUnsupportedJvm: Map<String, List<String>>
@@ -77,8 +78,6 @@ class ConfigureDialogWithModulesAndVersion(
showWarningIfThereAreDifferentKotlinVersions()
}
Disposer.register(disposable, kotlinVersionChooser)
init()
}
@@ -2,13 +2,19 @@
package org.jetbrains.kotlin.idea.framework.ui
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.EDT
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.asContextElement
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.observable.properties.AtomicBooleanProperty
import com.intellij.openapi.observable.properties.AtomicProperty
import com.intellij.openapi.observable.util.not
import com.intellij.openapi.observable.util.or
import com.intellij.platform.ide.progress.withBackgroundProgress
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.DialogPanel
import com.intellij.openapi.util.Disposer
import com.intellij.platform.util.coroutines.namedChildScope
import com.intellij.ui.dsl.builder.*
import com.intellij.ui.dsl.gridLayout.UnscaledGaps
import com.intellij.uiDesigner.core.Spacer
@@ -18,39 +24,54 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jetbrains.kotlin.idea.projectConfiguration.KotlinProjectConfigurationBundle
import java.awt.Dimension
import javax.swing.DefaultComboBoxModel
internal class KotlinVersionChooser(project: Project, minimumVersion: String): Disposable {
@Service(Service.Level.PROJECT)
internal class KotlinVersionChooserService(
private val coroutineScope: CoroutineScope
) {
fun childScope(name: String): CoroutineScope = coroutineScope.namedChildScope(name)
}
internal class KotlinVersionChooser(
private val project: Project,
private val minimumVersion: String,
private val parentDisposable: Disposable,
private val modalityState: ModalityState
) {
private val loading = AtomicBooleanProperty(true)
private val error = AtomicBooleanProperty(false)
private val comboBoxModel = DefaultComboBoxModel<String>()
private val selectedVersion = AtomicProperty("")
private val coroutineScope = CoroutineScope(Dispatchers.Default)
private val coroutineScope = project.service<KotlinVersionChooserService>().childScope("KotlinVersionChooser")
val kotlinVersion: String?
get() = selectedVersion.get().takeIf { it.isNotBlank() }
init {
coroutineScope.launch {
withBackgroundProgress(project, KotlinProjectConfigurationBundle.message("configure.kotlin.find.maven.versions")) {
comboBoxModel.removeAllElements()
loading.set(true)
error.set(false)
val kotlinVersions = try {
Disposer.register(parentDisposable) {
coroutineScope.cancel()
}
coroutineScope.launch(Dispatchers.EDT + modalityState.asContextElement()) {
// Use IO dispatcher because loadVersions is blocking
val loadedVersions = withContext(Dispatchers.IO) {
runCatching {
ConfigureDialogWithModulesAndVersion.loadVersions(minimumVersion)
} catch (e: Exception) {
error.set(true)
listOf(ConfigureDialogWithModulesAndVersion.DEFAULT_KOTLIN_VERSION)
}
comboBoxModel.addAll(kotlinVersions)
@Suppress("HardCodedStringLiteral")
comboBoxModel.selectedItem = kotlinVersions.firstOrNull()
loading.set(false)
}.getOrNull()
}
error.set(loadedVersions == null)
val kotlinVersions = loadedVersions ?: listOf(ConfigureDialogWithModulesAndVersion.DEFAULT_KOTLIN_VERSION)
comboBoxModel.addAll(kotlinVersions)
@Suppress("HardCodedStringLiteral")
comboBoxModel.selectedItem = kotlinVersions.firstOrNull()
loading.set(false)
}
}
@@ -101,8 +122,4 @@ internal class KotlinVersionChooser(project: Project, minimumVersion: String): D
}.layout(RowLayout.PARENT_GRID)
}
}
override fun dispose() {
coroutineScope.cancel()
}
}