Promise.cancel() API instead of low-level OBSOLETE_ERROR
authorVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Fri, 1 Jul 2016 10:33:15 +0000 (12:33 +0200)
committerVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Fri, 1 Jul 2016 11:04:39 +0000 (13:04 +0200)
platform/platform-api/src/org/jetbrains/concurrency/AsyncPromise.kt
platform/platform-api/src/org/jetbrains/concurrency/Promise.java
platform/script-debugger/backend/src/DeclarativeScope.kt
platform/script-debugger/backend/src/org/jetbrains/debugger/VariablesHost.java
platform/script-debugger/backend/src/org/jetbrains/debugger/values/ValueManager.kt
platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/RejectErrorReporter.kt
platform/script-debugger/debugger-ui/src/util.kt [deleted file]

index 51a81a86bfb6078f6ca903256a36b38c8b4ec72b..91f13db02c968c55bf5242e58b5b3ca5e34e85b4 100644 (file)
@@ -24,7 +24,7 @@ import java.util.*
 private val LOG = Logger.getInstance(AsyncPromise::class.java)
 
 @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
-val OBSOLETE_ERROR = Promise.createError("Obsolete")
+private val OBSOLETE_ERROR = Promise.createError("Obsolete")
 
 open class AsyncPromise<T> : Promise<T>(), Getter<T> {
   @Volatile private var done: Consumer<in T>? = null
@@ -92,7 +92,7 @@ open class AsyncPromise<T> : Promise<T>(), Getter<T> {
     addHandlers(Consumer({ result ->
                            promise.catchError {
                              if (fulfilled is Obsolescent && fulfilled.isObsolete) {
-                               promise.setError(OBSOLETE_ERROR)
+                               promise.cancel()
                              }
                              else {
                                promise.setResult(fulfilled.`fun`(result))
@@ -186,6 +186,10 @@ open class AsyncPromise<T> : Promise<T>(), Getter<T> {
     return setError(Promise.createError(error))
   }
 
+  fun cancel() {
+    setError(OBSOLETE_ERROR)
+  }
+
   open fun setError(error: Throwable): Boolean {
     if (state != Promise.State.PENDING) {
       return false
@@ -272,4 +276,9 @@ inline fun <T> AsyncPromise<*>.catchError(runnable: () -> T): T? {
   }
 }
 
+private val cancelledPromise = RejectedPromise<Any?>(OBSOLETE_ERROR)
+
+@Suppress("CAST_NEVER_SUCCEEDS")
+fun <T> cancelledPromise(): Promise<T> = cancelledPromise as Promise<T>
+
 fun <T> rejectedPromise(error: Throwable): Promise<T> = Promise.reject(error)
\ No newline at end of file
index e5d186f75703a7e2ad996fc4b0401253a978a4e7..ffeb4d5d914224d75a6d535978f660ab15d9f660 100644 (file)
@@ -69,17 +69,8 @@ public abstract class Promise<T> {
   @NotNull
   public static Promise<Void> wrapAsVoid(@NotNull ActionCallback asyncResult) {
     final AsyncPromise<Void> promise = new AsyncPromise<Void>();
-    asyncResult.doWhenDone(new Runnable() {
-      @Override
-      public void run() {
-        promise.setResult(null);
-      }
-    }).doWhenRejected(new Consumer<String>() {
-      @Override
-      public void consume(String error) {
-        promise.setError(createError(error == null ? "Internal error" : error));
-      }
-    });
+    asyncResult.doWhenDone(() -> promise.setResult(null)).doWhenRejected(
+      error -> promise.setError(createError(error == null ? "Internal error" : error)));
     return promise;
   }
 
@@ -91,12 +82,7 @@ public abstract class Promise<T> {
       public void consume(T result) {
         promise.setResult(result);
       }
-    }).doWhenRejected(new Consumer<String>() {
-      @Override
-      public void consume(String error) {
-        promise.setError(error);
-      }
-    });
+    }).doWhenRejected(promise::setError);
     return promise;
   }
 
@@ -146,16 +132,20 @@ public abstract class Promise<T> {
   /**
    * Log error if not message error
    */
-  public static void logError(@NotNull Logger logger, @NotNull Throwable e) {
+  public static boolean logError(@NotNull Logger logger, @NotNull Throwable e) {
     if (e instanceof MessageError) {
       ThreeState log = ((MessageError)e).log;
       if (log == ThreeState.YES || (log == ThreeState.UNSURE && ApplicationManager.getApplication().isUnitTestMode())) {
         logger.error(e);
+        return true;
       }
     }
     else if (!(e instanceof ProcessCanceledException)) {
       logger.error(e);
+      return true;
     }
+
+    return false;
   }
 
   public abstract void notify(@NotNull AsyncPromise<? super T> child);
index db1e206776a37eed751d47a1a7d3f907141b026c..ed6523dd66d5faf77eb16cec72259e0cea128d82 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -15,8 +15,8 @@
  */
 package org.jetbrains.debugger
 
-import com.intellij.util.Consumer
 import org.jetbrains.concurrency.Promise
+import org.jetbrains.concurrency.cancelledPromise
 import org.jetbrains.debugger.values.ObjectValue
 import org.jetbrains.debugger.values.ValueManager
 
@@ -25,14 +25,10 @@ abstract class DeclarativeScope<VALUE_MANAGER : ValueManager>(type: Scope.Type,
 
   protected fun loadScopeObjectProperties(value: ObjectValue): Promise<List<Variable>> {
     if (childrenManager.valueManager.isObsolete) {
-      return ValueManager.reject()
+      return cancelledPromise()
     }
 
-    return value.properties.done(object : Consumer<List<Variable>> {
-      override fun consume(variables: List<Variable>) {
-        childrenManager.updateCacheStamp()
-      }
-    })
+    return value.properties.done { childrenManager.updateCacheStamp() }
   }
 
   override fun getVariablesHost() = childrenManager
index 746016d690cf37cd14f67da4a642617d831e582a..f83f8010a2c44fe59d1f284362c4e53aa2b5f91d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -17,6 +17,7 @@ package org.jetbrains.debugger;
 
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.concurrency.AsyncPromiseKt;
 import org.jetbrains.concurrency.Promise;
 import org.jetbrains.concurrency.PromiseManager;
 import org.jetbrains.debugger.values.ValueManager;
@@ -35,7 +36,7 @@ public abstract class VariablesHost<VALUE_MANAGER extends ValueManager> {
       @NotNull
       @Override
       public Promise load(@NotNull VariablesHost host) {
-        return host.valueManager.isObsolete() ? ValueManager.Companion.reject() : host.load();
+        return host.valueManager.isObsolete() ? AsyncPromiseKt.cancelledPromise() : host.load();
       }
     };
 
index 43a7120be001d2d92ab84a4a4c9355b59e31e294..f1d1ee5740c39d37ce8eff06010bef330137d156 100644 (file)
  */
 package org.jetbrains.debugger.values
 
-import org.jetbrains.concurrency.OBSOLETE_ERROR
 import org.jetbrains.concurrency.Obsolescent
-import org.jetbrains.concurrency.Promise
-import org.jetbrains.concurrency.rejectedPromise
 import java.util.concurrent.atomic.AtomicInteger
 
 /**
@@ -43,11 +40,4 @@ abstract class ValueManager() : Obsolescent {
   fun markObsolete() {
     obsolete = true
   }
-
-  companion object {
-    val OBSOLETE_CONTEXT_PROMISE = rejectedPromise<Any?>(OBSOLETE_ERROR)
-
-    @Suppress("UNCHECKED_CAST")
-    fun <T> reject() = OBSOLETE_CONTEXT_PROMISE as Promise<T>
-  }
 }
\ No newline at end of file
index 604718a562e65f52c4c2edbcac7f22e679eb2e45..9a2b08606ce534723a760148e08f45e21b4b1f52 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * 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.
@@ -17,15 +17,13 @@ package org.jetbrains.debugger
 
 import com.intellij.util.Consumer
 import com.intellij.xdebugger.XDebugSession
-import org.jetbrains.concurrency.OBSOLETE_ERROR
 import org.jetbrains.concurrency.Promise
 import org.jetbrains.rpc.LOG
 
 class RejectErrorReporter @JvmOverloads constructor(private val session: XDebugSession, private val description: String? = null) : Consumer<Throwable> {
   override fun consume(error: Throwable) {
-    Promise.logError(LOG, error)
-    if (error !== OBSOLETE_ERROR) {
-      session.reportError((if (description == null) "" else "$description: ") + error.message)
+    if (Promise.logError(LOG, error)) {
+      session.reportError("${if (description == null) "" else "$description: "}${error.message}")
     }
   }
 }
\ No newline at end of file
diff --git a/platform/script-debugger/debugger-ui/src/util.kt b/platform/script-debugger/debugger-ui/src/util.kt
deleted file mode 100644 (file)
index ab8df6a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.
- */
-package com.intellij.xdebugger.util
-
-import com.intellij.xdebugger.XDebugSession
-import org.jetbrains.concurrency.OBSOLETE_ERROR
-import org.jetbrains.concurrency.Promise
-import org.jetbrains.rpc.LOG
-
-// have to use package "com.intellij.xdebugger.util" to avoid package clash
-fun XDebugSession.rejectedErrorReporter(description: String? = null): (Throwable) -> Unit = {
-  Promise.logError(LOG, it)
-  if (it != OBSOLETE_ERROR) {
-    reportError("${if (description == null) "" else description + ": "}${it.message}")
-  }
-}
\ No newline at end of file