From 730ca354050f46e4894e09a301f7ff40558ab313 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Tue, 30 May 2023 13:13:36 -0700 Subject: [PATCH] Prepare bolts.Task to be safe to be usde from Kotlin Summary: In this diff I analyzed bolts.Task class to ensure it's ready to be used from kotlin. I won't convert bolts.Task to kotlin, but this is necessary to be able to convert its callsites (ReactHost) to kotlin This is a 'continuation' of the previous diff, I splitted in 2 because Task is a very large class and it's worth analyzing separately. bypass-github-export-checks changelog: [internal] internal Reviewed By: cortinico Differential Revision: D46194126 fbshipit-source-id: 765af7683fa62814747c7d8516d311cffabac3c1 --- .../react/bridgeless/internal/bolts/Task.java | 233 ++++++++++-------- 1 file changed, 125 insertions(+), 108 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/internal/bolts/Task.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/internal/bolts/Task.java index 499afcab9d1..5b66c9496c7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/internal/bolts/Task.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridgeless/internal/bolts/Task.java @@ -7,6 +7,8 @@ package com.facebook.react.bridgeless.internal.bolts; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -59,14 +61,14 @@ public class Task { * @param t the task * @param e the exception */ - void unobservedException(Task t, UnobservedTaskException e); + void unobservedException(@NonNull Task t, @NonNull UnobservedTaskException e); } // null unless explicitly set private static volatile UnobservedExceptionHandler unobservedExceptionHandler; /** Returns the handler invoked when a task has an unobserved exception or {@code null}. */ - public static UnobservedExceptionHandler getUnobservedExceptionHandler() { + public static @Nullable UnobservedExceptionHandler getUnobservedExceptionHandler() { return unobservedExceptionHandler; } @@ -83,15 +85,15 @@ public class Task { private final Object lock = new Object(); private boolean complete; private boolean cancelled; - private TResult result; - private Exception error; + @Nullable private TResult result; + @Nullable private Exception error; private boolean errorHasBeenObserved; - private UnobservedErrorNotifier unobservedErrorNotifier; - private List> continuations = new ArrayList<>(); + @Nullable private UnobservedErrorNotifier unobservedErrorNotifier; + @Nullable private List> continuations = new ArrayList<>(); /* package */ Task() {} - private Task(TResult result) { + private Task(@Nullable TResult result) { trySetResult(result); } @@ -103,7 +105,7 @@ public class Task { } } - public static TaskCompletionSource create() { + public static @NonNull TaskCompletionSource create() { Task task = new Task<>(); return new TaskCompletionSource(); } @@ -133,14 +135,14 @@ public class Task { } /** @return The result of the task, if set. {@code null} otherwise. */ - public TResult getResult() { + public @Nullable TResult getResult() { synchronized (lock) { return result; } } /** @return The error for the task, if set. {@code null} otherwise. */ - public Exception getError() { + public @Nullable Exception getError() { synchronized (lock) { if (error != null) { errorHasBeenObserved = true; @@ -168,7 +170,8 @@ public class Task { * @return {@code true} if the task completed (has a result, an error, or was cancelled). {@code * false} otherwise. */ - public boolean waitForCompletion(long duration, TimeUnit timeUnit) throws InterruptedException { + public boolean waitForCompletion(long duration, @NonNull TimeUnit timeUnit) + throws InterruptedException { synchronized (lock) { if (!isCompleted()) { lock.wait(timeUnit.toMillis(duration)); @@ -179,7 +182,7 @@ public class Task { /** Creates a completed task with the given value. */ @SuppressWarnings("unchecked") - public static Task forResult(TResult value) { + public static @NonNull Task forResult(@Nullable TResult value) { if (value == null) { return (Task) TASK_NULL; } @@ -192,7 +195,7 @@ public class Task { } /** Creates a faulted task with the given error. */ - public static Task forError(Exception error) { + public static @NonNull Task forError(@Nullable Exception error) { TaskCompletionSource tcs = new TaskCompletionSource<>(); tcs.setError(error); return tcs.getTask(); @@ -200,7 +203,7 @@ public class Task { /** Creates a cancelled task. */ @SuppressWarnings("unchecked") - public static Task cancelled() { + public static @NonNull Task cancelled() { return (Task) TASK_CANCELLED; } @@ -210,7 +213,7 @@ public class Task { * @param delay The number of milliseconds to wait before completing the returned task. Zero and * negative values are treated as requests for immediate execution. */ - public static Task delay(long delay) { + public static @NonNull Task delay(long delay) { return delay(delay, BoltsExecutors.scheduled(), null); } @@ -222,12 +225,15 @@ public class Task { * @param cancellationToken The optional cancellation token that will be checked prior to * completing the returned task. */ - public static Task delay(long delay, CancellationToken cancellationToken) { + public static @NonNull Task delay( + long delay, @Nullable CancellationToken cancellationToken) { return delay(delay, BoltsExecutors.scheduled(), cancellationToken); } - /* package */ static Task delay( - long delay, ScheduledExecutorService executor, final CancellationToken cancellationToken) { + /* package */ static @NonNull Task delay( + long delay, + @NonNull ScheduledExecutorService executor, + @Nullable final CancellationToken cancellationToken) { if (cancellationToken != null && cancellationToken.isCancellationRequested()) { return Task.cancelled(); } @@ -266,14 +272,14 @@ public class Task { * Makes a fluent cast of a Task's result possible, avoiding an extra continuation just to cast * the type of the result. */ - public Task cast() { + public @NonNull Task cast() { @SuppressWarnings("unchecked") Task task = (Task) this; return task; } /** Turns a Task into a Task, dropping any result. */ - public Task makeVoid() { + public @NonNull Task makeVoid() { return this.continueWithTask( new Continuation>() { @Override @@ -295,13 +301,14 @@ public class Task { *

If you want to cancel the resulting Task throw a {@link * java.util.concurrent.CancellationException} from the callable. */ - public static Task callInBackground(Callable callable) { + public static @NonNull Task callInBackground( + @NonNull Callable callable) { return call(callable, BACKGROUND_EXECUTOR, null); } /** Invokes the callable on a background thread, returning a Task to represent the operation. */ - public static Task callInBackground( - Callable callable, CancellationToken ct) { + public static @NonNull Task callInBackground( + @NonNull Callable callable, @Nullable CancellationToken ct) { return call(callable, BACKGROUND_EXECUTOR, ct); } @@ -311,13 +318,16 @@ public class Task { *

If you want to cancel the resulting Task throw a {@link * java.util.concurrent.CancellationException} from the callable. */ - public static Task call(final Callable callable, Executor executor) { + public static @NonNull Task call( + @NonNull final Callable callable, @NonNull Executor executor) { return call(callable, executor, null); } /** Invokes the callable using the given executor, returning a Task to represent the operation. */ - public static Task call( - final Callable callable, Executor executor, final CancellationToken ct) { + public static @NonNull Task call( + @NonNull final Callable callable, + @NonNull Executor executor, + @Nullable final CancellationToken ct) { final TaskCompletionSource tcs = new TaskCompletionSource<>(); try { executor.execute( @@ -351,13 +361,13 @@ public class Task { *

If you want to cancel the resulting Task throw a {@link * java.util.concurrent.CancellationException} from the callable. */ - public static Task call(final Callable callable) { + public static @NonNull Task call(@NonNull final Callable callable) { return call(callable, IMMEDIATE_EXECUTOR, null); } /** Invokes the callable on the current thread, producing a Task. */ - public static Task call( - final Callable callable, CancellationToken ct) { + public static @NonNull Task call( + @NonNull final Callable callable, @Nullable CancellationToken ct) { return call(callable, IMMEDIATE_EXECUTOR, ct); } @@ -372,8 +382,8 @@ public class Task { * @return A task that represents the completion of one of the supplied tasks. The return task's * result is the task that completed. */ - public static Task> whenAnyResult( - Collection> tasks) { + public static @NonNull Task> whenAnyResult( + @NonNull Collection> tasks) { if (tasks.size() == 0) { return Task.forResult(null); } @@ -410,7 +420,7 @@ public class Task { * Result is the task that completed. */ @SuppressWarnings("unchecked") - public static Task> whenAny(Collection> tasks) { + public static @NonNull Task> whenAny(@NonNull Collection> tasks) { if (tasks.size() == 0) { return Task.forResult(null); } @@ -462,8 +472,8 @@ public class Task { * @return A Task that will resolve to {@code List<TResult>} when all the tasks are * resolved. */ - public static Task> whenAllResult( - final Collection> tasks) { + public static @NonNull Task> whenAllResult( + @NonNull final Collection> tasks) { return whenAll(tasks) .onSuccess( new Continuation>() { @@ -502,7 +512,7 @@ public class Task { * @param tasks The tasks that the return value will wait for before completing. * @return A Task that will resolve to {@code Void} when all the tasks are resolved. */ - public static Task whenAll(Collection> tasks) { + public static @NonNull Task whenAll(@NonNull Collection> tasks) { if (tasks.size() == 0) { return Task.forResult(null); } @@ -558,8 +568,8 @@ public class Task { * Continues a task with the equivalent of a Task-based while loop, where the body of the loop is * a task continuation. */ - public Task continueWhile( - Callable predicate, Continuation> continuation) { + public @NonNull Task continueWhile( + @NonNull Callable predicate, @NonNull Continuation> continuation) { return continueWhile(predicate, continuation, IMMEDIATE_EXECUTOR, null); } @@ -567,10 +577,10 @@ public class Task { * Continues a task with the equivalent of a Task-based while loop, where the body of the loop is * a task continuation. */ - public Task continueWhile( - Callable predicate, - Continuation> continuation, - CancellationToken ct) { + public @NonNull Task continueWhile( + @NonNull Callable predicate, + @NonNull Continuation> continuation, + @Nullable CancellationToken ct) { return continueWhile(predicate, continuation, IMMEDIATE_EXECUTOR, ct); } @@ -578,10 +588,10 @@ public class Task { * Continues a task with the equivalent of a Task-based while loop, where the body of the loop is * a task continuation. */ - public Task continueWhile( - final Callable predicate, - final Continuation> continuation, - final Executor executor) { + public @NonNull Task continueWhile( + @NonNull final Callable predicate, + @NonNull final Continuation> continuation, + @NonNull final Executor executor) { return continueWhile(predicate, continuation, executor, null); } @@ -589,11 +599,11 @@ public class Task { * Continues a task with the equivalent of a Task-based while loop, where the body of the loop is * a task continuation. */ - public Task continueWhile( - final Callable predicate, - final Continuation> continuation, - final Executor executor, - final CancellationToken ct) { + public @NonNull Task continueWhile( + @NonNull final Callable predicate, + @NonNull final Continuation> continuation, + @NonNull final Executor executor, + @Nullable final CancellationToken ct) { final Capture>> predicateContinuation = new Capture<>(); predicateContinuation.set( new Continuation>() { @@ -619,8 +629,9 @@ public class Task { * completes after the continuation has finished running. This allows the continuation to be * scheduled on different thread. */ - public Task continueWith( - final Continuation continuation, final Executor executor) { + public @NonNull Task continueWith( + @NonNull final Continuation continuation, + @NonNull final Executor executor) { return continueWith(continuation, executor, null); } @@ -629,10 +640,10 @@ public class Task { * completes after the continuation has finished running. This allows the continuation to be * scheduled on different thread. */ - public Task continueWith( - final Continuation continuation, - final Executor executor, - final CancellationToken ct) { + public @NonNull Task continueWith( + @NonNull final Continuation continuation, + @NonNull final Executor executor, + @Nullable final CancellationToken ct) { boolean completed; final TaskCompletionSource tcs = new TaskCompletionSource<>(); synchronized (lock) { @@ -658,8 +669,8 @@ public class Task { * Adds a synchronous continuation to this task, returning a new task that completes after the * continuation has finished running. */ - public Task continueWith( - Continuation continuation) { + public @NonNull Task continueWith( + @NonNull Continuation continuation) { return continueWith(continuation, IMMEDIATE_EXECUTOR, null); } @@ -667,8 +678,9 @@ public class Task { * Adds a synchronous continuation to this task, returning a new task that completes after the * continuation has finished running. */ - public Task continueWith( - Continuation continuation, CancellationToken ct) { + public @NonNull Task continueWith( + @NonNull Continuation continuation, + @Nullable CancellationToken ct) { return continueWith(continuation, IMMEDIATE_EXECUTOR, ct); } @@ -676,9 +688,9 @@ public class Task { * Adds an Task-based continuation to this task that will be scheduled using the executor, * returning a new task that completes after the task returned by the continuation has completed. */ - public Task continueWithTask( - final Continuation> continuation, - final Executor executor) { + public @NonNull Task continueWithTask( + @NonNull final Continuation> continuation, + @NonNull final Executor executor) { return continueWithTask(continuation, executor, null); } @@ -686,10 +698,10 @@ public class Task { * Adds an Task-based continuation to this task that will be scheduled using the executor, * returning a new task that completes after the task returned by the continuation has completed. */ - public Task continueWithTask( - final Continuation> continuation, - final Executor executor, - final CancellationToken ct) { + public @NonNull Task continueWithTask( + @NonNull final Continuation> continuation, + @NonNull final Executor executor, + @Nullable final CancellationToken ct) { boolean completed; final TaskCompletionSource tcs = new TaskCompletionSource<>(); synchronized (lock) { @@ -715,8 +727,8 @@ public class Task { * Adds an asynchronous continuation to this task, returning a new task that completes after the * task returned by the continuation has completed. */ - public Task continueWithTask( - Continuation> continuation) { + public @NonNull Task continueWithTask( + @NonNull Continuation> continuation) { return continueWithTask(continuation, IMMEDIATE_EXECUTOR, null); } @@ -724,8 +736,9 @@ public class Task { * Adds an asynchronous continuation to this task, returning a new task that completes after the * task returned by the continuation has completed. */ - public Task continueWithTask( - Continuation> continuation, CancellationToken ct) { + public @NonNull Task continueWithTask( + @NonNull Continuation> continuation, + @Nullable CancellationToken ct) { return continueWithTask(continuation, IMMEDIATE_EXECUTOR, ct); } @@ -733,8 +746,9 @@ public class Task { * Runs a continuation when a task completes successfully, forwarding along {@link * java.lang.Exception} or cancellation. */ - public Task onSuccess( - final Continuation continuation, Executor executor) { + public @NonNull Task onSuccess( + @NonNull final Continuation continuation, + @NonNull Executor executor) { return onSuccess(continuation, executor, null); } @@ -742,10 +756,10 @@ public class Task { * Runs a continuation when a task completes successfully, forwarding along {@link * java.lang.Exception} or cancellation. */ - public Task onSuccess( - final Continuation continuation, - Executor executor, - final CancellationToken ct) { + public @NonNull Task onSuccess( + @NonNull final Continuation continuation, + @NonNull Executor executor, + @Nullable final CancellationToken ct) { return continueWithTask( new Continuation>() { @Override @@ -770,8 +784,8 @@ public class Task { * Runs a continuation when a task completes successfully, forwarding along {@link * java.lang.Exception}s or cancellation. */ - public Task onSuccess( - final Continuation continuation) { + public @NonNull Task onSuccess( + @NonNull final Continuation continuation) { return onSuccess(continuation, IMMEDIATE_EXECUTOR, null); } @@ -779,8 +793,9 @@ public class Task { * Runs a continuation when a task completes successfully, forwarding along {@link * java.lang.Exception}s or cancellation. */ - public Task onSuccess( - final Continuation continuation, CancellationToken ct) { + public @NonNull Task onSuccess( + @NonNull final Continuation continuation, + @Nullable CancellationToken ct) { return onSuccess(continuation, IMMEDIATE_EXECUTOR, ct); } @@ -788,8 +803,9 @@ public class Task { * Runs a continuation when a task completes successfully, forwarding along {@link * java.lang.Exception}s or cancellation. */ - public Task onSuccessTask( - final Continuation> continuation, Executor executor) { + public @NonNull Task onSuccessTask( + @NonNull final Continuation> continuation, + @NonNull Executor executor) { return onSuccessTask(continuation, executor, null); } @@ -797,10 +813,10 @@ public class Task { * Runs a continuation when a task completes successfully, forwarding along {@link * java.lang.Exception}s or cancellation. */ - public Task onSuccessTask( - final Continuation> continuation, - Executor executor, - final CancellationToken ct) { + public @NonNull Task onSuccessTask( + @NonNull final Continuation> continuation, + @NonNull Executor executor, + @Nullable final CancellationToken ct) { return continueWithTask( new Continuation>() { @Override @@ -825,8 +841,8 @@ public class Task { * Runs a continuation when a task completes successfully, forwarding along {@link * java.lang.Exception}s or cancellation. */ - public Task onSuccessTask( - final Continuation> continuation) { + public @NonNull Task onSuccessTask( + @NonNull final Continuation> continuation) { return onSuccessTask(continuation, IMMEDIATE_EXECUTOR); } @@ -834,8 +850,9 @@ public class Task { * Runs a continuation when a task completes successfully, forwarding along {@link * java.lang.Exception}s or cancellation. */ - public Task onSuccessTask( - final Continuation> continuation, CancellationToken ct) { + public @NonNull Task onSuccessTask( + @NonNull final Continuation> continuation, + @Nullable CancellationToken ct) { return onSuccessTask(continuation, IMMEDIATE_EXECUTOR, ct); } @@ -851,11 +868,11 @@ public class Task { * be scheduled on a different thread). */ private static void completeImmediately( - final TaskCompletionSource tcs, - final Continuation continuation, - final Task task, - Executor executor, - final CancellationToken ct) { + @NonNull final TaskCompletionSource tcs, + @NonNull final Continuation continuation, + @NonNull final Task task, + @NonNull Executor executor, + @Nullable final CancellationToken ct) { try { executor.execute( new Runnable() { @@ -894,11 +911,11 @@ public class Task { * be scheduled on a different thread). */ private static void completeAfterTask( - final TaskCompletionSource tcs, - final Continuation> continuation, - final Task task, - final Executor executor, - final CancellationToken ct) { + @NonNull final TaskCompletionSource tcs, + @NonNull final Continuation> continuation, + @NonNull final Task task, + @NonNull final Executor executor, + @Nullable final CancellationToken ct) { try { executor.execute( new Runnable() { @@ -917,7 +934,7 @@ public class Task { result.continueWith( new Continuation() { @Override - public Void then(Task task) { + public Void then(@NonNull Task task) { if (ct != null && ct.isCancellationRequested()) { tcs.setCancelled(); return null; @@ -976,7 +993,7 @@ public class Task { } /** Sets the result on the Task if the Task hasn't already been completed. */ - /* package */ boolean trySetResult(TResult result) { + /* package */ boolean trySetResult(@Nullable TResult result) { synchronized (lock) { if (complete) { return false; @@ -990,7 +1007,7 @@ public class Task { } /** Sets the error on the Task if the Task hasn't already been completed. */ - /* package */ boolean trySetError(Exception error) { + /* package */ boolean trySetError(@Nullable Exception error) { synchronized (lock) { if (complete) { return false; @@ -1006,8 +1023,8 @@ public class Task { } } - private static Task TASK_NULL = new Task<>(null); - private static Task TASK_TRUE = new Task<>((Boolean) true); - private static Task TASK_FALSE = new Task<>((Boolean) false); - private static Task TASK_CANCELLED = new Task(true); + private static final Task TASK_NULL = new Task<>(null); + private static final Task TASK_TRUE = new Task<>((Boolean) true); + private static final Task TASK_FALSE = new Task<>((Boolean) false); + private static final Task TASK_CANCELLED = new Task(true); }