diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java index f09a9ab52e..273e0eea17 100644 --- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java +++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/ReactorRules.java @@ -33,6 +33,7 @@ import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -1904,4 +1905,41 @@ Duration after(StepVerifier.LastStep step, Duration duration) { return step.verifyTimeout(duration); } } + + /** + * Prefer {@link Mono#fromFuture(Supplier)} over {@link Mono#fromFuture(CompletableFuture)}, as + * the former may defer initiation of the asynchornous computation until subscription. + */ + static final class MonoFromFutureSupplier { + // XXX: Constrain the `future` parameter using `@NotMatches(IsIdentityOperation.class)` once + // `IsIdentityOperation` no longer matches nullary method invocations. + @BeforeTemplate + Mono before(CompletableFuture future) { + return Mono.fromFuture(future); + } + + @AfterTemplate + Mono after(CompletableFuture future) { + return Mono.fromFuture(() -> future); + } + } + + /** + * Prefer {@link Mono#fromFuture(Supplier, boolean)} over {@link + * Mono#fromFuture(CompletableFuture, boolean)}, as the former may defer initiation of the + * asynchornous computation until subscription. + */ + static final class MonoFromFutureSupplierBoolean { + // XXX: Constrain the `future` parameter using `@NotMatches(IsIdentityOperation.class)` once + // `IsIdentityOperation` no longer matches nullary method invocations. + @BeforeTemplate + Mono before(CompletableFuture future, boolean suppressCancel) { + return Mono.fromFuture(future, suppressCancel); + } + + @AfterTemplate + Mono after(CompletableFuture future, boolean suppressCancel) { + return Mono.fromFuture(() -> future, suppressCancel); + } + } } diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java index 881428ef51..1efc888cc4 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestInput.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -651,4 +652,12 @@ Duration testStepVerifierLastStepVerifyErrorMessage() { Duration testStepVerifierLastStepVerifyTimeout() { return Mono.empty().as(StepVerifier::create).expectTimeout(Duration.ZERO).verify(); } + + Mono testMonoFromFutureSupplier() { + return Mono.fromFuture(CompletableFuture.completedFuture(null)); + } + + Mono testMonoFromFutureSupplierBoolean() { + return Mono.fromFuture(CompletableFuture.completedFuture(null), true); + } } diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java index a9dcd26c05..7e4c325bf1 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/ReactorRulesTestOutput.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -632,4 +633,12 @@ Duration testStepVerifierLastStepVerifyErrorMessage() { Duration testStepVerifierLastStepVerifyTimeout() { return Mono.empty().as(StepVerifier::create).verifyTimeout(Duration.ZERO); } + + Mono testMonoFromFutureSupplier() { + return Mono.fromFuture(() -> CompletableFuture.completedFuture(null)); + } + + Mono testMonoFromFutureSupplierBoolean() { + return Mono.fromFuture(() -> CompletableFuture.completedFuture(null), true); + } }