mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Promise — add onError and onSuccess
Prefix "on" makes method purpose more clear (especially if you are not familiar with "signals" concept).
This commit is contained in:
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
@@ -65,7 +51,7 @@ public abstract class ArrayAction extends DebuggerAction {
|
||||
// title = title + " " + label.substring(index);
|
||||
//}
|
||||
createNewRenderer(node, renderer, debuggerContext, node.getName())
|
||||
.done(newRenderer -> setArrayRenderer(newRenderer, node, debuggerContext));
|
||||
.onSuccess(newRenderer -> setArrayRenderer(newRenderer, node, debuggerContext));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -119,7 +105,7 @@ public abstract class ArrayAction extends DebuggerAction {
|
||||
if (debugProcess != null) {
|
||||
debugProcess.getManagerThread().schedule(new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) {
|
||||
@Override
|
||||
public void contextAction(@NotNull SuspendContextImpl suspendContext) throws Exception {
|
||||
public void contextAction(@NotNull SuspendContextImpl suspendContext) {
|
||||
final Renderer lastRenderer = descriptor.getLastRenderer();
|
||||
if (lastRenderer instanceof ArrayRenderer) {
|
||||
((JavaValue)container).setRenderer(newRenderer, node);
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.ide
|
||||
|
||||
import com.intellij.ide.impl.ProjectUtil.focusProjectWindow
|
||||
@@ -118,7 +104,7 @@ internal class OpenFileHttpService : RestService() {
|
||||
}
|
||||
|
||||
val promise = openFile(apiRequest, context, request) ?: return null
|
||||
promise.done { sendStatus(HttpResponseStatus.OK, keepAlive, channel) }
|
||||
promise.onSuccess { sendStatus(HttpResponseStatus.OK, keepAlive, channel) }
|
||||
.rejected {
|
||||
if (it === NOT_FOUND) {
|
||||
// don't expose file status
|
||||
@@ -134,7 +120,7 @@ internal class OpenFileHttpService : RestService() {
|
||||
return null
|
||||
}
|
||||
|
||||
internal fun openFile(request: OpenFileRequest, context: ChannelHandlerContext, httpRequest: HttpRequest?): Promise<Void>? {
|
||||
internal fun openFile(request: OpenFileRequest, context: ChannelHandlerContext, httpRequest: HttpRequest?): Promise<Void?>? {
|
||||
val systemIndependentPath = FileUtil.toSystemIndependentName(FileUtil.expandUserHome(request.file!!))
|
||||
val file = Paths.get(FileUtil.toSystemDependentName(systemIndependentPath))
|
||||
if (file.isAbsolute) {
|
||||
@@ -198,7 +184,7 @@ internal class OpenFileRequest {
|
||||
}
|
||||
|
||||
private class OpenFileTask(internal val path: String, internal val request: OpenFileRequest) {
|
||||
internal val promise = AsyncPromise<Void>()
|
||||
internal val promise = AsyncPromise<Void?>()
|
||||
}
|
||||
|
||||
private fun navigate(project: Project?, file: VirtualFile, request: OpenFileRequest) {
|
||||
@@ -251,8 +237,8 @@ private fun openRelativePath(path: String, request: OpenFileRequest): Boolean {
|
||||
} ?: false
|
||||
}
|
||||
|
||||
private fun openAbsolutePath(file: Path, request: OpenFileRequest): Promise<Void> {
|
||||
val promise = AsyncPromise<Void>()
|
||||
private fun openAbsolutePath(file: Path, request: OpenFileRequest): Promise<Void?> {
|
||||
val promise = AsyncPromise<Void?>()
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
promise.catchError {
|
||||
val virtualFile = runWriteAction { LocalFileSystem.getInstance().refreshAndFindFileByPath(file.systemIndependentPath) }
|
||||
|
||||
+2
-16
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.execution.runners;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
@@ -37,7 +23,7 @@ public abstract class AsyncGenericProgramRunner<Settings extends RunnerSettings>
|
||||
@Nullable Callback callback,
|
||||
@NotNull RunProfileState state) throws ExecutionException {
|
||||
prepare(environment, state)
|
||||
.done(result -> UIUtil.invokeLaterIfNeeded(() -> {
|
||||
.onSuccess(result -> UIUtil.invokeLaterIfNeeded(() -> {
|
||||
if (!environment.getProject().isDisposed()) {
|
||||
startRunProfile(environment, state, callback, result);
|
||||
}
|
||||
|
||||
+13
-9
@@ -35,10 +35,9 @@ import com.intellij.util.ui.tree.TreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.concurrency.Promise;
|
||||
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@@ -207,7 +206,10 @@ class AsyncProjectViewSupport {
|
||||
}
|
||||
|
||||
private void acceptAndUpdate(TreeVisitor visitor, List<TreePath> list, boolean structure) {
|
||||
if (visitor != null) myAsyncTreeModel.accept(visitor, false).done(path -> update(list, structure));
|
||||
if (visitor != null) {
|
||||
myAsyncTreeModel.accept(visitor, false)
|
||||
.onSuccess(path -> update(list, structure));
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePresentationsFromRootTo(@NotNull VirtualFile file) {
|
||||
@@ -238,15 +240,17 @@ class AsyncProjectViewSupport {
|
||||
void accept(List<TreeVisitor> visitors, Consumer<List<TreePath>> consumer) {
|
||||
if (visitors != null && !visitors.isEmpty()) {
|
||||
if (1 == visitors.size()) {
|
||||
myAsyncTreeModel.accept(visitors.get(0)).done(path -> {
|
||||
if (path != null) consumer.consume(singletonList(path));
|
||||
});
|
||||
myAsyncTreeModel.accept(visitors.get(0))
|
||||
.onSuccess(path -> {
|
||||
if (path != null) consumer.consume(singletonList(path));
|
||||
});
|
||||
}
|
||||
else {
|
||||
List<Promise<TreePath>> promises = visitors.stream().map(visitor -> myAsyncTreeModel.accept(visitor)).collect(toList());
|
||||
collectResults(promises, true).done(list -> {
|
||||
if (list != null && !list.isEmpty()) consumer.consume(list);
|
||||
});
|
||||
collectResults(promises, true)
|
||||
.onSuccess(list -> {
|
||||
if (list != null && !list.isEmpty()) consumer.consume(list);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.tree;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
@@ -36,7 +22,6 @@ import javax.swing.event.TreeModelEvent;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.IntFunction;
|
||||
@@ -165,8 +150,8 @@ public final class AsyncTreeModel extends AbstractTreeModel implements Identifia
|
||||
onValidThread(() -> async.setError("rejected"));
|
||||
}
|
||||
else {
|
||||
promise.rejected(onValidThread(async::setError));
|
||||
promise.done(onValidThread(path -> resolve(async, path)));
|
||||
promise.onError(onValidThread(async::setError));
|
||||
promise.onSuccess(onValidThread(path -> resolve(async, path)));
|
||||
}
|
||||
return async;
|
||||
}
|
||||
@@ -256,7 +241,9 @@ public final class AsyncTreeModel extends AbstractTreeModel implements Identifia
|
||||
@Override
|
||||
protected Collection<Node> getChildren(@NotNull Node node) {
|
||||
if (node.leaf || !allowLoading) return node.getChildren();
|
||||
promiseChildren(node).done(parent -> setChildren(parent.getChildren())).rejected(this::setError);
|
||||
promiseChildren(node)
|
||||
.onSuccess(parent -> setChildren(parent.getChildren()))
|
||||
.onError(this::setError);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -288,7 +275,7 @@ public final class AsyncTreeModel extends AbstractTreeModel implements Identifia
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <T> Consumer<T> onValidThread(Consumer<T> consumer) {
|
||||
private <T> java.util.function.Consumer<T> onValidThread(Consumer<T> consumer) {
|
||||
return value -> onValidThread(() -> consumer.consume(value));
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,8 @@ class AsyncPromiseTest {
|
||||
val count = AtomicInteger()
|
||||
|
||||
val r = {
|
||||
promise.done { count.incrementAndGet() }
|
||||
promise
|
||||
.onSuccess { count.incrementAndGet() }
|
||||
}
|
||||
|
||||
val s = {
|
||||
@@ -101,10 +102,10 @@ class AsyncPromiseTest {
|
||||
|
||||
val r = {
|
||||
if (reject) {
|
||||
promise.rejected { count.incrementAndGet() }
|
||||
promise.onError { count.incrementAndGet() }
|
||||
}
|
||||
else {
|
||||
promise.done { count.incrementAndGet() }
|
||||
promise.onSuccess { count.incrementAndGet() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.jetbrains.concurrency
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.util.Getter
|
||||
import com.intellij.util.Consumer
|
||||
import com.intellij.util.Function
|
||||
import org.jetbrains.concurrency.Promise.State
|
||||
import java.util.*
|
||||
@@ -11,12 +10,13 @@ import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.TimeoutException
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import java.util.function.Consumer
|
||||
|
||||
private val LOG = Logger.getInstance(AsyncPromise::class.java)
|
||||
|
||||
private data class PromiseValue<out T>(val result: T? = null, val error: Throwable? = null)
|
||||
|
||||
open class AsyncPromise<T> : Promise<T>, Getter<T>, CancellablePromise<T> {
|
||||
open class AsyncPromise<T : Any?> : Promise<T>, Getter<T>, CancellablePromise<T> {
|
||||
private val doneRef = AtomicReference<Consumer<in T>?>()
|
||||
private val rejectedRef = AtomicReference<Consumer<in Throwable>?>()
|
||||
|
||||
@@ -31,13 +31,18 @@ open class AsyncPromise<T> : Promise<T>, Getter<T>, CancellablePromise<T> {
|
||||
}
|
||||
}
|
||||
|
||||
override fun done(done: Consumer<in T>): Promise<T> {
|
||||
override fun onSuccess(done: Consumer<in T>): Promise<T> {
|
||||
setHandler(doneRef, done, State.FULFILLED)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun rejected(rejected: Consumer<Throwable>): Promise<T> {
|
||||
setHandler(rejectedRef, rejected, State.REJECTED)
|
||||
override fun rejected(rejected: com.intellij.util.Consumer<Throwable>): Promise<T> {
|
||||
setHandler(rejectedRef, Consumer { rejected.consume(it) }, State.REJECTED)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun onError(errorHandler: Consumer<Throwable>): Promise<T> {
|
||||
setHandler(rejectedRef, errorHandler, State.REJECTED)
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -83,8 +88,8 @@ open class AsyncPromise<T> : Promise<T>, Getter<T>, CancellablePromise<T> {
|
||||
addHandlers(Consumer({
|
||||
promise.catchError {
|
||||
handler.`fun`(it)
|
||||
.done { promise.catchError { promise.setResult(it) } }
|
||||
.rejected(rejectedHandler)
|
||||
.onSuccess { promise.catchError { promise.setResult(it) } }
|
||||
.onError(rejectedHandler)
|
||||
}
|
||||
}), rejectedHandler)
|
||||
return promise
|
||||
@@ -96,9 +101,10 @@ open class AsyncPromise<T> : Promise<T>, Getter<T>, CancellablePromise<T> {
|
||||
}
|
||||
|
||||
val value = valueRef.get()
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
when {
|
||||
value == null -> addHandlers(Consumer({ child.catchError { child.setResult(it) } }), Consumer({ child.setError(it) }))
|
||||
value.error == null -> child.setResult(value.result)
|
||||
value.error == null -> child.setResult(value.result as T)
|
||||
else -> child.setError(value.error)
|
||||
}
|
||||
return this
|
||||
@@ -109,7 +115,7 @@ open class AsyncPromise<T> : Promise<T>, Getter<T>, CancellablePromise<T> {
|
||||
setHandler(rejectedRef, rejected, State.REJECTED)
|
||||
}
|
||||
|
||||
fun setResult(result: T?) {
|
||||
fun setResult(result: T) {
|
||||
if (!valueRef.compareAndSet(null, PromiseValue(result = result))) {
|
||||
return
|
||||
}
|
||||
@@ -118,7 +124,7 @@ open class AsyncPromise<T> : Promise<T>, Getter<T>, CancellablePromise<T> {
|
||||
rejectedRef.set(null)
|
||||
|
||||
if (done != null && !isObsolete(done)) {
|
||||
done.consume(result)
|
||||
done.accept(result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,14 +147,14 @@ open class AsyncPromise<T> : Promise<T>, Getter<T>, CancellablePromise<T> {
|
||||
LOG.errorIfNotMessage(error)
|
||||
}
|
||||
else if (!isObsolete(rejected)) {
|
||||
rejected.consume(error)
|
||||
rejected.accept(error)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun processed(processed: Consumer<in T>): Promise<T> {
|
||||
done(processed)
|
||||
rejected { processed.consume(null) }
|
||||
override fun onProcessed(action: Consumer<in T?>): Promise<T> {
|
||||
onSuccess { action.accept(it) }
|
||||
onError { action.accept(null) }
|
||||
return this
|
||||
}
|
||||
|
||||
@@ -223,11 +229,11 @@ open class AsyncPromise<T> : Promise<T>, Getter<T>, CancellablePromise<T> {
|
||||
}
|
||||
}
|
||||
|
||||
private fun <C_T> callConsumerIfTargeted(targetState: State, newConsumer: Consumer<in C_T>, value: PromiseValue<T>) {
|
||||
private fun <C_T : Any?> callConsumerIfTargeted(targetState: State, newConsumer: Consumer<in C_T>, value: PromiseValue<T>) {
|
||||
val currentState = if (value.error == null) State.FULFILLED else State.REJECTED
|
||||
if (currentState == targetState) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
newConsumer.consume(if (currentState == State.FULFILLED) value.result as C_T? else value.error as C_T)
|
||||
newConsumer.accept(if (currentState == State.FULFILLED) value.result as C_T else value.error as C_T)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +266,7 @@ private class CompoundConsumer<T>(c1: Consumer<in T>, c2: Consumer<in T>) : Cons
|
||||
}
|
||||
}
|
||||
|
||||
override fun consume(t: T) {
|
||||
override fun accept(t: T) {
|
||||
val list = synchronized(this) {
|
||||
val list = consumers
|
||||
consumers = null
|
||||
@@ -269,13 +275,13 @@ private class CompoundConsumer<T>(c1: Consumer<in T>, c2: Consumer<in T>) : Cons
|
||||
|
||||
for (consumer in list) {
|
||||
if (!isObsolete(consumer)) {
|
||||
consumer.consume(t)
|
||||
consumer.accept(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun isObsolete(consumer: Consumer<*>?) = consumer is Obsolescent && consumer.isObsolete
|
||||
internal fun isObsolete(consumer: Any) = consumer is Obsolescent && consumer.isObsolete
|
||||
|
||||
inline fun <T> AsyncPromise<*>.catchError(runnable: () -> T): T? {
|
||||
try {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
package org.jetbrains.concurrency;
|
||||
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -11,6 +10,7 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.jetbrains.concurrency.Promises.rejectedPromise;
|
||||
import static org.jetbrains.concurrency.Promises.resolvedPromise;
|
||||
@@ -24,9 +24,9 @@ class DonePromise<T> implements Getter<T>, Promise<T>, Future<T> {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Promise<T> done(@NotNull Consumer<? super T> done) {
|
||||
public Promise<T> onSuccess(@NotNull Consumer<? super T> done) {
|
||||
if (!AsyncPromiseKt.isObsolete(done)) {
|
||||
done.consume(result);
|
||||
done.accept(result);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -43,14 +43,14 @@ class DonePromise<T> implements Getter<T>, Promise<T>, Future<T> {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Promise<T> processed(@NotNull Consumer<? super T> processed) {
|
||||
done(processed);
|
||||
public Promise<T> onProcessed(@NotNull Consumer<? super T> processed) {
|
||||
onSuccess(processed);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Promise<T> rejected(@NotNull Consumer<Throwable> rejected) {
|
||||
public Promise<T> onError(@NotNull Consumer<Throwable> rejected) {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,13 +71,30 @@ public interface Promise<T> {
|
||||
* Execute passed handler on promise resolve.
|
||||
*/
|
||||
@NotNull
|
||||
Promise<T> done(@NotNull Consumer<? super T> done);
|
||||
Promise<T> onSuccess(@NotNull java.util.function.Consumer<? super T> done);
|
||||
|
||||
/**
|
||||
* Execute passed handler on promise resolve.
|
||||
* @deprecated Use {@link #onSuccess(java.util.function.Consumer)}
|
||||
*/
|
||||
@NotNull
|
||||
default Promise<T> done(@NotNull Consumer<? super T> done) {
|
||||
return onSuccess(it -> done.consume(it));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute passed handler on promise reject.
|
||||
*/
|
||||
@NotNull
|
||||
Promise<T> rejected(@NotNull Consumer<Throwable> rejected);
|
||||
Promise<T> onError(@NotNull java.util.function.Consumer<Throwable> rejected);
|
||||
|
||||
/**
|
||||
* Execute passed handler on promise reject.
|
||||
*/
|
||||
@NotNull
|
||||
default Promise<T> rejected(@NotNull Consumer<Throwable> rejected) {
|
||||
return onError(it -> rejected.consume(it));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve or reject passed promise as soon as this promise resolved or rejected.
|
||||
@@ -89,7 +106,15 @@ public interface Promise<T> {
|
||||
* Execute passed handler on promise resolve (result value will be passed),
|
||||
* or on promise reject (null as result value will be passed).
|
||||
*/
|
||||
Promise<T> processed(@NotNull Consumer<? super T> processed);
|
||||
Promise<T> onProcessed(@NotNull java.util.function.Consumer<? super T> processed);
|
||||
|
||||
/**
|
||||
* Execute passed handler on promise resolve (result value will be passed),
|
||||
* or on promise reject (null as result value will be passed).
|
||||
*/
|
||||
default Promise<T> processed(@NotNull Consumer<? super T> action) {
|
||||
return onProcessed(it -> action.consume(it));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get promise state.
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.concurrency
|
||||
|
||||
import com.intellij.util.Consumer
|
||||
import com.intellij.util.Function
|
||||
import java.util.concurrent.Future
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.function.Consumer
|
||||
|
||||
internal class RejectedPromise<T>(private val error: Throwable) : Promise<T>, Future<T> {
|
||||
override fun getState() = Promise.State.REJECTED
|
||||
|
||||
override fun done(done: Consumer<in T>) = this
|
||||
override fun onSuccess(done: Consumer<in T>) = this
|
||||
|
||||
override fun processed(child: Promise<in T>): Promise<T> {
|
||||
if (child is AsyncPromise) {
|
||||
@@ -19,15 +19,15 @@ internal class RejectedPromise<T>(private val error: Throwable) : Promise<T>, Fu
|
||||
return this
|
||||
}
|
||||
|
||||
override fun rejected(rejected: Consumer<Throwable>): Promise<T> {
|
||||
if (!isObsolete(rejected)) {
|
||||
rejected.consume(error)
|
||||
override fun onError(action: Consumer<Throwable>): Promise<T> {
|
||||
if (!isObsolete(action)) {
|
||||
action.accept(error)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
override fun processed(processed: Consumer<in T>): RejectedPromise<T> {
|
||||
processed.consume(null)
|
||||
override fun onProcessed(processed: Consumer<in T?>): RejectedPromise<T> {
|
||||
processed.accept(null)
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ abstract class ValueNodeAsyncFunction<PARAM, RESULT>(private val node: Obsolesce
|
||||
override fun isObsolete() = node.isObsolete
|
||||
}
|
||||
|
||||
abstract class ObsolescentConsumer<T>(private val obsolescent: Obsolescent) : Obsolescent, Consumer<T> {
|
||||
abstract class ObsolescentConsumer<T>(private val obsolescent: Obsolescent) : Obsolescent, java.util.function.Consumer<T> {
|
||||
override fun isObsolete() = obsolescent.isObsolete
|
||||
}
|
||||
|
||||
@@ -67,20 +67,20 @@ inline fun <T, SUB_RESULT> Promise<T>.then(obsolescent: Obsolescent, crossinline
|
||||
})
|
||||
|
||||
|
||||
inline fun <T> Promise<T>.done(node: Obsolescent, crossinline handler: (T) -> Unit) = done(object : ObsolescentConsumer<T>(node) {
|
||||
override fun consume(param: T) = handler(param)
|
||||
inline fun <T> Promise<T>.onSuccess(node: Obsolescent, crossinline handler: (T) -> Unit) = onSuccess(object : ObsolescentConsumer<T>(node) {
|
||||
override fun accept(param: T) = handler(param)
|
||||
})
|
||||
|
||||
inline fun Promise<*>.processed(node: Obsolescent, crossinline handler: () -> Unit): Promise<Any?>? {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return (this as Promise<Any?>)
|
||||
.processed(object : ObsolescentConsumer<Any?>(node) {
|
||||
override fun consume(param: Any?) = handler()
|
||||
.onProcessed(object : ObsolescentConsumer<Any?>(node) {
|
||||
override fun accept(param: Any?) = handler()
|
||||
})
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
inline fun Promise<*>.doneRun(crossinline handler: () -> Unit) = done({ handler() })
|
||||
inline fun Promise<*>.doneRun(crossinline handler: () -> Unit) = onSuccess { handler() }
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
inline fun <T> Promise<*>.thenRun(crossinline handler: () -> T): Promise<T> = (this as Promise<Any?>).then({ handler() })
|
||||
@@ -94,9 +94,11 @@ inline fun <T, SUB_RESULT> Promise<T>.thenAsync(node: Obsolescent, crossinline h
|
||||
})
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
inline fun <T> Promise<T>.thenAsyncAccept(node: Obsolescent, crossinline handler: (T) -> Promise<*>) = thenAsync(object : ValueNodeAsyncFunction<T, Any?>(node) {
|
||||
override fun `fun`(param: T) = handler(param) as Promise<Any?>
|
||||
})
|
||||
inline fun <T> Promise<T>.thenAsyncAccept(node: Obsolescent, crossinline handler: (T) -> Promise<*>): Promise<Any?> {
|
||||
return thenAsync(object : ValueNodeAsyncFunction<T, Any?>(node) {
|
||||
override fun `fun`(param: T) = handler(param) as Promise<Any?>
|
||||
})
|
||||
}
|
||||
|
||||
inline fun <T> Promise<T>.thenAsyncAccept(crossinline handler: (T) -> Promise<*>) = thenAsync(Function<T, Promise<Any?>> { param ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@@ -104,8 +106,8 @@ inline fun <T> Promise<T>.thenAsyncAccept(crossinline handler: (T) -> Promise<*>
|
||||
})
|
||||
|
||||
|
||||
inline fun Promise<*>.rejected(node: Obsolescent, crossinline handler: (Throwable) -> Unit) = rejected(object : ObsolescentConsumer<Throwable>(node) {
|
||||
override fun consume(param: Throwable) = handler(param)
|
||||
inline fun Promise<*>.onError(node: Obsolescent, crossinline handler: (Throwable) -> Unit) = onError(object : ObsolescentConsumer<Throwable>(node) {
|
||||
override fun accept(param: Throwable) = handler(param)
|
||||
})
|
||||
|
||||
@JvmOverloads
|
||||
@@ -116,7 +118,7 @@ fun <T> collectResults(promises: List<Promise<T>>, ignoreErrors: Boolean = false
|
||||
|
||||
val results: MutableList<T> = if (promises.size == 1) SmartList<T>() else ArrayList(promises.size)
|
||||
for (promise in promises) {
|
||||
promise.done { results.add(it) }
|
||||
promise.onSuccess { results.add(it) }
|
||||
}
|
||||
return all(promises, results, ignoreErrors)
|
||||
}
|
||||
@@ -125,10 +127,15 @@ fun <T> collectResults(promises: List<Promise<T>>, ignoreErrors: Boolean = false
|
||||
fun createError(error: String, log: Boolean = false): RuntimeException = MessageError(error, log)
|
||||
|
||||
inline fun <T> AsyncPromise<T>.compute(runnable: () -> T) {
|
||||
val result = catchError(runnable)
|
||||
if (!isRejected) {
|
||||
setResult(result)
|
||||
val result = try {
|
||||
runnable()
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
setError(e)
|
||||
return
|
||||
}
|
||||
|
||||
setResult(result)
|
||||
}
|
||||
|
||||
inline fun <T> runAsync(crossinline runnable: () -> T): Promise<T> {
|
||||
@@ -172,16 +179,17 @@ fun Logger.errorIfNotMessage(e: Throwable): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
fun ActionCallback.toPromise(): Promise<Void> {
|
||||
val promise = AsyncPromise<Void>()
|
||||
doWhenDone { promise.setResult(null) }.doWhenRejected { error -> promise.setError(createError(error ?: "Internal error")) }
|
||||
fun ActionCallback.toPromise(): Promise<Void?> {
|
||||
val promise = AsyncPromise<Void?>()
|
||||
doWhenDone { promise.setResult(null) }
|
||||
.doWhenRejected { error -> promise.setError(createError(error ?: "Internal error")) }
|
||||
return promise
|
||||
}
|
||||
|
||||
fun all(promises: Collection<Promise<*>>): Promise<*> = if (promises.size == 1) promises.first() else all(promises, null)
|
||||
|
||||
@JvmOverloads
|
||||
fun <T> all(promises: Collection<Promise<*>>, totalResult: T?, ignoreErrors: Boolean = false): Promise<T> {
|
||||
fun <T: Any?> all(promises: Collection<Promise<*>>, totalResult: T, ignoreErrors: Boolean = false): Promise<T> {
|
||||
if (promises.isEmpty()) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return DONE as Promise<T>
|
||||
@@ -190,21 +198,21 @@ fun <T> all(promises: Collection<Promise<*>>, totalResult: T?, ignoreErrors: Boo
|
||||
val totalPromise = AsyncPromise<T>()
|
||||
val done = CountDownConsumer(promises.size, totalPromise, totalResult)
|
||||
val rejected = if (ignoreErrors) {
|
||||
Consumer { done.consume(null) }
|
||||
Consumer { done.accept(null) }
|
||||
}
|
||||
else {
|
||||
Consumer<Throwable> { totalPromise.setError(it) }
|
||||
}
|
||||
|
||||
for (promise in promises) {
|
||||
promise.done(done)
|
||||
promise.onSuccess(done)
|
||||
promise.rejected(rejected)
|
||||
}
|
||||
return totalPromise
|
||||
}
|
||||
|
||||
private class CountDownConsumer<T>(@Volatile private var countDown: Int, private val promise: AsyncPromise<T>, private val totalResult: T?) : Consumer<Any?> {
|
||||
override fun consume(t: Any?) {
|
||||
private class CountDownConsumer<T : Any?>(@Volatile private var countDown: Int, private val promise: AsyncPromise<T>, private val totalResult: T) : java.util.function.Consumer<Any?> {
|
||||
override fun accept(t: Any?) {
|
||||
if (--countDown == 0) {
|
||||
promise.setResult(totalResult)
|
||||
}
|
||||
@@ -221,11 +229,11 @@ fun <T> any(promises: Collection<Promise<T>>, totalError: String): Promise<T> {
|
||||
}
|
||||
|
||||
val totalPromise = AsyncPromise<T>()
|
||||
val done = Consumer<T> { result -> totalPromise.setResult(result) }
|
||||
val rejected = object : Consumer<Throwable> {
|
||||
val done = java.util.function.Consumer<T> { result -> totalPromise.setResult(result) }
|
||||
val rejected = object : java.util.function.Consumer<Throwable> {
|
||||
@Volatile private var toConsume = promises.size
|
||||
|
||||
override fun consume(throwable: Throwable) {
|
||||
override fun accept(throwable: Throwable) {
|
||||
if (--toConsume <= 0) {
|
||||
totalPromise.setError(totalError)
|
||||
}
|
||||
@@ -233,8 +241,8 @@ fun <T> any(promises: Collection<Promise<T>>, totalError: String): Promise<T> {
|
||||
}
|
||||
|
||||
for (promise in promises) {
|
||||
promise.done(done)
|
||||
promise.rejected(rejected)
|
||||
promise.onSuccess(done)
|
||||
promise.onError(rejected)
|
||||
}
|
||||
return totalPromise
|
||||
}
|
||||
@@ -1,28 +1,13 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.debugger
|
||||
|
||||
import com.intellij.util.Consumer
|
||||
import org.jetbrains.concurrency.Promise
|
||||
import org.jetbrains.debugger.values.ValueManager
|
||||
|
||||
/**
|
||||
* An object that matches the execution state of the VM while suspended
|
||||
*/
|
||||
interface SuspendContext<CALL_FRAME : CallFrame> {
|
||||
interface SuspendContext<out CALL_FRAME : CallFrame> {
|
||||
val state: SuspendState
|
||||
|
||||
val script: Script?
|
||||
@@ -60,22 +45,26 @@ interface SuspendContext<CALL_FRAME : CallFrame> {
|
||||
get() = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
abstract class ContextDependentAsyncResultConsumer<T>(private val context: SuspendContext<*>) : Consumer<T> {
|
||||
override final fun consume(result: T) {
|
||||
abstract class ContextDependentAsyncResultConsumer<T>(private val context: SuspendContext<*>) : java.util.function.Consumer<T> {
|
||||
override final fun accept(result: T) {
|
||||
val vm = context.vm
|
||||
if (vm.attachStateManager.isAttached && !vm.suspendContextManager.isContextObsolete(context)) {
|
||||
consume(result, vm)
|
||||
accept(result, vm)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun consume(result: T, vm: Vm)
|
||||
protected abstract fun accept(result: T, vm: Vm)
|
||||
}
|
||||
|
||||
|
||||
inline fun <T> Promise<T>.done(context: SuspendContext<*>, crossinline handler: (result: T) -> Unit) = done(object : ContextDependentAsyncResultConsumer<T>(context) {
|
||||
override fun consume(result: T, vm: Vm) = handler(result)
|
||||
})
|
||||
inline fun <T> Promise<T>.onSuccess(context: SuspendContext<*>, crossinline handler: (result: T) -> Unit): Promise<T> {
|
||||
return onSuccess(object : ContextDependentAsyncResultConsumer<T>(context) {
|
||||
override fun accept(result: T, vm: Vm) = handler(result)
|
||||
})
|
||||
}
|
||||
|
||||
inline fun Promise<*>.rejected(context: SuspendContext<*>, crossinline handler: (error: Throwable) -> Unit) = rejected(object : ContextDependentAsyncResultConsumer<Throwable>(context) {
|
||||
override fun consume(result: Throwable, vm: Vm) = handler(result)
|
||||
})
|
||||
inline fun Promise<*>.onError(context: SuspendContext<*>, crossinline handler: (error: Throwable) -> Unit): Promise<out Any> {
|
||||
return onError(object : ContextDependentAsyncResultConsumer<Throwable>(context) {
|
||||
override fun accept(result: Throwable, vm: Vm) = handler(result)
|
||||
})
|
||||
}
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.debugger
|
||||
|
||||
import org.jetbrains.concurrency.AsyncPromise
|
||||
@@ -24,7 +10,7 @@ import java.util.concurrent.atomic.AtomicReference
|
||||
abstract class SuspendContextManagerBase<T : SuspendContextBase<CALL_FRAME>, CALL_FRAME : CallFrame> : SuspendContextManager<CALL_FRAME> {
|
||||
val contextRef = AtomicReference<T>()
|
||||
|
||||
protected val suspendCallback = AtomicReference<AsyncPromise<Void>>()
|
||||
protected val suspendCallback = AtomicReference<AsyncPromise<Void?>>()
|
||||
|
||||
protected abstract val debugListener: DebugEventListener
|
||||
|
||||
@@ -46,7 +32,7 @@ abstract class SuspendContextManagerBase<T : SuspendContextBase<CALL_FRAME>, CAL
|
||||
|
||||
protected fun dismissContextOnDone(promise: Promise<*>): Promise<*> {
|
||||
val context = contextOrFail
|
||||
promise.done { contextDismissed(context) }
|
||||
promise.onSuccess { contextDismissed(context) }
|
||||
return promise
|
||||
}
|
||||
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.rpc
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
@@ -23,7 +9,10 @@ import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
val LOG = Logger.getInstance(CommandProcessor::class.java)
|
||||
|
||||
abstract class CommandProcessor<INCOMING, INCOMING_WITH_SEQ : Any, SUCCESS_RESPONSE>() : CommandSenderBase<SUCCESS_RESPONSE>(), MessageManager.Handler<Request<*>, INCOMING, INCOMING_WITH_SEQ, SUCCESS_RESPONSE>, ResultReader<SUCCESS_RESPONSE>, MessageProcessor {
|
||||
abstract class CommandProcessor<INCOMING, INCOMING_WITH_SEQ : Any, SUCCESS_RESPONSE : Any?> : CommandSenderBase<SUCCESS_RESPONSE>(),
|
||||
MessageManager.Handler<Request<*>, INCOMING, INCOMING_WITH_SEQ, SUCCESS_RESPONSE>,
|
||||
ResultReader<SUCCESS_RESPONSE>,
|
||||
MessageProcessor {
|
||||
private val currentSequence = AtomicInteger()
|
||||
protected val messageManager = MessageManager(this)
|
||||
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.rpc
|
||||
|
||||
import org.jetbrains.concurrency.AsyncPromise
|
||||
@@ -23,28 +9,28 @@ import org.jetbrains.jsonProtocol.Request
|
||||
abstract class CommandSenderBase<SUCCESS_RESPONSE> {
|
||||
protected abstract fun <RESULT> doSend(message: Request<RESULT>, callback: RequestPromise<SUCCESS_RESPONSE, RESULT>)
|
||||
|
||||
fun <RESULT> send(message: Request<RESULT>): Promise<RESULT> {
|
||||
fun <RESULT : Any?> send(message: Request<RESULT>): Promise<RESULT> {
|
||||
val callback = RequestPromise<SUCCESS_RESPONSE, RESULT>(message.methodName)
|
||||
doSend(message, callback)
|
||||
return callback
|
||||
}
|
||||
}
|
||||
|
||||
class RequestPromise<SUCCESS_RESPONSE, RESULT>(private val methodName: String?) : AsyncPromise<RESULT>(), RequestCallback<SUCCESS_RESPONSE> {
|
||||
class RequestPromise<SUCCESS_RESPONSE, RESULT : Any?>(private val methodName: String?) : AsyncPromise<RESULT>(), RequestCallback<SUCCESS_RESPONSE> {
|
||||
override fun onSuccess(response: SUCCESS_RESPONSE?, resultReader: ResultReader<SUCCESS_RESPONSE>?) {
|
||||
catchError {
|
||||
val r: Any?
|
||||
if (resultReader == null || response == null) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
setResult(response as RESULT?)
|
||||
r = response
|
||||
}
|
||||
else if (methodName == null) {
|
||||
r = null
|
||||
}
|
||||
else {
|
||||
if (methodName == null) {
|
||||
setResult(null)
|
||||
}
|
||||
else {
|
||||
setResult(resultReader.readResult(methodName, response))
|
||||
}
|
||||
r = resultReader.readResult(methodName, response)
|
||||
}
|
||||
|
||||
UnsafeSetResult.setResult(this, r)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.rpc;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.concurrency.AsyncPromise;
|
||||
|
||||
// we cannot fix all WIP types to be nullable for now,
|
||||
// but don't want to to use explicitly nullable result type for method setResult
|
||||
class UnsafeSetResult {
|
||||
static <T> void setResult(@NotNull AsyncPromise<T> promise, @Nullable Object result) {
|
||||
//noinspection unchecked
|
||||
promise.setResult((T)result);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,12 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.debugger
|
||||
|
||||
import com.intellij.xdebugger.frame.XCompositeNode
|
||||
import com.intellij.xdebugger.frame.XValueChildrenList
|
||||
import com.intellij.xdebugger.frame.XValueNode
|
||||
import org.jetbrains.concurrency.Promise
|
||||
import org.jetbrains.concurrency.done
|
||||
import org.jetbrains.concurrency.rejected
|
||||
import org.jetbrains.concurrency.onError
|
||||
import org.jetbrains.concurrency.onSuccess
|
||||
import org.jetbrains.concurrency.resolvedPromise
|
||||
import org.jetbrains.debugger.values.ObjectValue
|
||||
import org.jetbrains.debugger.values.Value
|
||||
@@ -41,10 +27,10 @@ open class BasicDebuggerViewSupport : MemberFilter, DebuggerViewSupport {
|
||||
|
||||
override fun computeReceiverVariable(context: VariableContext, callFrame: CallFrame, node: XCompositeNode): Promise<*> {
|
||||
return callFrame.receiverVariable
|
||||
.done(node) {
|
||||
.onSuccess(node) {
|
||||
node.addChildren(if (it == null) XValueChildrenList.EMPTY else XValueChildrenList.singleton(VariableView(it, context)), true)
|
||||
}
|
||||
.rejected(node) {
|
||||
.onError(node) {
|
||||
node.addChildren(XValueChildrenList.EMPTY, true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.debugger
|
||||
|
||||
import com.intellij.execution.ExecutionResult
|
||||
@@ -205,7 +191,8 @@ abstract class DebugProcessImpl<C : VmConnection<*>>(session: XDebugSession,
|
||||
}
|
||||
|
||||
override final fun startPausing() {
|
||||
activeOrMainVm!!.suspendContextManager.suspend().rejected(RejectErrorReporter(session, "Cannot pause"))
|
||||
activeOrMainVm!!.suspendContextManager.suspend()
|
||||
.onError(RejectErrorReporter(session, "Cannot pause"))
|
||||
}
|
||||
|
||||
override final fun getCurrentStateMessage() = connection.state.message
|
||||
|
||||
@@ -1,25 +1,11 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.debugger
|
||||
|
||||
import com.intellij.xdebugger.frame.XCompositeNode
|
||||
import com.intellij.xdebugger.frame.XValueChildrenList
|
||||
import com.intellij.xdebugger.frame.XValueGroup
|
||||
import org.jetbrains.concurrency.done
|
||||
import org.jetbrains.concurrency.errorIfNotMessage
|
||||
import org.jetbrains.concurrency.onSuccess
|
||||
import org.jetbrains.debugger.values.FunctionValue
|
||||
import org.jetbrains.rpc.LOG
|
||||
import java.util.*
|
||||
@@ -29,7 +15,7 @@ internal class FunctionScopesValueGroup(private val functionValue: FunctionValue
|
||||
node.setAlreadySorted(true)
|
||||
|
||||
functionValue.resolve()
|
||||
.done(node) {
|
||||
.onSuccess(node) {
|
||||
val scopes = it.scopes
|
||||
if (scopes == null || scopes.size == 0) {
|
||||
node.addChildren(XValueChildrenList.EMPTY, true)
|
||||
|
||||
@@ -1,26 +1,12 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.debugger
|
||||
|
||||
import com.intellij.xdebugger.XDebuggerBundle
|
||||
import com.intellij.xdebugger.frame.XCompositeNode
|
||||
import com.intellij.xdebugger.frame.XValueChildrenList
|
||||
import com.intellij.xdebugger.frame.XValueGroup
|
||||
import org.jetbrains.concurrency.done
|
||||
import org.jetbrains.concurrency.rejected
|
||||
import org.jetbrains.concurrency.onError
|
||||
import org.jetbrains.concurrency.onSuccess
|
||||
import org.jetbrains.concurrency.thenAsyncAccept
|
||||
|
||||
class ScopeVariablesGroup(val scope: Scope, parentContext: VariableContext, callFrame: CallFrame?) : XValueGroup(scope.createScopeNodeName()) {
|
||||
@@ -42,13 +28,13 @@ class ScopeVariablesGroup(val scope: Scope, parentContext: VariableContext, call
|
||||
}
|
||||
|
||||
promise
|
||||
.done(node) {
|
||||
.onSuccess(node) {
|
||||
context.memberFilter
|
||||
.thenAsyncAccept(node) {
|
||||
if (it.hasNameMappings()) {
|
||||
it.sourceNameToRaw(RECEIVER_NAME)?.let {
|
||||
return@thenAsyncAccept callFrame.evaluateContext.evaluate(it)
|
||||
.done(node) {
|
||||
.onSuccess(node) {
|
||||
VariableImpl(RECEIVER_NAME, it.value, null)
|
||||
node.addChildren(XValueChildrenList.singleton(VariableView(
|
||||
VariableImpl(RECEIVER_NAME, it.value, null), context)), true)
|
||||
@@ -58,7 +44,7 @@ class ScopeVariablesGroup(val scope: Scope, parentContext: VariableContext, call
|
||||
|
||||
context.viewSupport.computeReceiverVariable(context, callFrame, node)
|
||||
}
|
||||
.rejected(node) {
|
||||
.onError(node) {
|
||||
context.viewSupport.computeReceiverVariable(context, callFrame, node)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.debugger
|
||||
|
||||
import com.intellij.icons.AllIcons
|
||||
@@ -196,7 +182,7 @@ class ExecutionStackView(val suspendContext: SuspendContext<*>,
|
||||
override fun computeStackFrames(firstFrameIndex: Int, container: XExecutionStack.XStackFrameContainer) {
|
||||
// WipSuspendContextManager set context to null on resume _before_ vm.getDebugListener().resumed() call() (in any case, XFramesView can queue event to EDT), so, IDE state could be outdated compare to VM (our) state
|
||||
suspendContext.frames
|
||||
.done(suspendContext) { frames ->
|
||||
.onSuccess(suspendContext) { frames ->
|
||||
val count = frames.size - firstFrameIndex
|
||||
val result: List<XStackFrame>
|
||||
if (count < 1) {
|
||||
|
||||
@@ -63,7 +63,7 @@ class VariableView(override val variableName: String, private val variable: Vari
|
||||
if (variable !is ObjectProperty || variable.getter == null) {
|
||||
// it is "used" expression (WEB-6779 Debugger/Variables: Automatically show used variables)
|
||||
evaluateContext.evaluate(variable.name)
|
||||
.done(node) {
|
||||
.onSuccess(node) {
|
||||
if (it.wasThrown) {
|
||||
setEvaluatedValue(viewSupport.transformErrorOnGetUsedReferenceValue(it.value, null), null, node)
|
||||
}
|
||||
@@ -72,7 +72,7 @@ class VariableView(override val variableName: String, private val variable: Vari
|
||||
computePresentation(it.value, node)
|
||||
}
|
||||
}
|
||||
.rejected(node) { setEvaluatedValue(viewSupport.transformErrorOnGetUsedReferenceValue(null, it.message), it.message, node) }
|
||||
.onError(node) { setEvaluatedValue(viewSupport.transformErrorOnGetUsedReferenceValue(null, it.message), it.message, node) }
|
||||
return
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ class VariableView(override val variableName: String, private val variable: Vari
|
||||
nonProtoContext = nonProtoContext.parent
|
||||
}
|
||||
valueModifier!!.evaluateGet(variable, evaluateContext)
|
||||
.done(node) {
|
||||
.onSuccess(node) {
|
||||
callback.evaluated("")
|
||||
setEvaluatedValue(it, null, node)
|
||||
}
|
||||
@@ -318,9 +318,9 @@ class VariableView(override val variableName: String, private val variable: Vari
|
||||
override fun computeSourcePosition(navigatable: XNavigatable) {
|
||||
if (value is FunctionValue) {
|
||||
(value as FunctionValue).resolve()
|
||||
.done { function ->
|
||||
.onSuccess { function ->
|
||||
vm!!.scriptManager.getScript(function)
|
||||
.done {
|
||||
.onSuccess {
|
||||
navigatable.setSourcePosition(it?.let { viewSupport.getSourceInfo(null, it, function.openParenLine, function.openParenColumn) }?.let {
|
||||
object : XSourcePositionWrapper(it) {
|
||||
override fun createNavigatable(project: Project): Navigatable {
|
||||
@@ -394,12 +394,12 @@ class VariableView(override val variableName: String, private val variable: Vari
|
||||
|
||||
val evaluated = AtomicBoolean()
|
||||
value.fullString
|
||||
.done {
|
||||
.onSuccess {
|
||||
if (!callback.isObsolete && evaluated.compareAndSet(false, true)) {
|
||||
callback.evaluated(value.valueString!!)
|
||||
}
|
||||
}
|
||||
.rejected { callback.errorOccurred(it.message!!) }
|
||||
.onError { callback.errorOccurred(it.message!!) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,8 +425,8 @@ class VariableView(override val variableName: String, private val variable: Vari
|
||||
}
|
||||
else {
|
||||
context.evaluateContext.evaluate("a.length", Collections.singletonMap<String, Any>("a", value), false)
|
||||
.done(node) { node.setPresentation(icon, null, "Array[${it.value.valueString}]", true) }
|
||||
.rejected(node) {
|
||||
.onSuccess(node) { node.setPresentation(icon, null, "Array[${it.value.valueString}]", true) }
|
||||
.onError(node) {
|
||||
logger<VariableView>().error("Failed to evaluate array length: $it")
|
||||
node.setPresentation(icon, null, valueString ?: "Array", true)
|
||||
}
|
||||
|
||||
+3
-17
@@ -1,27 +1,13 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.debugger
|
||||
|
||||
import com.intellij.util.Consumer
|
||||
import com.intellij.xdebugger.XDebugSession
|
||||
import org.jetbrains.concurrency.errorIfNotMessage
|
||||
import org.jetbrains.rpc.LOG
|
||||
import java.util.function.Consumer
|
||||
|
||||
class RejectErrorReporter @JvmOverloads constructor(private val session: XDebugSession, private val description: String? = null) : Consumer<Throwable> {
|
||||
override fun consume(error: Throwable) {
|
||||
override fun accept(error: Throwable) {
|
||||
if (LOG.errorIfNotMessage(error)) {
|
||||
session.reportError("${if (description == null) "" else "$description: "}${error.message}")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user