Introduce FluxCollectToImmutableList Refaster rule (#570)

And extend `MonoIdentity` to simplify `mono.map(ImmutableList::copyOf)`
expressions where possible, as the new rule may introduce such cases.
This commit is contained in:
Luke Prananta
2023-04-13 08:31:45 +02:00
committed by GitHub
parent 6d23fbdd35
commit 6514236514
4 changed files with 42 additions and 2 deletions

View File

@@ -35,6 +35,8 @@ import tech.picnic.errorprone.bugpatterns.util.SourceCode;
// XXX: Consider detecting cases where a flagged expression is passed to a method, and where removal
// of the identity conversion would cause a different method overload to be selected. Depending on
// the target method such a modification may change the code's semantics or performance.
// XXX: Also flag `Stream#map`, `Mono#map` and `Flux#map` invocations where the given transformation
// is effectively the identity operation.
@AutoService(BugChecker.class)
@BugPattern(
summary = "Avoid or clarify identity conversions",

View File

@@ -403,6 +403,13 @@ final class ReactorRules {
return mono.then();
}
// XXX: Replace this rule with an extension of the `IdentityConversion` rule, supporting
// `Stream#map`, `Mono#map` and `Flux#map`.
@BeforeTemplate
Mono<ImmutableList<T>> before3(Mono<ImmutableList<T>> mono) {
return mono.map(ImmutableList::copyOf);
}
@AfterTemplate
Mono<T> after(Mono<T> mono) {
return mono;
@@ -1169,6 +1176,23 @@ final class ReactorRules {
}
}
/**
* Prefer {@link Flux#collect(Collector)} with {@link ImmutableList#toImmutableList()} over
* alternatives that do not explicitly return an immutable collection.
*/
static final class FluxCollectToImmutableList<T> {
@BeforeTemplate
Mono<List<T>> before(Flux<T> flux) {
return flux.collectList();
}
@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
Mono<ImmutableList<T>> after(Flux<T> flux) {
return flux.collect(toImmutableList());
}
}
/**
* Prefer {@link Flux#collect(Collector)} with {@link ImmutableSet#toImmutableSet()} over more
* contrived alternatives.

View File

@@ -141,7 +141,8 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
Mono.just(1).switchIfEmpty(Mono.empty()),
Mono.just(2).flux().next(),
Mono.just(3).flux().singleOrEmpty(),
Mono.<Void>empty().then());
Mono.<Void>empty().then(),
Mono.<ImmutableList<String>>empty().map(ImmutableList::copyOf));
}
ImmutableSet<Flux<Integer>> testFluxSwitchIfEmptyOfEmptyPublisher() {
@@ -377,6 +378,10 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return Flux.just(1, 4, 3, 2).sort(reverseOrder()).filter(i -> i % 2 == 0);
}
Mono<List<Integer>> testFluxCollectToImmutableList() {
return Flux.just(1).collectList();
}
Mono<ImmutableSet<Integer>> testFluxCollectToImmutableSet() {
return Flux.just(1).collect(toImmutableList()).map(ImmutableSet::copyOf);
}

View File

@@ -142,7 +142,12 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
}
ImmutableSet<Mono<?>> testMonoIdentity() {
return ImmutableSet.of(Mono.just(1), Mono.just(2), Mono.just(3), Mono.<Void>empty());
return ImmutableSet.of(
Mono.just(1),
Mono.just(2),
Mono.just(3),
Mono.<Void>empty(),
Mono.<ImmutableList<String>>empty());
}
ImmutableSet<Flux<Integer>> testFluxSwitchIfEmptyOfEmptyPublisher() {
@@ -366,6 +371,10 @@ final class ReactorRulesTest implements RefasterRuleCollectionTestCase {
return Flux.just(1, 4, 3, 2).filter(i -> i % 2 == 0).sort(reverseOrder());
}
Mono<List<Integer>> testFluxCollectToImmutableList() {
return Flux.just(1).collect(toImmutableList());
}
Mono<ImmutableSet<Integer>> testFluxCollectToImmutableSet() {
return Flux.just(1).collect(toImmutableSet());
}