Skip to content

Commit

Permalink
Extend StreamRules Refaster rule collection
Browse files Browse the repository at this point in the history
All changes suggested by SonarCloud's `java:s4034` rule, as well as the
examples mentioned in openrewrite/rewrite#2984 are now covered. (In a
number of cases through composition of more generic rules.)

See https://rules.sonarsource.com/java/RSPEC-4034
  • Loading branch information
Stephan202 committed Apr 29, 2023
1 parent f675cf0 commit 6df4877
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.google.errorprone.refaster.annotation.Placeholder;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.IntSummaryStatistics;
Expand Down Expand Up @@ -247,12 +248,13 @@ Optional<S> after(Stream<T> stream, Function<? super T, S> function) {
/** In order to test whether a stream has any element, simply try to find one. */
static final class StreamIsEmpty<T> {
@BeforeTemplate
boolean before(Stream<T> stream) {
boolean before(Stream<T> stream, Collector<? super T, ?, ? extends Collection<?>> collector) {
return Refaster.anyOf(
stream.count() == 0,
stream.count() <= 0,
stream.count() < 1,
stream.findFirst().isEmpty());
stream.findFirst().isEmpty(),
stream.collect(collector).isEmpty());
}

@AfterTemplate
Expand Down Expand Up @@ -337,6 +339,7 @@ Optional<T> after(Stream<T> stream) {
}

/** Prefer {@link Stream#noneMatch(Predicate)} over more contrived alternatives. */
@SuppressWarnings({"FunctionalInterfaceClash", "overloads"})
static final class StreamNoneMatch<T> {
@BeforeTemplate
@SuppressWarnings("java:S4034" /* This violation will be rewritten. */)
Expand All @@ -347,6 +350,11 @@ boolean before(Stream<T> stream, Predicate<? super T> predicate) {
stream.filter(predicate).findAny().isEmpty());
}

@BeforeTemplate
boolean before(Stream<T> stream, Function<? super T, Boolean> predicate) {
return stream.map(predicate).noneMatch(Refaster.anyOf(Boolean::booleanValue, b -> b));
}

@AfterTemplate
boolean after(Stream<T> stream, Predicate<? super T> predicate) {
return stream.noneMatch(predicate);
Expand All @@ -369,6 +377,7 @@ boolean after(Stream<T> stream) {
}

/** Prefer {@link Stream#anyMatch(Predicate)} over more contrived alternatives. */
@SuppressWarnings({"FunctionalInterfaceClash", "overloads"})
static final class StreamAnyMatch<T> {
@BeforeTemplate
@SuppressWarnings("java:S4034" /* This violation will be rewritten. */)
Expand All @@ -377,18 +386,29 @@ boolean before(Stream<T> stream, Predicate<? super T> predicate) {
!stream.noneMatch(predicate), stream.filter(predicate).findAny().isPresent());
}

@BeforeTemplate
boolean before(Stream<T> stream, Function<? super T, Boolean> predicate) {
return stream.map(predicate).anyMatch(Refaster.anyOf(Boolean::booleanValue, b -> b));
}

@AfterTemplate
boolean after(Stream<T> stream, Predicate<? super T> predicate) {
return stream.anyMatch(predicate);
}
}

@SuppressWarnings({"FunctionalInterfaceClash", "overloads"})
static final class StreamAllMatch<T> {
@BeforeTemplate
boolean before(Stream<T> stream, Predicate<? super T> predicate) {
return stream.noneMatch(Refaster.anyOf(not(predicate), predicate.negate()));
}

@BeforeTemplate
boolean before(Stream<T> stream, Function<? super T, Boolean> predicate) {
return stream.map(predicate).allMatch(Refaster.anyOf(Boolean::booleanValue, b -> b));
}

@AfterTemplate
boolean after(Stream<T> stream, Predicate<? super T> predicate) {
return stream.allMatch(predicate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ ImmutableSet<Boolean> testStreamIsEmpty() {
Stream.of(1).count() == 0,
Stream.of(2).count() <= 0,
Stream.of(3).count() < 1,
Stream.of(4).findFirst().isEmpty());
Stream.of(4).findFirst().isEmpty(),
Stream.of(5).collect(toImmutableSet()).isEmpty());
}

ImmutableSet<Boolean> testStreamIsNotEmpty() {
Expand Down Expand Up @@ -150,7 +151,9 @@ ImmutableSet<Boolean> testStreamNoneMatch() {
!Stream.of("foo").anyMatch(s -> s.length() > 1),
Stream.of("bar").allMatch(not(String::isBlank)),
Stream.of("baz").allMatch(pred.negate()),
Stream.of("qux").filter(String::isEmpty).findAny().isEmpty());
Stream.of("qux").filter(String::isEmpty).findAny().isEmpty(),
Stream.of("quux").map(String::isBlank).noneMatch(Boolean::booleanValue),
Stream.of("quuz").map(Boolean::valueOf).noneMatch(r -> r));
}

ImmutableSet<Boolean> testStreamNoneMatch2() {
Expand All @@ -161,14 +164,18 @@ ImmutableSet<Boolean> testStreamNoneMatch2() {
ImmutableSet<Boolean> testStreamAnyMatch() {
return ImmutableSet.of(
!Stream.of("foo").noneMatch(s -> s.length() > 1),
Stream.of("bar").filter(String::isEmpty).findAny().isPresent());
Stream.of("bar").filter(String::isEmpty).findAny().isPresent(),
Stream.of("baz").map(String::isBlank).anyMatch(Boolean::booleanValue),
Stream.of("qux").map(Boolean::valueOf).anyMatch(r -> r));
}

ImmutableSet<Boolean> testStreamAllMatch() {
Predicate<String> pred = String::isBlank;
return ImmutableSet.of(
Stream.of("foo").noneMatch(not(String::isBlank)),
Stream.of("bar").noneMatch(pred.negate()));
Stream.of("bar").noneMatch(pred.negate()),
Stream.of("baz").map(String::isBlank).allMatch(Boolean::booleanValue),
Stream.of("qux").map(Boolean::valueOf).allMatch(r -> r));
}

boolean testStreamAllMatch2() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ ImmutableSet<Boolean> testStreamIsEmpty() {
Stream.of(1).findAny().isEmpty(),
Stream.of(2).findAny().isEmpty(),
Stream.of(3).findAny().isEmpty(),
Stream.of(4).findAny().isEmpty());
Stream.of(4).findAny().isEmpty(),
Stream.of(5).findAny().isEmpty());
}

