Skip to content

Commit

Permalink
Add refaster rules for prefering requireNonNullElse(A, B) and `requ…
Browse files Browse the repository at this point in the history
…ireNonNullElseGet(A, () -> B)` over Optional alternative.

Added Rules: (NullRules)
 - prefer `requireNonNullElse(A, B)` over `Optional.ofNullable(A).orElse(B)`
 - prefer `requireNonNullElseGet(A, () -> B)` over `Optional.ofNullable(A).orElseGet(() -> B)`

Related issue: PicnicSupermarket#364
  • Loading branch information
benhalasi authored and Stephan202 committed Dec 28, 2022
1 parent b220786 commit 161cc4d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS;
import static java.util.Objects.requireNonNullElse;
import static java.util.Objects.requireNonNullElseGet;

import com.google.common.base.MoreObjects;
import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import com.google.errorprone.refaster.annotation.Matches;
import com.google.errorprone.refaster.annotation.UseImportPolicy;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.jspecify.annotations.Nullable;
import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation;

Expand Down Expand Up @@ -43,22 +47,50 @@ boolean after(@Nullable Object object) {
}
}

/** Prefer {@link Objects#requireNonNullElse(Object, Object)} over the Guava alternative. */
// XXX: This rule is not valid in case `second` is `@Nullable`: in that case the Guava variant
// will return `null`, while the JDK variant will throw an NPE.
/**
* Prefer {@link Objects#requireNonNullElse(Object, Object)} over the Guava and Optional
* alternatives.
*/
// XXX: This rule is not valid in case `second` is `@Nullable`: in that case the Guava and
// Optional variants
// will return `null`, while the Objects.requireNonNullElse variant will throw an NPE.
static final class RequireNonNullElse<T> {
@BeforeTemplate
T before(T first, T second) {
return MoreObjects.firstNonNull(first, second);
}

@BeforeTemplate
T beforeOptional(T first, T second) {
return Optional.ofNullable(first).orElse(second);
}

@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
T after(T first, T second) {
return requireNonNullElse(first, second);
}
}

/**
* Prefer {@link Objects#requireNonNullElseGet(Object, Supplier)} over {@link Optional}{@code
* .ofNullable(Object).orElseGet(Supplier)}
*/
// XXX: This rule is not valid in case `supplier` may return `null`: Optional will return `null`,
// while the `requireNonNullElseGet` replacement will throw an NPE.
static final class RequireNonNullElseGet<T, S extends Supplier<T>> {
@BeforeTemplate
T before(T object, S defaultSupplier) {
return Optional.ofNullable(object).orElseGet(defaultSupplier);
}

@AfterTemplate
@UseImportPolicy(STATIC_IMPORT_ALWAYS)
T after(T object, S defaultSupplier) {
return requireNonNullElseGet(object, defaultSupplier);
}
}

/** Prefer {@link Objects#isNull(Object)} over the equivalent lambda function. */
static final class IsNullFunction<T> {
@BeforeTemplate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ boolean testIsNotNull() {
return Objects.nonNull("foo");
}

String testRequireNonNullElse() {
return MoreObjects.firstNonNull("foo", "bar");
ImmutableSet<String> testRequireNonNullElse() {
return ImmutableSet.of(
MoreObjects.firstNonNull("foo", "bar"), java.util.Optional.ofNullable("foo").orElse("bar"));
}

String testRequireNonNullElseGet() {
return java.util.Optional.ofNullable("foo").orElseGet(() -> "bar");
}

long testIsNullFunction() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tech.picnic.errorprone.refasterrules;

import static java.util.Objects.requireNonNullElse;
import static java.util.Objects.requireNonNullElseGet;

import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableSet;
Expand All @@ -22,8 +23,12 @@ boolean testIsNotNull() {
return "foo" != null;
}

String testRequireNonNullElse() {
return requireNonNullElse("foo", "bar");
ImmutableSet<String> testRequireNonNullElse() {
return ImmutableSet.of(requireNonNullElse("foo", "bar"), requireNonNullElse("foo", "bar"));
}

String testRequireNonNullElseGet() {
return requireNonNullElseGet("foo", () -> "bar");
}

long testIsNullFunction() {
Expand Down

0 comments on commit 161cc4d

Please sign in to comment.