diff --git a/platform/core-api/src/org/jetbrains/concurrency/Promise.java b/platform/core-api/src/org/jetbrains/concurrency/Promise.java index 15566aa3c80e..da9dfefeb334 100644 --- a/platform/core-api/src/org/jetbrains/concurrency/Promise.java +++ b/platform/core-api/src/org/jetbrains/concurrency/Promise.java @@ -23,6 +23,7 @@ import com.intellij.openapi.util.AsyncResult; import com.intellij.util.Consumer; import com.intellij.util.Function; import com.intellij.util.ThreeState; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -103,6 +104,40 @@ public abstract class Promise { return totalPromise; } + public static Promise any(@NotNull final Collection> promises, @NotNull final String totalError) { + if (promises.isEmpty()) { + //noinspection unchecked + return (Promise)DONE; + } + else if (promises.size() == 1) { + return ContainerUtil.getFirstItem(promises); + } + + final AsyncPromise totalPromise = new AsyncPromise(); + Consumer done = new Consumer() { + @Override + public void consume(T result) { + totalPromise.setResult(result); + } + }; + Consumer rejected = new Consumer() { + private volatile int toConsume = promises.size(); + + @Override + public void consume(Throwable throwable) { + if (--toConsume <= 0) { + totalPromise.setError(totalError); + } + } + }; + + for (Promise promise : promises) { + promise.done(done); + promise.rejected(rejected); + } + return totalPromise; + } + @NotNull public static Promise wrapAsVoid(@NotNull ActionCallback asyncResult) { final AsyncPromise promise = new AsyncPromise(); diff --git a/platform/script-debugger/backend/src/BreakpointManager.kt b/platform/script-debugger/backend/src/BreakpointManager.kt index b6e0dca23bbb..1000774eb9f8 100644 --- a/platform/script-debugger/backend/src/BreakpointManager.kt +++ b/platform/script-debugger/backend/src/BreakpointManager.kt @@ -16,6 +16,7 @@ package org.jetbrains.debugger import com.intellij.openapi.util.Ref +import com.intellij.util.Url import org.jetbrains.concurrency.Promise import java.util.* @@ -31,7 +32,14 @@ interface BreakpointManager { val regExpBreakpointSupported: Boolean get() = false - fun setBreakpoint(target: BreakpointTarget, line: Int, column: Int = Breakpoint.EMPTY_VALUE, condition: String? = null, ignoreCount: Int = Breakpoint.EMPTY_VALUE, enabled: Boolean = true, promiseRef: Ref>? = null): Breakpoint + fun setBreakpoint(target: BreakpointTarget, + line: Int, + column: Int = Breakpoint.EMPTY_VALUE, + url: Url? = null, + condition: String? = null, + ignoreCount: Int = Breakpoint.EMPTY_VALUE, + enabled: Boolean = true, + promiseRef: Ref>? = null): Breakpoint fun remove(breakpoint: Breakpoint): Promise<*> diff --git a/platform/script-debugger/backend/src/BreakpointManagerBase.kt b/platform/script-debugger/backend/src/BreakpointManagerBase.kt index 31125c0258d2..73c73e281454 100644 --- a/platform/script-debugger/backend/src/BreakpointManagerBase.kt +++ b/platform/script-debugger/backend/src/BreakpointManagerBase.kt @@ -19,6 +19,7 @@ import com.intellij.openapi.util.Ref import com.intellij.openapi.util.text.StringUtil import com.intellij.util.EventDispatcher import com.intellij.util.SmartList +import com.intellij.util.Url import com.intellij.util.containers.ContainerUtil import gnu.trove.TObjectHashingStrategy import org.jetbrains.concurrency.Promise @@ -47,9 +48,9 @@ abstract class BreakpointManagerBase> : BreakpointManager protected abstract fun createBreakpoint(target: BreakpointTarget, line: Int, column: Int, condition: String?, ignoreCount: Int, enabled: Boolean): T - protected abstract fun doSetBreakpoint(target: BreakpointTarget, breakpoint: T): Promise + protected abstract fun doSetBreakpoint(target: BreakpointTarget, url: Url?, breakpoint: T): Promise - override final fun setBreakpoint(target: BreakpointTarget, line: Int, column: Int, condition: String?, ignoreCount: Int, enabled: Boolean, promiseRef: Ref>?): Breakpoint { + override fun setBreakpoint(target: BreakpointTarget, line: Int, column: Int, url: Url?, condition: String?, ignoreCount: Int, enabled: Boolean, promiseRef: Ref>?): Breakpoint { val breakpoint = createBreakpoint(target, line, column, condition, ignoreCount, enabled) val existingBreakpoint = breakpointDuplicationByTarget.putIfAbsent(breakpoint, breakpoint) if (existingBreakpoint != null) { @@ -59,7 +60,7 @@ abstract class BreakpointManagerBase> : BreakpointManager breakpoints.add(breakpoint) if (enabled) { - val promise = doSetBreakpoint(target, breakpoint) + val promise = doSetBreakpoint(target, url, breakpoint) .rejected { dispatcher.multicaster.errorOccurred(breakpoint, it.message ?: it.toString()) } promiseRef?.set(promise) } @@ -114,7 +115,7 @@ class DummyBreakpointManager : BreakpointManager { override val breakpoints: Iterable get() = emptyList() - override fun setBreakpoint(target: BreakpointTarget, line: Int, column: Int, condition: String?, ignoreCount: Int, enabled: Boolean, promiseRef: Ref>?): Breakpoint { + override fun setBreakpoint(target: BreakpointTarget, line: Int, column: Int, url: Url?, condition: String?, ignoreCount: Int, enabled: Boolean, promiseRef: Ref>?): Breakpoint { throw UnsupportedOperationException() } diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt index 7022d7435ead..344444e70b15 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/LineBreakpointManager.kt @@ -186,7 +186,7 @@ abstract class LineBreakpointManager(private val debugProcess: DebugProcessImpl< promiseRef?.set(resolvedPromise(it)) return it } - return breakpointManager.setBreakpoint(target, location.line, location.column, breakpoint?.conditionExpression?.expression, promiseRef = promiseRef) + return breakpointManager.setBreakpoint(target, location.line, location.column, location.url, breakpoint?.conditionExpression?.expression, promiseRef = promiseRef) } protected abstract fun createTarget(breakpoint: XLineBreakpoint<*>?, breakpointManager: BreakpointManager, location: Location, isTemporary: Boolean): BreakpointTarget