From a1c67da8ef426af9fdfe9099ea8038e9d6ee9975 Mon Sep 17 00:00:00 2001 From: Konstantin Nisht Date: Fri, 5 Jun 2026 15:48:19 +0200 Subject: [PATCH] [threading] IJPL-246537: Remove modal progress from calculation of CodeVision GitOrigin-RevId: 7548fef2e4bebe4fd98de570f0256a13b2ee16f1 --- platform/lang-impl/api-dump.txt | 2 +- .../codeInsight/codeVision/CodeVisionHost.kt | 23 +++++++++++-------- .../CodeVisionVisualVerticalPositionKeeper.kt | 1 + 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/api-dump.txt b/platform/lang-impl/api-dump.txt index a3c65a51b48d..0c50209041a1 100644 --- a/platform/lang-impl/api-dump.txt +++ b/platform/lang-impl/api-dump.txt @@ -324,7 +324,7 @@ Fc:com.intellij.codeInsight.codeVision.CodeVisionHost - sf:defaultVisibleLenses:I - sf:settingsLensProviderId:java.lang.String - (com.intellij.openapi.project.Project,kotlinx.coroutines.CoroutineScope):V -- f:calculateCodeVisionSync(com.intellij.openapi.editor.Editor,com.intellij.openapi.Disposable):V +- f:calculateCodeVisionSync(com.intellij.openapi.editor.Editor,com.intellij.openapi.Disposable):java.util.concurrent.CompletableFuture - f:collectPlaceholders(com.intellij.openapi.editor.Editor,com.intellij.psi.PsiFile,kotlin.coroutines.Continuation):java.lang.Object - f:getAnchorForEntry(com.intellij.codeInsight.codeVision.CodeVisionEntry):com.intellij.codeInsight.codeVision.CodeVisionAnchorKind - f:getCodeVisionLifetime():com.jetbrains.rd.util.lifetime.Lifetime diff --git a/platform/lang-impl/src/com/intellij/codeInsight/codeVision/CodeVisionHost.kt b/platform/lang-impl/src/com/intellij/codeInsight/codeVision/CodeVisionHost.kt index 97ef9ec86eac..c1f093477842 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/codeVision/CodeVisionHost.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/codeVision/CodeVisionHost.kt @@ -22,7 +22,6 @@ import com.intellij.ide.plugins.DynamicPluginListener import com.intellij.ide.plugins.IdeaPluginDescriptor import com.intellij.lang.Language import com.intellij.openapi.Disposable -import com.intellij.openapi.actionSystem.ex.ActionUtil import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.EDT import com.intellij.openapi.application.ModalityState @@ -73,6 +72,7 @@ import com.jetbrains.rd.util.reactive.Signal import com.jetbrains.rd.util.reactive.whenTrue import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import kotlinx.coroutines.withTimeoutOrNull import org.jetbrains.annotations.ApiStatus import org.jetbrains.annotations.TestOnly @@ -210,27 +210,28 @@ open class CodeVisionHost(val project: Project, protected val coroutineScope: Co return getPriorityForId(entry.providerId) } + /** + * In particular tests, consider using + * `CodeVisionTestCase.waitForCodeVisionSync` + */ @TestOnly - fun calculateCodeVisionSync(editor: Editor, testRootDisposable: Disposable) { + fun calculateCodeVisionSync(editor: Editor, testRootDisposable: Disposable): CompletableFuture { + val future = CompletableFuture() calculateFrontendLenses(testRootDisposable.createLifetime(), editor, inTestSyncMode = true) { lenses, _ -> if (EDT.isCurrentThreadEdt()) { runReadActionBlocking { editor.lensContext?.setResults(lenses) + future.complete(Unit) } } else { - // This code runs under modal progress - // We have no guarantees whether the scheduled event will be completed inside or outside the modal progress - // So here we forcibly wait for its completion - // This is a test method anyway, so it is acceptable to hold the read lock - val future = CompletableFuture() ApplicationManager.getApplication().invokeLater { editor.lensContext?.setResults(lenses) future.complete(Unit) } - future.join() } } + return future } protected open fun subscribeForDocumentChanges(editor: Editor, editorLifetime: Lifetime, onDocumentChanged: () -> Unit) { @@ -617,7 +618,11 @@ open class CodeVisionHost(val project: Project, protected val coroutineScope: Co } } else { - ActionUtil.underModalProgress(project, "") { runnable() } + coroutineScope.launch { + readAction { + runnable() + } + } } return indicator diff --git a/platform/lang-impl/src/com/intellij/codeInsight/codeVision/ui/model/CodeVisionVisualVerticalPositionKeeper.kt b/platform/lang-impl/src/com/intellij/codeInsight/codeVision/ui/model/CodeVisionVisualVerticalPositionKeeper.kt index 0919f1708b9e..bff49a79ea0e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/codeVision/ui/model/CodeVisionVisualVerticalPositionKeeper.kt +++ b/platform/lang-impl/src/com/intellij/codeInsight/codeVision/ui/model/CodeVisionVisualVerticalPositionKeeper.kt @@ -13,6 +13,7 @@ class CodeVisionVisualVerticalPositionKeeper(vararg editors: Editor) { init { for (editor in editors) { + if (editor.isDisposed) continue map[editor] = keep(editor) } }