IJPL-165058 WEB-70490 WEB-70574 Introduce SuspendingLookupElementRenderer API to avoid creation of tons of threads, if the renderer performs suspending or blocking requests

(cherry picked from commit d2177ec9d91a0e4d2c85c8b1e0c1f8a065393853)

IJ-CR-150700

GitOrigin-RevId: 113d82171da592604e4c7902691a107a1f4d9023
This commit is contained in:
Piotr Tomiak
2024-12-02 16:35:49 +01:00
committed by intellij-monorepo-bot
parent ff9f0dea64
commit 8fe7eb46e8
3 changed files with 40 additions and 4 deletions

View File

@@ -914,6 +914,11 @@ com.intellij.codeInsight.lookup.LookupListener
- lookupCanceled(com.intellij.codeInsight.lookup.LookupEvent):V
- lookupShown(com.intellij.codeInsight.lookup.LookupEvent):V
- uiRefreshed():V
a:com.intellij.codeInsight.lookup.SuspendingLookupElementRenderer
- com.intellij.codeInsight.lookup.LookupElementRenderer
- <init>():V
- f:renderElement(com.intellij.codeInsight.lookup.LookupElement,com.intellij.codeInsight.lookup.LookupElementPresentation):V
- a:renderElementSuspending(com.intellij.codeInsight.lookup.LookupElement,com.intellij.codeInsight.lookup.LookupElementPresentation,kotlin.coroutines.Continuation):java.lang.Object
a:com.intellij.codeInsight.lookup.TailTypeDecorator
- com.intellij.codeInsight.lookup.LookupElementDecorator
- <init>(com.intellij.codeInsight.lookup.LookupElement):V

View File

@@ -0,0 +1,16 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.lookup
import com.intellij.openapi.progress.runBlockingCancellable
abstract class SuspendingLookupElementRenderer<T : LookupElement> : LookupElementRenderer<T>() {
/**
* Render LookupElement in a coroutine. There is no guarantee that the element is valid.
* The method will usually be called without a read lock.
*/
abstract suspend fun renderElementSuspending(element: T, presentation: LookupElementPresentation)
final override fun renderElement(element: T, presentation: LookupElementPresentation) {
runBlockingCancellable { renderElementSuspending(element, presentation) }
}
}

View File

@@ -6,6 +6,7 @@ package com.intellij.codeInsight.lookup.impl
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementPresentation
import com.intellij.codeInsight.lookup.LookupElementRenderer
import com.intellij.codeInsight.lookup.SuspendingLookupElementRenderer
import com.intellij.openapi.application.readAction
import com.intellij.openapi.util.Key
import com.intellij.util.indexing.DumbModeAccessType
@@ -42,11 +43,14 @@ internal class AsyncRendering(private val lookup: LookupImpl) {
val job = lookup.coroutineScope.launch(limitedDispatcher) {
val job = coroutineContext.job
readAction {
if (element.isValid) {
renderInBackground(element, renderer)
if (renderer is SuspendingLookupElementRenderer<LookupElement>) {
renderInBackgroundSuspending(element, renderer)
} else
readAction {
if (element.isValid) {
renderInBackground(element, renderer)
}
}
}
synchronized(LAST_COMPUTATION) {
element.replace(LAST_COMPUTATION, job, null)
}
@@ -65,4 +69,15 @@ internal class AsyncRendering(private val lookup: LookupImpl) {
rememberPresentation(element, presentation)
lookup.cellRenderer.scheduleUpdateLookupWidthFromVisibleItems()
}
private suspend fun renderInBackgroundSuspending(element: LookupElement, renderer: SuspendingLookupElementRenderer<LookupElement>) {
val presentation = LookupElementPresentation()
renderer.renderElementSuspending(element, presentation)
presentation.freeze()
rememberPresentation(element, presentation)
lookup.cellRenderer.scheduleUpdateLookupWidthFromVisibleItems()
}
}