Skip to content

Commit

Permalink
Prepare bolts to be safe to use it from Kotlin
Browse files Browse the repository at this point in the history
Summary:
In this diff I analyzed bolts library to ensure it's ready to be used from kotlin.
I won't convert bolts to kotlin, but this is necessary to be able to convert its callsites (ReactHost) to kotlin

bypass-github-export-checks

changelog: [internal] internal

Reviewed By: fkgozali

Differential Revision: D46194127

fbshipit-source-id: 609e356230b1c87fe26571b811d23430d0168276
  • Loading branch information
mdvacca authored and facebook-github-bot committed May 30, 2023
1 parent 88eef42 commit dfb42a3
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

package com.facebook.react.bridgeless.internal.bolts;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
Expand All @@ -24,7 +26,7 @@ public class AggregateException extends Exception {

private static final String DEFAULT_MESSAGE = "There were multiple errors.";

private List<Throwable> innerThrowables;
@NonNull private final List<Throwable> innerThrowables;

/**
* Constructs a new {@code AggregateException} with the current stack trace, the specified detail
Expand All @@ -33,7 +35,7 @@ public class AggregateException extends Exception {
* @param detailMessage The detail message for this exception.
* @param innerThrowables The exceptions that are the cause of the current exception.
*/
public AggregateException(String detailMessage, Throwable[] innerThrowables) {
public AggregateException(@NonNull String detailMessage, @NonNull Throwable[] innerThrowables) {
this(detailMessage, Arrays.asList(innerThrowables));
}

Expand All @@ -44,11 +46,13 @@ public AggregateException(String detailMessage, Throwable[] innerThrowables) {
* @param detailMessage The detail message for this exception.
* @param innerThrowables The exceptions that are the cause of the current exception.
*/
public AggregateException(String detailMessage, List<? extends Throwable> innerThrowables) {
public AggregateException(
@NonNull String detailMessage, @Nullable List<? extends Throwable> innerThrowables) {
super(
detailMessage,
innerThrowables != null && innerThrowables.size() > 0 ? innerThrowables.get(0) : null);
this.innerThrowables = Collections.unmodifiableList(innerThrowables);
this.innerThrowables =
Collections.unmodifiableList(innerThrowables != null ? innerThrowables : new ArrayList<>());
}

/**
Expand All @@ -57,20 +61,20 @@ public AggregateException(String detailMessage, List<? extends Throwable> innerT
*
* @param innerThrowables The exceptions that are the cause of the current exception.
*/
public AggregateException(List<? extends Throwable> innerThrowables) {
public AggregateException(@Nullable List<? extends Throwable> innerThrowables) {
this(DEFAULT_MESSAGE, innerThrowables);
}

/**
* Returns a read-only {@link List} of the {@link Throwable} instances that caused the current
* exception.
*/
public List<Throwable> getInnerThrowables() {
public @NonNull List<Throwable> getInnerThrowables() {
return innerThrowables;
}

@Override
public void printStackTrace(PrintStream err) {
public void printStackTrace(@NonNull PrintStream err) {
super.printStackTrace(err);

int currentIndex = -1;
Expand All @@ -85,7 +89,7 @@ public void printStackTrace(PrintStream err) {
}

@Override
public void printStackTrace(PrintWriter err) {
public void printStackTrace(@NonNull PrintWriter err) {
super.printStackTrace(err);

int currentIndex = -1;
Expand All @@ -101,7 +105,7 @@ public void printStackTrace(PrintWriter err) {

/** @deprecated Please use {@link #getInnerThrowables()} instead. */
@Deprecated
public List<Exception> getErrors() {
public @NonNull List<Exception> getErrors() {
List<Exception> errors = new ArrayList<Exception>();
if (innerThrowables == null) {
return errors;
Expand All @@ -119,7 +123,7 @@ public List<Exception> getErrors() {

/** @deprecated Please use {@link #getInnerThrowables()} instead. */
@Deprecated
public Throwable[] getCauses() {
public @NonNull Throwable[] getCauses() {
return innerThrowables.toArray(new Throwable[innerThrowables.size()]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
Expand All @@ -32,11 +33,12 @@
* 0 and maxPoolSize is Integer.MAX_VALUE. This is dangerous because it can create an unchecked
* amount of threads.
*/
/* package */ final class AndroidExecutors {
/* package */
final class AndroidExecutors {

private static final AndroidExecutors INSTANCE = new AndroidExecutors();

private final Executor uiThread;
@NonNull private final Executor uiThread;

private AndroidExecutors() {
uiThread = new UIThreadExecutor();
Expand Down Expand Up @@ -64,7 +66,7 @@ private AndroidExecutors() {
*
* @return the newly created thread pool
*/
public static ExecutorService newCachedThreadPool() {
public static @NonNull ExecutorService newCachedThreadPool() {
ThreadPoolExecutor executor =
new ThreadPoolExecutor(
CORE_POOL_SIZE,
Expand All @@ -89,7 +91,7 @@ public static ExecutorService newCachedThreadPool() {
* @param threadFactory the factory to use when creating new threads
* @return the newly created thread pool
*/
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
public static @NonNull ExecutorService newCachedThreadPool(@NonNull ThreadFactory threadFactory) {
ThreadPoolExecutor executor =
new ThreadPoolExecutor(
CORE_POOL_SIZE,
Expand All @@ -114,21 +116,21 @@ public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
* @param value true if should time out, else false
*/
@SuppressLint("NewApi")
public static void allowCoreThreadTimeout(ThreadPoolExecutor executor, boolean value) {
public static void allowCoreThreadTimeout(@NonNull ThreadPoolExecutor executor, boolean value) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
executor.allowCoreThreadTimeOut(value);
}
}

/** An {@link java.util.concurrent.Executor} that executes tasks on the UI thread. */
public static Executor uiThread() {
public static @NonNull Executor uiThread() {
return INSTANCE.uiThread;
}

/** An {@link java.util.concurrent.Executor} that runs tasks on the UI thread. */
private static class UIThreadExecutor implements Executor {
@Override
public void execute(Runnable command) {
public void execute(@NonNull Runnable command) {
new Handler(Looper.getMainLooper()).post(command);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@

package com.facebook.react.bridgeless.internal.bolts;

import androidx.annotation.NonNull;
import java.util.Locale;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/** Collection of {@link Executor}s to use in conjunction with {@link Task}. */
/* package */ final class BoltsExecutors {
/* package */
final class BoltsExecutors {

private static final BoltsExecutors INSTANCE = new BoltsExecutors();

Expand All @@ -26,9 +28,9 @@ private static boolean isAndroidRuntime() {
return javaRuntimeName.toLowerCase(Locale.US).contains("android");
}

private final ExecutorService background;
private final ScheduledExecutorService scheduled;
private final Executor immediate;
private final @NonNull ExecutorService background;
private final @NonNull ScheduledExecutorService scheduled;
private final @NonNull Executor immediate;

private BoltsExecutors() {
background =
Expand All @@ -40,11 +42,11 @@ private BoltsExecutors() {
}

/** An {@link java.util.concurrent.Executor} that executes tasks in parallel. */
public static ExecutorService background() {
public static @NonNull ExecutorService background() {
return INSTANCE.background;
}

/* package */ static ScheduledExecutorService scheduled() {
/* package */ static @NonNull ScheduledExecutorService scheduled() {
return INSTANCE.scheduled;
}

Expand All @@ -53,7 +55,7 @@ public static ExecutorService background() {
* stack runs too deep, at which point it will delegate to {@link BoltsExecutors#background} in
* order to trim the stack.
*/
/* package */ static Executor immediate() {
/* package */ static @NonNull Executor immediate() {
return INSTANCE.immediate;
}

Expand Down Expand Up @@ -102,7 +104,7 @@ private int decrementDepth() {
}

@Override
public void execute(Runnable command) {
public void execute(@NonNull Runnable command) {
int depth = incrementDepth();
try {
if (depth <= MAX_DEPTH) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

package com.facebook.react.bridgeless.internal.bolts;

import androidx.annotation.NonNull;
import java.util.Locale;
import java.util.concurrent.CancellationException;

Expand All @@ -29,7 +30,7 @@ public class CancellationToken {

private final CancellationTokenSource tokenSource;

/* package */ CancellationToken(CancellationTokenSource tokenSource) {
/* package */ CancellationToken(@NonNull CancellationTokenSource tokenSource) {
this.tokenSource = tokenSource;
}

Expand All @@ -49,7 +50,7 @@ public boolean isCancellationRequested() {
* @return a {@link CancellationTokenRegistration} instance that can be used to unregister the
* action.
*/
public CancellationTokenRegistration register(Runnable action) {
public @NonNull CancellationTokenRegistration register(@NonNull Runnable action) {
return tokenSource.register(action);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

package com.facebook.react.bridgeless.internal.bolts;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.Closeable;

/**
Expand All @@ -17,12 +19,12 @@
public class CancellationTokenRegistration implements Closeable {

private final Object lock = new Object();
private CancellationTokenSource tokenSource;
private Runnable action;
private @Nullable CancellationTokenSource tokenSource;
private @Nullable Runnable action;
private boolean closed;

/* package */ CancellationTokenRegistration(
CancellationTokenSource tokenSource, Runnable action) {
@NonNull CancellationTokenSource tokenSource, @NonNull Runnable action) {
this.tokenSource = tokenSource;
this.action = action;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

package com.facebook.react.bridgeless.internal.bolts;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -27,9 +29,9 @@
public class CancellationTokenSource implements Closeable {

private final Object lock = new Object();
private final List<CancellationTokenRegistration> registrations = new ArrayList<>();
private final ScheduledExecutorService executor = BoltsExecutors.scheduled();
private ScheduledFuture<?> scheduledCancellation;
private final @NonNull List<CancellationTokenRegistration> registrations = new ArrayList<>();
private final @NonNull ScheduledExecutorService executor = BoltsExecutors.scheduled();
@Nullable private ScheduledFuture<?> scheduledCancellation;
private boolean cancellationRequested;
private boolean closed;

Expand All @@ -48,7 +50,7 @@ public boolean isCancellationRequested() {
}

/** @return the token that can be passed to asynchronous method to control cancellation. */
public CancellationToken getToken() {
public @NonNull CancellationToken getToken() {
synchronized (lock) {
throwIfClosed();
return new CancellationToken(this);
Expand Down Expand Up @@ -84,7 +86,7 @@ public void cancelAfter(final long delay) {
cancelAfter(delay, TimeUnit.MILLISECONDS);
}

private void cancelAfter(long delay, TimeUnit timeUnit) {
private void cancelAfter(long delay, @NonNull TimeUnit timeUnit) {
if (delay < -1) {
throw new IllegalArgumentException("Delay must be >= -1");
}
Expand Down Expand Up @@ -137,7 +139,8 @@ public void close() {
}
}

/* package */ CancellationTokenRegistration register(Runnable action) {
/* package */ @NonNull
CancellationTokenRegistration register(@NonNull Runnable action) {
CancellationTokenRegistration ctr;
synchronized (lock) {
throwIfClosed();
Expand Down Expand Up @@ -165,7 +168,7 @@ public void close() {
}
}

/* package */ void unregister(CancellationTokenRegistration registration) {
/* package */ void unregister(@NonNull CancellationTokenRegistration registration) {
synchronized (lock) {
throwIfClosed();
registrations.remove(registration);
Expand All @@ -178,7 +181,7 @@ public void close() {
// to be synchronized with state changes you should provide external synchronization.
// If this is invoked without external synchronization there is a probability the token becomes
// cancelled concurrently.
private void notifyListeners(List<CancellationTokenRegistration> registrations) {
private void notifyListeners(@NonNull List<CancellationTokenRegistration> registrations) {
for (CancellationTokenRegistration registration : registrations) {
registration.runAction();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,27 @@

package com.facebook.react.bridgeless.internal.bolts;

import androidx.annotation.Nullable;

/**
* Provides a class that can be used for capturing variables in an anonymous class implementation.
*
* @param <T>
*/
public class Capture<T> {
private T value;
private @Nullable T value;

public Capture() {}

public Capture(T value) {
public Capture(@Nullable T value) {
this.value = value;
}

public T get() {
public @Nullable T get() {
return value;
}

public void set(T value) {
public void set(@Nullable T value) {
this.value = value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

package com.facebook.react.bridgeless.internal.bolts;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* A function to be called after a task completes.
*
Expand All @@ -16,5 +19,6 @@
* @see Task
*/
public interface Continuation<TTaskResult, TContinuationResult> {
TContinuationResult then(Task<TTaskResult> task) throws Exception;
@Nullable
TContinuationResult then(@NonNull Task<TTaskResult> task) throws Exception;
}
Loading

0 comments on commit dfb42a3

Please sign in to comment.