Skip to content

Commit

Permalink
Improve nullability annotations for J2cl overlays in the concurrent p…
Browse files Browse the repository at this point in the history
…ackage -- make them consistent with the underlying classes.

This gives us slightly more motivation for #2934.

RELNOTES=`util.concurrent`: Improved nullability annotations for J2cl overlays.
PiperOrigin-RevId: 492223286
  • Loading branch information
java-team-github-bot authored and Google Java Core Libraries committed Dec 7, 2022
1 parent ea49a6b commit 464a323
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@

/** Emulation for AbstractFuture in GWT. */
@SuppressWarnings("nullness") // TODO(b/147136275): Remove once our checker understands & and |.
public abstract class AbstractFuture<V> extends InternalFutureFailureAccess
@ElementTypesAreNonnullByDefault
public abstract class AbstractFuture<V extends @Nullable Object> extends InternalFutureFailureAccess
implements ListenableFuture<V> {

static final boolean GENERATE_CANCELLATION_CAUSES = false;
Expand All @@ -48,9 +49,10 @@ public abstract class AbstractFuture<V> extends InternalFutureFailureAccess
* of this interface must also be an AbstractFuture and must not override or expose for overriding
* any of the public methods of ListenableFuture.
*/
interface Trusted<V> extends ListenableFuture<V> {}
interface Trusted<V extends @Nullable Object> extends ListenableFuture<V> {}

abstract static class TrustedFuture<V> extends AbstractFuture<V> implements Trusted<V> {
abstract static class TrustedFuture<V extends @Nullable Object> extends AbstractFuture<V>
implements Trusted<V> {
@CanIgnoreReturnValue
@Override
public final V get() throws InterruptedException, ExecutionException {
Expand Down Expand Up @@ -90,8 +92,8 @@ public final boolean cancel(boolean mayInterruptIfRunning) {

private State state;
private V value;
private Future<? extends V> delegate;
private Throwable throwable;
private @Nullable Future<? extends V> delegate;
private @Nullable Throwable throwable;
private boolean mayInterruptIfRunning;
private List<Listener> listeners;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
import static com.google.common.collect.Sets.newHashSet;

import java.util.Set;
import org.checkerframework.checker.nullness.qual.Nullable;

/** Emulation of AggregateFutureState. */
abstract class AggregateFutureState<OutputT> extends AbstractFuture.TrustedFuture<OutputT> {
@ElementTypesAreNonnullByDefault
abstract class AggregateFutureState<OutputT extends @Nullable Object>
extends AbstractFuture.TrustedFuture<OutputT> {
// Lazily initialized the first time we see an exception; not released until all the input futures
// & this future completes. Released when the future releases the reference to the running state
private Set<Throwable> seenExceptions = null;
private @Nullable Set<Throwable> seenExceptions = null;
private int remaining;

AggregateFutureState(int remainingFutures) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@

import com.google.common.base.Function;
import java.util.concurrent.Executor;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* Hidden superclass of {@link FluentFuture} that provides us a place to declare special GWT
* versions of the {@link FluentFuture#catching(Class, com.google.common.base.Function)
* FluentFuture.catching} family of methods. Those versions have slightly different signatures.
*/
abstract class GwtFluentFutureCatchingSpecialization<V> extends AbstractFuture<V> {
@ElementTypesAreNonnullByDefault
abstract class GwtFluentFutureCatchingSpecialization<V extends @Nullable Object>
extends AbstractFuture<V> {
/*
* In the GWT versions of the methods (below), every exceptionType parameter is required to be
* Class<Throwable>. To handle only certain kinds of exceptions under GWT, you'll need to write
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,30 @@

import com.google.common.base.Function;
import java.util.concurrent.Executor;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* Hidden superclass of {@link Futures} that provides us a place to declare special GWT versions of
* the {@link Futures#catching(ListenableFuture, Class, com.google.common.base.Function)
* Futures.catching} family of methods. Those versions have slightly different signatures.
*/
@ElementTypesAreNonnullByDefault
abstract class GwtFuturesCatchingSpecialization {
/*
* In the GWT versions of the methods (below), every exceptionType parameter is required to be
* Class<Throwable>. To handle only certain kinds of exceptions under GWT, you'll need to write
* your own instanceof tests.
*/

public static <V> ListenableFuture<V> catching(
public static <V extends @Nullable Object> ListenableFuture<V> catching(
ListenableFuture<? extends V> input,
Class<Throwable> exceptionType,
Function<? super Throwable, ? extends V> fallback,
Executor executor) {
return AbstractCatchingFuture.create(input, exceptionType, fallback, executor);
}

public static <V> ListenableFuture<V> catchingAsync(
public static <V extends @Nullable Object> ListenableFuture<V> catchingAsync(
ListenableFuture<? extends V> input,
Class<Throwable> exceptionType,
AsyncFunction<? super Throwable, ? extends V> fallback,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@

import static com.google.common.util.concurrent.NullnessCasts.uncheckedCastNullableTToT;

import org.checkerframework.checker.nullness.qual.Nullable;

/** Emulation for InterruptibleTask in GWT. */
abstract class InterruptibleTask<T> implements Runnable {
@ElementTypesAreNonnullByDefault
abstract class InterruptibleTask<T extends @Nullable Object> implements Runnable {

@Override
public void run() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@
import jsinterop.annotations.JsOptional;
import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsType;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* Java super source for ListenableFuture, implementing a structural thenable via a default method.
* For restrictions, please refer to the documentation of the then() method.
*/
public interface ListenableFuture<V> extends Future<V>, IThenable<V> {
@ElementTypesAreNonnullByDefault
public interface ListenableFuture<V extends @Nullable Object> extends Future<V>, IThenable<V> {
void addListener(Runnable listener, Executor executor);

/** Note that this method is not expected to be overridden. */
@JsMethod
@Override
default <R> IThenable<R> then(
default <R extends @Nullable Object> IThenable<R> then(
@JsOptional IThenOnFulfilledCallbackFn<? super V, ? extends R> onFulfilled,
@JsOptional IThenOnRejectedCallbackFn<? extends R> onRejected) {
return new Promise<V>(
Expand Down Expand Up @@ -61,30 +63,30 @@ public void onFailure(Throwable throwable) {
* us to implement it using a default implementation in J2cl ListenableFuture.
*/
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "IThenable")
interface IThenable<T> {
<V> IThenable<V> then(
interface IThenable<T extends @Nullable Object> {
<V extends @Nullable Object> IThenable<V> then(
@JsOptional IThenOnFulfilledCallbackFn<? super T, ? extends V> onFulfilled,
@JsOptional IThenOnRejectedCallbackFn<? extends V> onRejected);

@JsFunction
interface IThenOnFulfilledCallbackFn<T, V> {
interface IThenOnFulfilledCallbackFn<T extends @Nullable Object, V extends @Nullable Object> {
V onInvoke(T p0);
}

@JsFunction
interface IThenOnRejectedCallbackFn<V> {
interface IThenOnRejectedCallbackFn<V extends @Nullable Object> {
V onInvoke(Object p0);
}
}

/** Subset of the elemental2 Promise API. */
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Promise")
class Promise<T> implements IThenable<T> {
class Promise<T extends @Nullable Object> implements IThenable<T> {

@JsFunction
interface PromiseExecutorCallbackFn<T> {
interface PromiseExecutorCallbackFn<T extends @Nullable Object> {
@JsFunction
interface ResolveCallbackFn<T> {
interface ResolveCallbackFn<T extends @Nullable Object> {
void onInvoke(T value);
}

Expand All @@ -99,7 +101,7 @@ interface RejectCallbackFn {
public Promise(PromiseExecutorCallbackFn<T> executor) {}

@Override
public native <V> Promise<V> then(
public native <V extends @Nullable Object> Promise<V> then(
@JsOptional IThenOnFulfilledCallbackFn<? super T, ? extends V> onFulfilled,
@JsOptional IThenOnRejectedCallbackFn<? extends V> onRejected);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

package com.google.common.util.concurrent;


/** Methods factored out so that they can be emulated differently in GWT. */
@ElementTypesAreNonnullByDefault
final class Platform {
static boolean isInstanceOfThrowableClass(Throwable t, Class<? extends Throwable> expectedClass) {
/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.checkerframework.checker.nullness.qual.Nullable;

/** Emulation of Uninterruptibles in GWT. */
@ElementTypesAreNonnullByDefault
public final class Uninterruptibles {

private Uninterruptibles() {}

@CanIgnoreReturnValue
public static <V> V getUninterruptibly(Future<V> future) throws ExecutionException {
public static <V extends @Nullable Object> V getUninterruptibly(Future<V> future)
throws ExecutionException {
try {
return future.get();
} catch (InterruptedException e) {
Expand Down

0 comments on commit 464a323

Please sign in to comment.