From fbda14828a01153a0ff4728232bcd8b973aff4cc Mon Sep 17 00:00:00 2001 From: Rick Ossendrijver Date: Sun, 16 May 2021 10:26:23 +0200 Subject: [PATCH] Improve the templates --- .../RxJavaToReactorTemplates.java | 116 +++++++++++------- .../bugpatterns/RefasterCheckTest.java | 9 ++ .../RxJavaToReactorTemplatesTestInput.java | 32 ++++- .../RxJavaToReactorTemplatesTestOutput.java | 36 +++++- 4 files changed, 134 insertions(+), 59 deletions(-) diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refastertemplates/RxJavaToReactorTemplates.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refastertemplates/RxJavaToReactorTemplates.java index f397df2e..c49406aa 100644 --- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refastertemplates/RxJavaToReactorTemplates.java +++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refastertemplates/RxJavaToReactorTemplates.java @@ -2,13 +2,17 @@ package tech.picnic.errorprone.refastertemplates; import com.google.errorprone.refaster.annotation.AfterTemplate; import com.google.errorprone.refaster.annotation.BeforeTemplate; -import io.reactivex.Flowable; -import io.reactivex.Maybe; +import io.reactivex.*; import io.reactivex.functions.Function; import io.reactivex.functions.Predicate; import org.reactivestreams.Publisher; import reactor.adapter.rxjava.RxJava2Adapter; import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.function.Supplier; final class RxJavaToReactorTemplates { private RxJavaToReactorTemplates() {} @@ -47,6 +51,7 @@ final class RxJavaToReactorTemplates { } // XXX: I don't think calling `next()` here is the right way... + // Also look at the tests... static final class FlowableFirstElementInReactor { @BeforeTemplate Maybe before(Flowable flowable) { @@ -55,23 +60,39 @@ final class RxJavaToReactorTemplates { @AfterTemplate Maybe after(Flowable flowable) { - return flowable - .as(RxJava2Adapter::flowableToFlux) - .next() - .as(RxJava2Adapter::monoToMaybe); + return flowable.as(RxJava2Adapter::flowableToFlux).next().as(RxJava2Adapter::monoToMaybe); } } + static final class MaybeSwitchIfEmptyInReactor { + @BeforeTemplate + Single before(Maybe maybe, Callable throwable) { + return maybe.switchIfEmpty(Single.error(throwable)); + } - // default Single getWarehouse(WarehouseId warehouseId) { - // return getAllWarehouses() - // .filter(warehouse -> warehouse.getId().equals(warehouseId)) - // .firstElement() - // .switchIfEmpty( - // Single.error( - // itemNotFound(Warehouse.class.getName(), warehouseId.toString()) - // ::get)); - // } + @AfterTemplate + Single after(Maybe maybe, Supplier throwable) { + return maybe + .as(RxJava2Adapter::maybeToMono) + .switchIfEmpty(Mono.error(throwable)) + .as(RxJava2Adapter::monoToSingle); + } + } + + static final class FlowableSwitchIfEmptyInReactor { + @BeforeTemplate + Flowable before(Flowable flowable, Callable throwable) { + return flowable.switchIfEmpty(Flowable.error(throwable)); + } + + @AfterTemplate + Flowable after(Flowable flowable, Supplier throwable) { + return flowable + .as(RxJava2Adapter::flowableToFlux) + .switchIfEmpty(Flux.error(throwable)) + .as(RxJava2Adapter::fluxToFlowable); + } + } static final class RemoveUnnecessaryConversion { @BeforeTemplate @@ -84,40 +105,41 @@ final class RxJavaToReactorTemplates { return flux; } } -} - // static final class FlowableToMapInReactor { - // @BeforeTemplate - // Single> before(Flowable flowable, Function function) { - // return flowable.toMap(function); - // } - // - // @AfterTemplate - // Single> after(Flowable flowable, java.util.function.Function function) { - // return flowable.as(RxJava2Adapter::flowableToFlux) - // .collectMap(function) - // .as(RxJava2Adapter::monoToSingle); - // } - // } + +// static final class FlowableToMapInReactor { +// @BeforeTemplate +// Single> before(Flowable flowable, Function function) { +// return flowable.toMap(function); +// } +// +// @AfterTemplate +// Single> after(Flowable flowable, java.util.function.Function function) { +// return flowable.as(RxJava2Adapter::flowableToFlux) +// .collectMap(function) +// .as(RxJava2Adapter::monoToSingle); +// } +// } // Check this with Stephan. - // static final class FlowableMapToFluxMapToFlowable { - // @BeforeTemplate - // Flowable before(Flowable flowable, Function function) { - // return flowable.map(function); - // } - // - // @AfterTemplate - // Flowable after( - // Flowable flowable, java.util.function.Function function) { - // return flowable - // .as(RxJava2Adapter::flowableToFlux) - // .map(function) - // .as(RxJava2Adapter::fluxToFlowable); - // // Moeten we hier ook iets doen met Refaster.canBeCoercedTo() - // // omdat we moeten weten dat het geen Flux maar Flux is... - // } - // } +// static final class FlowableMapToFluxMapToFlowable { +// @BeforeTemplate +// Flowable before(Flowable flowable, Function function) { +// return flowable.map(function); +// } +// +// @AfterTemplate +// Flowable after( +// Flowable flowable, java.util.function.Function function) { +// return flowable +// .as(RxJava2Adapter::flowableToFlux) +// .map(function) +// .as(RxJava2Adapter::fluxToFlowable); // > +// // Moeten we hier ook iets doen met Refaster.canBeCoercedTo() +// // omdat we moeten weten dat het geen Flux maar Flux is... +// } +// } // Stephan: Bad return type in method reference: cannot convert io.reactivex.Flowable to // io.reactivex.Flowable integerSingle = Maybe.just(1) + .switchIfEmpty( + Single.error( + () -> { + throw new IllegalStateException(); + })); createRestrictedRefactoringTestHelper(templateNamePattern) .addInput(groupName + "TemplatesTestInput.java") .addOutput(groupName + "TemplatesTestOutput.java") diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/bugpatterns/RxJavaToReactorTemplatesTestInput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/bugpatterns/RxJavaToReactorTemplatesTestInput.java index 32d9a755..772d3751 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/bugpatterns/RxJavaToReactorTemplatesTestInput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/bugpatterns/RxJavaToReactorTemplatesTestInput.java @@ -2,9 +2,11 @@ package tech.picnic.errorprone.bugpatterns; import com.google.common.collect.ImmutableSet; import io.reactivex.Flowable; +import io.reactivex.Maybe; +import io.reactivex.Single; import reactor.adapter.rxjava.RxJava2Adapter; import reactor.core.publisher.Flux; -import io.reactivex.Maybe; +import reactor.core.publisher.Mono; final class RxJavaToReactorTemplatesTest implements RefasterTemplateTestCase { Flowable testFlowableFlatMapInReactor() { // look at the return type... @@ -15,11 +17,29 @@ final class RxJavaToReactorTemplatesTest implements RefasterTemplateTestCase { return Flowable.just(1).filter(i -> i > 2); } -// ImmutableSet> testFlowableFirstElementInReactor() { -// return ImmutableSet.of( -// Maybe.just(1).toFlowable().firstElement(), -// Maybe.empty().toFlowable().firstElement()); -// } + ImmutableSet> testFlowableFirstElementInReactor() { + return ImmutableSet.of( + Flowable.toMaybe(::evenFilter).firstElement(), + Maybe.empty().toFlowable().firstElement()); + } + + Single testMaybeSwitchIfEmptyInReactor() { + return Maybe.just(1) + .switchIfEmpty( + Single.error( + () -> { + throw new IllegalStateException(); + })); + } + + Flowable testFlowableSwitchIfEmptyInReactor() { + return Flowable.just(1) + .switchIfEmpty( + Flowable.error( + () -> { + throw new IllegalStateException(); + })); + } Flux testRemoveUnnecessaryConversion() { Flowable.just(1) diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/bugpatterns/RxJavaToReactorTemplatesTestOutput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/bugpatterns/RxJavaToReactorTemplatesTestOutput.java index 4b18916d..906295e4 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/bugpatterns/RxJavaToReactorTemplatesTestOutput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/bugpatterns/RxJavaToReactorTemplatesTestOutput.java @@ -2,9 +2,11 @@ package tech.picnic.errorprone.bugpatterns; import com.google.common.collect.ImmutableSet; import io.reactivex.Flowable; +import io.reactivex.Maybe; +import io.reactivex.Single; import reactor.adapter.rxjava.RxJava2Adapter; import reactor.core.publisher.Flux; -import io.reactivex.Maybe; +import reactor.core.publisher.Mono; final class RxJavaToReactorTemplatesTest implements RefasterTemplateTestCase { Flowable testFlowableFlatMapInReactor() { // look at the return type... @@ -21,11 +23,33 @@ final class RxJavaToReactorTemplatesTest implements RefasterTemplateTestCase { .as(RxJava2Adapter::fluxToFlowable); } -// ImmutableSet> testFlowableFirstElementInReactor() { -// return ImmutableSet.of( -// Flowable.just(1).as(RxJava2Adapter::flowableToFlux).next().as(RxJava2Adapter::monoToMaybe), -// Flowable.empty().as(RxJava2Adapter::flowableToFlux).next().as(RxJava2Adapter::monoToMaybe)); -// } + ImmutableSet> testFlowableFirstElementInReactor() { + return ImmutableSet.of( + Flowable.just(1).as(RxJava2Adapter::flowableToFlux).next().as(RxJava2Adapter::monoToMaybe), + Flowable.empty().as(RxJava2Adapter::flowableToFlux).next().as(RxJava2Adapter::monoToMaybe)); + } + + Single testMaybeSwitchIfEmptyInReactor() { + return Maybe.just(1) + .as(RxJava2Adapter::maybeToMono) + .switchIfEmpty( + Mono.error( + () -> { + throw new IllegalStateException(); + })) + .as(RxJava2Adapter::monoToSingle); + } + + Flowable testFlowableSwitchIfEmptyInReactor() { + return Flowable.just(1) + .as(RxJava2Adapter::flowableToFlux) + .switchIfEmpty( + Flux.error( + () -> { + throw new IllegalStateException(); + })) + .as(RxJava2Adapter::fluxToFlowable); + } Flux testRemoveUnnecessaryConversion() { Flowable.just(1)