diff --git a/platform/script-debugger/backend/src/debugger/Scope.kt b/platform/script-debugger/backend/src/debugger/Scope.kt index 548143d41d85..1b2b7f55276a 100644 --- a/platform/script-debugger/backend/src/debugger/Scope.kt +++ b/platform/script-debugger/backend/src/debugger/Scope.kt @@ -30,6 +30,8 @@ enum class ScopeType { INSTANCE, BLOCK, SCRIPT, + STACK, + MODULE, UNKNOWN } diff --git a/platform/util/concurrency/api-dump-unreviewed.txt b/platform/util/concurrency/api-dump-unreviewed.txt index 421cf7bb7bf1..48d18a411cac 100644 --- a/platform/util/concurrency/api-dump-unreviewed.txt +++ b/platform/util/concurrency/api-dump-unreviewed.txt @@ -251,6 +251,7 @@ f:org.jetbrains.concurrency.Promises - sf:createError(java.lang.String,Z):java.lang.RuntimeException - bs:createError$default(java.lang.String,Z,I,java.lang.Object):java.lang.RuntimeException - sf:errorIfNotMessage(com.intellij.openapi.diagnostic.Logger,java.lang.Throwable):Z +- sf:first(java.util.Collection,org.jetbrains.concurrency.Obsolescent,kotlin.jvm.functions.Function1):org.jetbrains.concurrency.Promise - sf:isPending(org.jetbrains.concurrency.Promise):Z - sf:isRejected(org.jetbrains.concurrency.Promise):Z - sf:nullPromise():org.jetbrains.concurrency.Promise @@ -273,6 +274,7 @@ f:org.jetbrains.concurrency.Promises - sf:thenRun(org.jetbrains.concurrency.Promise,kotlin.jvm.functions.Function0):org.jetbrains.concurrency.Promise - sf:toActionCallback(org.jetbrains.concurrency.Promise):com.intellij.openapi.util.ActionCallback - sf:toPromise(com.intellij.openapi.util.ActionCallback):org.jetbrains.concurrency.Promise +- sf:waitAll(java.util.Collection,org.jetbrains.concurrency.Obsolescent):org.jetbrains.concurrency.Promise a:org.jetbrains.concurrency.ValueNodeAsyncFunction - com.intellij.util.Function - org.jetbrains.concurrency.Obsolescent diff --git a/platform/util/concurrency/src/org/jetbrains/concurrency/promise.kt b/platform/util/concurrency/src/org/jetbrains/concurrency/promise.kt index abd484e86c42..af1f9fa4c16b 100644 --- a/platform/util/concurrency/src/org/jetbrains/concurrency/promise.kt +++ b/platform/util/concurrency/src/org/jetbrains/concurrency/promise.kt @@ -19,6 +19,7 @@ import java.util.concurrent.CompletableFuture import java.util.concurrent.Future import java.util.concurrent.TimeUnit import java.util.concurrent.atomic.AtomicInteger +import java.util.function.BiConsumer import java.util.function.Consumer private val obsoleteError: RuntimeException by lazy { MessageError("Obsolete", false) } @@ -378,6 +379,73 @@ fun any(promises: Collection>, totalError: String): Promise { return totalPromise } + +fun Collection>.waitAll(node: Obsolescent): Promise> { + if (isEmpty()) { + return resolvedPromise(emptyList()) + } + else if (size == 1) { + return first().then(node, ::listOf) + } + + val totalPromise = AsyncPromise>() + + val done = object : BiConsumer { + val toConsume = AtomicInteger(size) + val result = Collections.synchronizedList( + MutableList(size) { null } + ) + + override fun accept(index: Int, t: T) { + result[index] = t + if (toConsume.decrementAndGet() <= 0) { + @Suppress("UNCHECKED_CAST") + totalPromise.setResult(result as List) + } + } + } + + val rejected = Consumer { throwable -> totalPromise.setError(throwable) } + + for ((index, promise) in withIndex()) { + promise.onSuccess(node) { done.accept(index, it) } + promise.onError(node, rejected::accept) + } + + return totalPromise +} + +fun Collection.first(node: Obsolescent, predicate: (T) -> Promise): Promise { + if (isEmpty()) { + return resolvedPromise() + } + + val totalPromise = AsyncPromise() + val toConsume = AtomicInteger(size) + + val done = Consumer { value -> + if (value != null) { + totalPromise.setResult(value) + } else if (toConsume.decrementAndGet() <= 0) { + totalPromise.setResult(null) + } + } + + val rejected = Consumer { throwable -> + if (toConsume.decrementAndGet() <= 0) { + totalPromise.setError(throwable) + } + } + + for (element in this) { + predicate(element) + .then(node) { matched -> done.accept(element.takeIf { matched }) } + .onError(node) { rejected.accept(it) } + } + + return totalPromise +} + private class DonePromise(private val value: PromiseValue) : Promise, Future, CancellablePromise { /** * The same as @{link Future[Future.isDone]}. diff --git a/platform/xdebugger-api/resources/messages/XDebuggerBundle.properties b/platform/xdebugger-api/resources/messages/XDebuggerBundle.properties index b1e8774674e9..0b1e39c265d6 100644 --- a/platform/xdebugger-api/resources/messages/XDebuggerBundle.properties +++ b/platform/xdebugger-api/resources/messages/XDebuggerBundle.properties @@ -173,6 +173,8 @@ scope.instance = Instance scope.library = Library scope.block = Block scope.script = Script +scope.stack = Values +scope.module = WebAssembly Module scope.unknown = Unknown setting.value.tooltip.delay.label=&Value tooltip delay (ms):