ImmutableSet<Boolean> testStreamIsNotEmpty() {
Expand Down Expand Up @@ -151,7 +152,9 @@ ImmutableSet<Boolean> testStreamNoneMatch() {
Stream.of("foo").noneMatch(s -> s.length() > 1),
Stream.of("bar").noneMatch(String::isBlank),
Stream.of("baz").noneMatch(pred),
Stream.of("qux").noneMatch(String::isEmpty));
Stream.of("qux").noneMatch(String::isEmpty),
Stream.of("quux").noneMatch(String::isBlank),
Stream.of("quuz").noneMatch(Boolean::valueOf));
}

ImmutableSet<Boolean> testStreamNoneMatch2() {
Expand All @@ -161,13 +164,19 @@ ImmutableSet<Boolean> testStreamNoneMatch2() {

ImmutableSet<Boolean> testStreamAnyMatch() {
return ImmutableSet.of(
Stream.of("foo").anyMatch(s -> s.length() > 1), Stream.of("bar").anyMatch(String::isEmpty));
Stream.of("foo").anyMatch(s -> s.length() > 1),
Stream.of("bar").anyMatch(String::isEmpty),
Stream.of("baz").anyMatch(String::isBlank),
Stream.of("qux").anyMatch(Boolean::valueOf));
}

ImmutableSet<Boolean> testStreamAllMatch() {
Predicate<String> pred = String::isBlank;
return ImmutableSet.of(
Stream.of("foo").allMatch(String::isBlank), Stream.of("bar").allMatch(pred));
Stream.of("foo").allMatch(String::isBlank),
Stream.of("bar").allMatch(pred),
Stream.of("baz").allMatch(String::isBlank),
Stream.of("qux").allMatch(Boolean::valueOf));
}

boolean testStreamAllMatch2() {
Expand Down

0 comments on commit 6df4877

Please sign in to comment.