IJPL-163538 Maintain actions order in processMatchedActionsAndStubs

(cherry picked from commit 63db5c5f0be301ef98c6e18fa1720236a2f92326)

IJ-MR-146410

(cherry picked from commit 757e8b342213425d413a506a13549daa1c0cf9fb)


(cherry picked from commit 34e00d1be3ed2a89e0bd5be374177f7bcbd36291)

IJ-CR-153899

GitOrigin-RevId: 9dfb2d9a75e7eba9678160ebc5bf77af9a7a03ca
This commit is contained in:
Mikhail Sokolov
2024-10-09 17:12:47 +02:00
committed by intellij-monorepo-bot
parent 75698d8271
commit 66fe716c81

View File

@@ -31,7 +31,6 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.SendChannel
import kotlinx.coroutines.channels.toList
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import kotlin.coroutines.coroutineContext
@@ -114,10 +113,10 @@ internal class ActionAsyncProvider(private val model: GotoActionModel) {
awaitJob?.join() //wait until all items from previous step are processed
LOG.debug { "Process matched actions for \"$pattern\"" }
list.forEachConcurrent { matchedActionOrStub -> //todo maintain order
list.forEachConcurrentOrdered { matchedActionOrStub, awaitMyTurn ->
val action = matchedActionOrStub.action
val matchedAction = if (action is ActionStubBase) loadAction(action.id)?.let { MatchedAction(it, matchedActionOrStub.mode, matchedActionOrStub.weight) } else matchedActionOrStub
if (matchedAction == null) return@forEachConcurrent
if (matchedAction == null) return@forEachConcurrentOrdered
val presentation = presentationProvider(matchedAction.action)
val matchedValue = matchItem(
item = wrapAnAction(action = matchedAction.action, presentation = presentation, matchMode = matchedAction.mode),
@@ -125,10 +124,20 @@ internal class ActionAsyncProvider(private val model: GotoActionModel) {
pattern = pattern,
matchType = MatchedValueType.ACTION,
)
awaitMyTurn()
if (!consumer(matchedValue)) cancel()
}
}
private suspend fun <T> Collection<T>.forEachConcurrentOrdered(action: suspend (T, suspend () -> Unit) -> Unit) {
suspend fun runConcurrent(item: T, jobToAwait: Job?): Job = coroutineScope {
launch { action(item) { jobToAwait?.join() } }
}
var prevItemJob: Job? = null
forEach { prevItemJob = runConcurrent(it, prevItemJob) }
}
private suspend fun collectMatchedActions(pattern: String, allIds: Collection<String>, weightMatcher: MinusculeMatcher, unmatchedIdsChannel: SendChannel<String>): List<MatchedAction> = coroutineScope {
val matcher = buildMatcher(pattern)