mirror of
https://github.com/jlengrand/error-prone-support.git
synced 2026-03-10 15:49:33 +00:00
Compare commits
1 Commits
sschroever
...
sschroever
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbef169556 |
@@ -1,272 +0,0 @@
|
||||
package tech.picnic.errorprone.refastertemplates;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
|
||||
import com.google.errorprone.refaster.annotation.AfterTemplate;
|
||||
import com.google.errorprone.refaster.annotation.BeforeTemplate;
|
||||
import io.reactivex.Completable;
|
||||
import io.reactivex.Flowable;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Supplier;
|
||||
import org.assertj.core.util.Streams;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.adapter.rxjava.RxJava2Adapter;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/** Refaster templates which replace RxJava expressions with equivalent Reactor assertions. */
|
||||
// XXX: Document the approach and any limitations; see the `TestNGToAssertJTemplates` documentation.
|
||||
// XXX: Document that the templates use `Completable` rather than `CompletableSource`, etc.
|
||||
// XXX: Have separate files for Completable, Maybe, Single, Flowable?
|
||||
final class RxJavaToReactorTemplates {
|
||||
private RxJavaToReactorTemplates() {}
|
||||
|
||||
// XXX: Handle array and varargs cases.
|
||||
// XXX: Simplify rule with `Completable.amb(Arrays.asList(sources))`?
|
||||
static final class CompletableAmbArray {
|
||||
@BeforeTemplate
|
||||
Completable before(Completable... sources) {
|
||||
return Completable.ambArray(sources);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after(Completable... sources) {
|
||||
return Mono.firstWithSignal(
|
||||
Arrays.stream(sources)
|
||||
.map(RxJava2Adapter::completableToMono)
|
||||
.collect(toImmutableList()))
|
||||
.as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
static final class CompletableAmb {
|
||||
@BeforeTemplate
|
||||
Completable before(Iterable<? extends Completable> sources) {
|
||||
return Completable.amb(sources);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after(Iterable<? extends Completable> sources) {
|
||||
return Mono.firstWithSignal(
|
||||
Streams.stream(sources)
|
||||
.map(RxJava2Adapter::completableToMono)
|
||||
.collect(toImmutableList()))
|
||||
.as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
static final class CompletableComplete {
|
||||
@BeforeTemplate
|
||||
Completable before() {
|
||||
return Completable.complete();
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after() {
|
||||
return Mono.empty().as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Handle array and varargs cases.
|
||||
// XXX: Simplify rule with `Completable.amb(Arrays.asList(sources))`?
|
||||
static final class CompletableConcatArray {
|
||||
@BeforeTemplate
|
||||
Completable before(Completable... sources) {
|
||||
return Completable.concatArray(sources);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after(Completable... sources) {
|
||||
return Flux.concat(
|
||||
Arrays.stream(sources)
|
||||
.map(RxJava2Adapter::completableToMono)
|
||||
.collect(toImmutableList()))
|
||||
.then()
|
||||
.as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Simplify rule with `Completable.concat(Flux.fromIterable(sources))`?
|
||||
static final class CompletableConcatIterable {
|
||||
@BeforeTemplate
|
||||
Completable before(Iterable<? extends Completable> sources) {
|
||||
return Completable.concat(sources);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after(Iterable<? extends Completable> sources) {
|
||||
return Flux.concat(Flux.fromIterable(sources).map(RxJava2Adapter::completableToMono))
|
||||
.then()
|
||||
.as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Simplify rule with `Completable.concat(sources, 2)`?
|
||||
// XXX: Arguably we should, since the Reactor prefetch is `Queues.XS_BUFFER_SIZE`.
|
||||
static final class CompletableConcatPublisher {
|
||||
@BeforeTemplate
|
||||
Completable before(Publisher<? extends Completable> sources) {
|
||||
return Completable.concat(sources);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after(Publisher<? extends Completable> sources) {
|
||||
return Flux.concat(Flux.from(sources).map(RxJava2Adapter::completableToMono))
|
||||
.then()
|
||||
.as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
static final class CompletableConcatPublisherPrefetch {
|
||||
@BeforeTemplate
|
||||
Completable before(Publisher<? extends Completable> sources, int prefetch) {
|
||||
return Completable.concat(sources, prefetch);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after(Publisher<? extends Completable> sources, int prefetch) {
|
||||
return Flux.concat(Flux.from(sources).map(RxJava2Adapter::completableToMono), prefetch)
|
||||
.then()
|
||||
.as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Migrate `Completable#create(CompletableOnSubscribe)`
|
||||
|
||||
// XXX: Migrate `Completable#unsafeCreate(CompletableSource)`
|
||||
|
||||
static final class CompletableDefer {
|
||||
@BeforeTemplate
|
||||
Completable before(Callable<? extends Completable> completableSupplier) {
|
||||
return Completable.defer(completableSupplier);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after(Callable<? extends Completable> completableSupplier) {
|
||||
return Mono.defer(
|
||||
() ->
|
||||
RxJava2ReactorMigrationUtil.getUnchecked(completableSupplier)
|
||||
.as(RxJava2Adapter::completableToMono))
|
||||
.as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
static final class CompletableErrorDeferred {
|
||||
@BeforeTemplate
|
||||
Completable before(Callable<? extends Throwable> errorSupplier) {
|
||||
return Completable.error(errorSupplier);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after(Callable<? extends Throwable> errorSupplier) {
|
||||
return Mono.error(RxJava2ReactorMigrationUtil.callableAsSupplier(errorSupplier))
|
||||
.as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
static final class CompletableError {
|
||||
@BeforeTemplate
|
||||
Completable before(Throwable error) {
|
||||
return Completable.error(error);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after(Throwable error) {
|
||||
return Mono.error(error).as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Migrate `Completable#fromAction(Action)`
|
||||
|
||||
static final class CompletableFromCallable<T> {
|
||||
@BeforeTemplate
|
||||
Completable before(Callable<T> callable) {
|
||||
return Completable.fromCallable(callable);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after(Callable<T> callable) {
|
||||
return Mono.fromSupplier(RxJava2ReactorMigrationUtil.callableAsSupplier(callable))
|
||||
.as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Also handle `Future`s that don't extend `CompletableFuture`.
|
||||
static final class CompletableFromFuture<T> {
|
||||
@BeforeTemplate
|
||||
Completable before(CompletableFuture<T> future) {
|
||||
return Completable.fromFuture(future);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Completable after(CompletableFuture<T> future) {
|
||||
return Mono.fromFuture(future).as(RxJava2Adapter::monoToCompletable);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Next up: migrate `Completable#fromMaybe(Maybe)`
|
||||
|
||||
// XXX: Move to a separate Maven module.
|
||||
static final class RxJava2ReactorMigrationUtil {
|
||||
private RxJava2ReactorMigrationUtil() {}
|
||||
|
||||
// XXX: Rename.
|
||||
// XXX: Introduce Refaster rules to drop this wrapper when possible.
|
||||
static <T> T getUnchecked(Callable<T> callable) {
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Callable threw checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: Rename.
|
||||
// XXX: Introduce Refaster rules to drop this wrapper when possible.
|
||||
static <T> Supplier<T> callableAsSupplier(Callable<T> callable) {
|
||||
return () -> {
|
||||
try {
|
||||
return callable.call();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Callable threw checked exception", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static <T, U, R> BiFunction<? super T, ? super U, ? extends R> toJdkBiFunction(
|
||||
io.reactivex.functions.BiFunction<? super T, ? super U, ? extends R> biFunction) {
|
||||
return (t, u) -> {
|
||||
try {
|
||||
return biFunction.apply(t, u);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("BiFunction threw checked exception", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////// FLOWABLE - MOVE!
|
||||
|
||||
static final class FlowableCombineLatest<T1, T2, R> {
|
||||
@BeforeTemplate
|
||||
Flowable<R> before(
|
||||
Publisher<? extends T1> publisher1,
|
||||
Publisher<? extends T2> publisher2,
|
||||
io.reactivex.functions.BiFunction<? super T1, ? super T2, ? extends R> combiner) {
|
||||
return Flowable.combineLatest(publisher1, publisher2, combiner);
|
||||
}
|
||||
|
||||
@AfterTemplate
|
||||
Flowable<R> after(
|
||||
Publisher<? extends T1> publisher1,
|
||||
Publisher<? extends T2> publisher2,
|
||||
io.reactivex.functions.BiFunction<? super T1, ? super T2, ? extends R> combiner) {
|
||||
// XXX: Generic type parameters are specified to appease IDEA; review.
|
||||
return RxJava2Adapter.fluxToFlowable(
|
||||
Flux.<T1, T2, R>combineLatest(
|
||||
publisher1, publisher2, RxJava2ReactorMigrationUtil.toJdkBiFunction(combiner)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -792,4 +792,39 @@ final class PrimitiveComparisonTest {
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
|
||||
// XXX: This still fails: all replacements start at the same place...
|
||||
@Test
|
||||
void testReplacementOfMultipleSubexpressions() {
|
||||
refactoringTestHelper
|
||||
.addInputLines(
|
||||
"in/A.java",
|
||||
"import java.util.Comparator;",
|
||||
"",
|
||||
"interface A extends Comparable<A> {",
|
||||
" Comparator<A> cmp = Comparator.<A, A>comparing(o -> o)",
|
||||
" .thenComparingInt(o -> Byte.valueOf((byte) 0))",
|
||||
" .thenComparingInt(o -> Character.valueOf((char) 0))",
|
||||
" .thenComparingInt(o -> Short.valueOf((short) 0))",
|
||||
" .thenComparingInt(o -> Integer.valueOf(0))",
|
||||
" .thenComparingLong(o -> Long.valueOf(0))",
|
||||
" .thenComparingDouble(o -> Float.valueOf(0))",
|
||||
" .thenComparingDouble(o -> Double.valueOf(0));",
|
||||
"}")
|
||||
.addOutputLines(
|
||||
"out/A.java",
|
||||
"import java.util.Comparator;",
|
||||
"",
|
||||
"interface A extends Comparable<A> {",
|
||||
" Comparator<A> cmp = Comparator.<A, A>comparing(o -> o) ",
|
||||
" .thenComparing(o -> Byte.valueOf((byte) 0))",
|
||||
" .thenComparing(o -> Character.valueOf((char) 0))",
|
||||
" .thenComparing(o -> Short.valueOf((short) 0))",
|
||||
" .thenComparing(o -> Integer.valueOf(0))",
|
||||
" .thenComparing(o -> Long.valueOf(0))",
|
||||
" .thenComparing(o -> Float.valueOf(0))",
|
||||
" .thenComparing(o -> Double.valueOf(0));",
|
||||
"}")
|
||||
.doTest(TestMode.TEXT_MATCH);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user