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 fca783f9d8..f29c00296f 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 @@ -1205,10 +1205,17 @@ Flux after(Flux> flux, int prefetch) { } /** Prefer {@link Flux#fromIterable(Iterable)} over less efficient alternatives. */ + // XXX: Once the `FluxFromStreamSupplier` rule is constrained using + // `@NotMatches(IsIdentityOperation.class)`, this rule should also cover + // `Flux.fromStream(collection.stream())`. static final class FluxFromIterable { + // XXX: Once the `MethodReferenceUsage` check is generally enabled, drop the second + // `Refaster.anyOf` variant. @BeforeTemplate Flux before(Collection collection) { - return Flux.fromStream(collection.stream()); + return Flux.fromStream( + Refaster.>>anyOf( + collection::stream, () -> collection.stream())); } @AfterTemplate @@ -1933,7 +1940,7 @@ Mono after(CompletableFuture 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. + * asynchronous computation until subscription. */ static final class MonoFromFutureSupplierBoolean { // XXX: Constrain the `future` parameter using `@NotMatches(IsIdentityOperation.class)` once @@ -1951,9 +1958,12 @@ Mono after(CompletableFuture future, boolean suppressCancel) { /** * Prefer {@link Flux#fromStream(Supplier)} over {@link Flux#fromStream(Stream)}, as the former - * may defer initiation of the asynchronous computation until subscription. + * yields a {@link Flux} that is more likely to behave as expected when subscribed to more than + * once. */ static final class FluxFromStreamSupplier { + // XXX: Constrain the `stream` parameter using `@NotMatches(IsIdentityOperation.class)` once + // `IsIdentityOperation` no longer matches nullary method invocations. @BeforeTemplate Flux before(Stream stream) { return Flux.fromStream(stream); 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 54c0f00775..d3c7841621 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 @@ -435,8 +435,10 @@ ImmutableSet> testConcatMapIterableIdentityWithPrefetch() { Flux.just(ImmutableList.of("bar")).concatMap(Flux::fromIterable, 2)); } - Flux testFluxFromIterable() { - return Flux.fromStream(ImmutableList.of("foo").stream()); + ImmutableSet> testFluxFromIterable() { + return ImmutableSet.of( + Flux.fromStream(ImmutableList.of("foo")::stream), + Flux.fromStream(() -> ImmutableList.of("bar").stream())); } ImmutableSet> testFluxCountMapMathToIntExact() { 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 df9762b4f4..76d30b497f 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 @@ -25,7 +25,6 @@ import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; -import java.util.random.RandomGenerator; import java.util.stream.Stream; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -431,8 +430,9 @@ ImmutableSet> testConcatMapIterableIdentityWithPrefetch() { Flux.just(ImmutableList.of("bar")).concatMapIterable(identity(), 2)); } - Flux testFluxFromIterable() { - return Flux.fromIterable(ImmutableList.of("foo")); + ImmutableSet> testFluxFromIterable() { + return ImmutableSet.of( + Flux.fromIterable(ImmutableList.of("foo")), Flux.fromIterable(ImmutableList.of("bar"))); } ImmutableSet> testFluxCountMapMathToIntExact() { @@ -645,6 +645,6 @@ Mono testMonoFromFutureSupplierBoolean() { } Flux testFluxFromStreamSupplier() { - return Flux.fromStream(() -> RandomGenerator.StreamableGenerator.of(1)); + return Flux.fromStream(() -> Stream.of(1)); } }