From ee5e33eb9910edf8d86d7e510b38c461741444f6 Mon Sep 17 00:00:00 2001 From: Benedek Halasi Date: Fri, 20 Jan 2023 13:32:39 +0100 Subject: [PATCH] Introduce `Flux.to{Stream,Iterable}` Refaster rules fixes #468 --- .../refasterrules/ReactorRules.java | 33 +++++++++++++++++++ .../refasterrules/ReactorRulesTestInput.java | 12 ++++++- .../refasterrules/ReactorRulesTestOutput.java | 12 ++++++- 3 files changed, 55 insertions(+), 2 deletions(-) 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 c99c77482a..ed3700d421 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 @@ -4,6 +4,7 @@ import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS; import static java.util.function.Function.identity; +import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; import static reactor.function.TupleUtils.function; @@ -27,6 +28,7 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.stream.Stream; import org.jspecify.annotations.Nullable; import org.reactivestreams.Publisher; import reactor.core.publisher.Flux; @@ -1303,4 +1305,35 @@ Duration after(StepVerifier.LastStep step, Duration duration) { return step.verifyTimeout(duration); } } + + /** Avoid accidental blocking with {@link Flux#toStream()} */ + // XXX: The alternative may lose some performance due to + // buffering and prefetching + static final class FluxToStream { + + @BeforeTemplate + Stream before(Flux flux) { + return flux.toStream(); + } + + @AfterTemplate + Stream after(Flux flux) { + return flux.collect(toList()).block().stream(); + } + } + + /** Avoid accidental blocking with {@link Flux#toIterable()} */ + // XXX: The alternative may lose some performance due to buffering and prefetching + static final class FluxToIterable { + + @BeforeTemplate + Iterable before(Flux flux) { + return flux.toIterable(); + } + + @AfterTemplate + Iterable after(Flux flux) { + return flux.collect(toList()).block(); + } + } } 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 25596c5cc3..16c3f9f198 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 @@ -12,6 +12,8 @@ import java.util.Optional; import java.util.concurrent.Callable; import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -23,7 +25,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase { @Override public ImmutableSet elidedTypesAndStaticImports() { - return ImmutableSet.of(assertThat(0), HashMap.class, ImmutableMap.class); + return ImmutableSet.of(assertThat(0), Collectors.class, HashMap.class, ImmutableMap.class); } ImmutableSet> testMonoFromSupplier() { @@ -402,4 +404,12 @@ Duration testStepVerifierLastStepVerifyErrorMessage() { Duration testStepVerifierLastStepVerifyTimeout() { return StepVerifier.create(Mono.empty()).expectTimeout(Duration.ZERO).verify(); } + + Stream testFluxToStream() { + return Flux.just(1, 2, 3).toStream(); + } + + Iterable testFluxToIterable() { + return Flux.just(1, 2, 3).toIterable(); + } } 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 7c471e5314..679a27e1d7 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 @@ -14,6 +14,8 @@ import java.util.Optional; import java.util.concurrent.Callable; import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.function.TupleUtils; @@ -26,7 +28,7 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase { @Override public ImmutableSet elidedTypesAndStaticImports() { - return ImmutableSet.of(assertThat(0), HashMap.class, ImmutableMap.class); + return ImmutableSet.of(assertThat(0), Collectors.class, HashMap.class, ImmutableMap.class); } ImmutableSet> testMonoFromSupplier() { @@ -391,4 +393,12 @@ Duration testStepVerifierLastStepVerifyErrorMessage() { Duration testStepVerifierLastStepVerifyTimeout() { return StepVerifier.create(Mono.empty()).verifyTimeout(Duration.ZERO); } + + Stream testFluxToStream() { + return Flux.just(1, 2, 3).collect(Collectors.toList()).block().stream(); + } + + Iterable testFluxToIterable() { + return Flux.just(1, 2, 3).collect(Collectors.toList()).block(); + } }