Skip to content

Commit

Permalink
Switch FluentFuture and AbstractFuture in inheritance chain
Browse files Browse the repository at this point in the history
RELNOTES=AbstractFuture doesn't expose FluentFuture APIs anymore.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=208673292
  • Loading branch information
sergeyv authored and ronshapiro committed Aug 16, 2018
1 parent 59f3b8a commit 0f8d360
Show file tree
Hide file tree
Showing 20 changed files with 158 additions and 42 deletions.
Expand Up @@ -40,7 +40,7 @@
@GwtCompatible(emulated = true)
public class FluentFutureTest extends TestCase {
public void testFromFluentFuture() {
FluentFuture<String> f = SettableFuture.create();
FluentFuture<String> f = FluentFuture.from(SettableFuture.<String>create());
assertThat(FluentFuture.from(f)).isSameAs(f);
}

Expand Down Expand Up @@ -131,7 +131,8 @@ public ListenableFuture<Integer> apply(Integer input) {
public void testWithTimeout() throws Exception {
ScheduledExecutorService executor = newScheduledThreadPool(1);
try {
FluentFuture<?> f = SettableFuture.create().withTimeout(0, SECONDS, executor);
FluentFuture<?> f =
FluentFuture.from(SettableFuture.create()).withTimeout(0, SECONDS, executor);
try {
f.get();
fail();
Expand Down
Expand Up @@ -29,7 +29,7 @@
/** Implementations of {@code Futures.catching*}. */
@GwtCompatible
abstract class AbstractCatchingFuture<V, X extends Throwable, F, T>
extends AbstractFuture.TrustedFuture<V> implements Runnable {
extends FluentFuture.TrustedFuture<V> implements Runnable {
static <V, X extends Throwable> ListenableFuture<V> create(
ListenableFuture<? extends V> input,
Class<X> exceptionType,
Expand Down
Expand Up @@ -63,18 +63,18 @@
@SuppressWarnings("ShortCircuitBoolean") // we use non-short circuiting comparisons intentionally
@GwtCompatible(emulated = true)
@ReflectionSupport(value = ReflectionSupport.Level.FULL)
public abstract class AbstractFuture<V> extends FluentFuture<V> {
public abstract class AbstractFuture<V> implements ListenableFuture<V> {
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||

private static final boolean GENERATE_CANCELLATION_CAUSES =
Boolean.parseBoolean(
System.getProperty("guava.concurrent.generate_cancellation_cause", "false"));

/**
* Tag interface marking trusted subclasses. This enables some optimizations.
* The implementation of this interface must also be an AbstractureFuture and
* must not override or expose for overriding all the public methods of ListenableFuture.
* */
* Tag interface marking trusted subclasses. This enables some optimizations. The implementation
* 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> {}

/**
Expand Down Expand Up @@ -965,7 +965,7 @@ private Listener clearListeners(Listener onto) {
return reversedList;
}

// TODO(user) move this up into FluentFuture, or parts as a default method on ListenableFuture?
// TODO(user): move parts into a default method on ListenableFuture?
@Override
public String toString() {
StringBuilder builder = new StringBuilder().append(super.toString()).append("[status=");
Expand Down
Expand Up @@ -28,7 +28,7 @@

/** Implementations of {@code Futures.transform*}. */
@GwtCompatible
abstract class AbstractTransformFuture<I, O, F, T> extends AbstractFuture.TrustedFuture<O>
abstract class AbstractTransformFuture<I, O, F, T> extends FluentFuture.TrustedFuture<O>
implements Runnable {
static <I, O> ListenableFuture<O> create(
ListenableFuture<I> input,
Expand Down
Expand Up @@ -18,6 +18,7 @@
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Function;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
Expand Down Expand Up @@ -68,6 +69,48 @@
@Beta
@GwtCompatible(emulated = true)
public abstract class FluentFuture<V> extends GwtFluentFutureCatchingSpecialization<V> {

/**
* A less abstract subclass of AbstractFuture. This can be used to optimize setFuture by ensuring
* that {@link #get} calls exactly the implementation of {@link AbstractFuture#get}.
*/
abstract static class TrustedFuture<V> extends FluentFuture<V>
implements AbstractFuture.Trusted<V> {
@CanIgnoreReturnValue
@Override
public final V get() throws InterruptedException, ExecutionException {
return super.get();
}

@CanIgnoreReturnValue
@Override
public final V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return super.get(timeout, unit);
}

@Override
public final boolean isDone() {
return super.isDone();
}

@Override
public final boolean isCancelled() {
return super.isCancelled();
}

@Override
public final void addListener(Runnable listener, Executor executor) {
super.addListener(listener, executor);
}

@CanIgnoreReturnValue
@Override
public final boolean cancel(boolean mayInterruptIfRunning) {
return super.cancel(mayInterruptIfRunning);
}
}

FluentFuture() {}

/**
Expand Down
Expand Up @@ -22,7 +22,7 @@
* FluentFuture.catching} family of methods. Those versions have slightly different signatures.
*/
@GwtCompatible(emulated = true)
abstract class GwtFluentFutureCatchingSpecialization<V> implements ListenableFuture<V> {
abstract class GwtFluentFutureCatchingSpecialization<V> extends AbstractFuture<V> {
/*
* This server copy of the class is empty. The corresponding GWT copy contains alternative
* versions of catching() and catchingAsync() with slightly different signatures from the ones
Expand Down
Expand Up @@ -28,7 +28,7 @@

/** Implementations of {@code Futures.immediate*}. */
@GwtCompatible(emulated = true)
abstract class ImmediateFuture<V> extends FluentFuture<V> {
abstract class ImmediateFuture<V> implements ListenableFuture<V> {
private static final Logger log = Logger.getLogger(ImmediateFuture.class.getName());

@Override
Expand Down
Expand Up @@ -34,7 +34,7 @@
* interrupted and cancelled if it times out.
*/
@GwtIncompatible
final class TimeoutFuture<V> extends AbstractFuture.TrustedFuture<V> {
final class TimeoutFuture<V> extends FluentFuture.TrustedFuture<V> {
static <V> ListenableFuture<V> create(
ListenableFuture<V> delegate,
long time,
Expand Down
Expand Up @@ -30,7 +30,7 @@
* performance reasons.
*/
@GwtCompatible
class TrustedListenableFutureTask<V> extends AbstractFuture.TrustedFuture<V>
class TrustedListenableFutureTask<V> extends FluentFuture.TrustedFuture<V>
implements RunnableFuture<V> {

static <V> TrustedListenableFutureTask<V> create(AsyncCallable<V> callable) {
Expand Down
Expand Up @@ -35,13 +35,42 @@
import org.checkerframework.checker.nullness.qual.Nullable;

/** Emulation for AbstractFuture in GWT. */
public abstract class AbstractFuture<V> extends FluentFuture<V> {
public abstract class AbstractFuture<V> implements ListenableFuture<V> {

/**
* Tag interface marking trusted subclasses. This enables some optimizations. The implementation
* 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> {}

abstract static class TrustedFuture<V> extends AbstractFuture<V> implements Trusted<V> {
@Override
public final V get() throws InterruptedException, ExecutionException {
return super.get();
}

@Override
public final V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return super.get(timeout, unit);
}

@Override
public final boolean isDone() {
return super.isDone();
}

@Override
public final boolean isCancelled() {
return super.isCancelled();
}

@Override
public final void addListener(Runnable listener, Executor executor) {
super.addListener(listener, executor);
}

abstract static class TrustedFuture<V> extends AbstractFuture<V> {
/*
* We don't need to override most of methods that we override in the prod version (and in fact
* we can't) because they are already final in AbstractFuture itself under GWT.
*/
@Override
public final boolean cancel(boolean mayInterruptIfRunning) {
return super.cancel(mayInterruptIfRunning);
Expand Down Expand Up @@ -83,34 +112,33 @@ public boolean cancel(boolean mayInterruptIfRunning) {
protected void interruptTask() {}

@Override
public final boolean isCancelled() {
public boolean isCancelled() {
return state.isCancelled();
}

@Override
public final boolean isDone() {
public boolean isDone() {
return state.isDone();
}

/*
* We let people override {@code get()} in the server version (though perhaps we shouldn't). Here,
* we don't want that, and anyway, users can't, thanks to the package-private parameter.
* ForwardingFluentFuture needs to override those methods, so they are not final.
*/
@Override
public final V get() throws InterruptedException, ExecutionException {
public V get() throws InterruptedException, ExecutionException {
state.maybeThrowOnGet(throwable);
return value;
}

@Override
public final V get(long timeout, TimeUnit unit)
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
checkNotNull(unit);
return get();
}

@Override
public final void addListener(Runnable runnable, Executor executor) {
public void addListener(Runnable runnable, Executor executor) {
Listener listener = new Listener(runnable, executor);
if (isDone()) {
listener.execute();
Expand Down
Expand Up @@ -22,7 +22,7 @@
* 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> implements ListenableFuture<V> {
abstract class GwtFluentFutureCatchingSpecialization<V> 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
Expand Up @@ -40,7 +40,7 @@
@GwtCompatible(emulated = true)
public class FluentFutureTest extends TestCase {
public void testFromFluentFuture() {
FluentFuture<String> f = SettableFuture.create();
FluentFuture<String> f = FluentFuture.from(SettableFuture.<String>create());
assertThat(FluentFuture.from(f)).isSameAs(f);
}

Expand Down Expand Up @@ -131,7 +131,8 @@ public ListenableFuture<Integer> apply(Integer input) {
public void testWithTimeout() throws Exception {
ScheduledExecutorService executor = newScheduledThreadPool(1);
try {
FluentFuture<?> f = SettableFuture.create().withTimeout(0, SECONDS, executor);
FluentFuture<?> f =
FluentFuture.from(SettableFuture.create()).withTimeout(0, SECONDS, executor);
try {
f.get();
fail();
Expand Down
Expand Up @@ -29,7 +29,7 @@
/** Implementations of {@code Futures.catching*}. */
@GwtCompatible
abstract class AbstractCatchingFuture<V, X extends Throwable, F, T>
extends AbstractFuture.TrustedFuture<V> implements Runnable {
extends FluentFuture.TrustedFuture<V> implements Runnable {
static <V, X extends Throwable> ListenableFuture<V> create(
ListenableFuture<? extends V> input,
Class<X> exceptionType,
Expand Down
12 changes: 6 additions & 6 deletions guava/src/com/google/common/util/concurrent/AbstractFuture.java
Expand Up @@ -63,18 +63,18 @@
@SuppressWarnings("ShortCircuitBoolean") // we use non-short circuiting comparisons intentionally
@GwtCompatible(emulated = true)
@ReflectionSupport(value = ReflectionSupport.Level.FULL)
public abstract class AbstractFuture<V> extends FluentFuture<V> {
public abstract class AbstractFuture<V> implements ListenableFuture<V> {
// NOTE: Whenever both tests are cheap and functional, it's faster to use &, | instead of &&, ||

private static final boolean GENERATE_CANCELLATION_CAUSES =
Boolean.parseBoolean(
System.getProperty("guava.concurrent.generate_cancellation_cause", "false"));

/**
* Tag interface marking trusted subclasses. This enables some optimizations.
* The implementation of this interface must also be an AbstractureFuture and
* must not override or expose for overriding all the public methods of ListenableFuture.
* */
* Tag interface marking trusted subclasses. This enables some optimizations. The implementation
* 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> {}

/**
Expand Down Expand Up @@ -965,7 +965,7 @@ private Listener clearListeners(Listener onto) {
return reversedList;
}

// TODO(user) move this up into FluentFuture, or parts as a default method on ListenableFuture?
// TODO(user): move parts into a default method on ListenableFuture?
@Override
public String toString() {
StringBuilder builder = new StringBuilder().append(super.toString()).append("[status=");
Expand Down
Expand Up @@ -28,7 +28,7 @@

/** Implementations of {@code Futures.transform*}. */
@GwtCompatible
abstract class AbstractTransformFuture<I, O, F, T> extends AbstractFuture.TrustedFuture<O>
abstract class AbstractTransformFuture<I, O, F, T> extends FluentFuture.TrustedFuture<O>
implements Runnable {
static <I, O> ListenableFuture<O> create(
ListenableFuture<I> input,
Expand Down
43 changes: 43 additions & 0 deletions guava/src/com/google/common/util/concurrent/FluentFuture.java
Expand Up @@ -18,6 +18,7 @@
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Function;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
Expand Down Expand Up @@ -68,6 +69,48 @@
@Beta
@GwtCompatible(emulated = true)
public abstract class FluentFuture<V> extends GwtFluentFutureCatchingSpecialization<V> {

/**
* A less abstract subclass of AbstractFuture. This can be used to optimize setFuture by ensuring
* that {@link #get} calls exactly the implementation of {@link AbstractFuture#get}.
*/
abstract static class TrustedFuture<V> extends FluentFuture<V>
implements AbstractFuture.Trusted<V> {
@CanIgnoreReturnValue
@Override
public final V get() throws InterruptedException, ExecutionException {
return super.get();
}

@CanIgnoreReturnValue
@Override
public final V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return super.get(timeout, unit);
}

@Override
public final boolean isDone() {
return super.isDone();
}

@Override
public final boolean isCancelled() {
return super.isCancelled();
}

@Override
public final void addListener(Runnable listener, Executor executor) {
super.addListener(listener, executor);
}

@CanIgnoreReturnValue
@Override
public final boolean cancel(boolean mayInterruptIfRunning) {
return super.cancel(mayInterruptIfRunning);
}
}

FluentFuture() {}

/**
Expand Down
Expand Up @@ -22,7 +22,7 @@
* FluentFuture.catching} family of methods. Those versions have slightly different signatures.
*/
@GwtCompatible(emulated = true)
abstract class GwtFluentFutureCatchingSpecialization<V> implements ListenableFuture<V> {
abstract class GwtFluentFutureCatchingSpecialization<V> extends AbstractFuture<V> {
/*
* This server copy of the class is empty. The corresponding GWT copy contains alternative
* versions of catching() and catchingAsync() with slightly different signatures from the ones
Expand Down

0 comments on commit 0f8d360

Please sign in to comment.