From cb0d519c33f38b1de356fbbf5e8a0ea2bee029d3 Mon Sep 17 00:00:00 2001 From: mlrprananta Date: Fri, 10 Mar 2023 15:33:20 +0100 Subject: [PATCH] Prefer Optional#orElseGet over Optional#orElse for non-compile-time input --- .../refasterrules/OptionalRules.java | 18 ++++++++++++++++++ .../refasterrules/OptionalRulesTestInput.java | 4 ++++ .../refasterrules/OptionalRulesTestOutput.java | 5 +++++ 3 files changed, 27 insertions(+) diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/OptionalRules.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/OptionalRules.java index 676c7633e9d..2b5c7ea716c 100644 --- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/OptionalRules.java +++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/OptionalRules.java @@ -3,10 +3,12 @@ import static com.google.errorprone.refaster.ImportPolicy.STATIC_IMPORT_ALWAYS; import com.google.common.collect.Streams; +import com.google.errorprone.matchers.CompileTimeConstantExpressionMatcher; import com.google.errorprone.refaster.Refaster; import com.google.errorprone.refaster.annotation.AfterTemplate; import com.google.errorprone.refaster.annotation.BeforeTemplate; import com.google.errorprone.refaster.annotation.MayOptionallyUse; +import com.google.errorprone.refaster.annotation.NotMatches; import com.google.errorprone.refaster.annotation.Placeholder; import com.google.errorprone.refaster.annotation.UseImportPolicy; import java.util.Comparator; @@ -220,6 +222,22 @@ T after(Optional o1, Optional o2) { } } + /** + * Prefer {@link Optional#orElseGet(Supplier)} over {@link Optional#orElse(Object)} if the given + * value is not a compile-time constant. + */ + abstract static class OrElseToOrElseGet { + @BeforeTemplate + T before(Optional o, @NotMatches(CompileTimeConstantExpressionMatcher.class) T value) { + return o.orElse(value); + } + + @AfterTemplate + T after(Optional o, T value) { + return o.orElseGet(() -> value); + } + } + /** * Flatten a stream of {@link Optional}s using {@link Optional#stream()}, rather than using one of * the more verbose alternatives. diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/OptionalRulesTestInput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/OptionalRulesTestInput.java index 5dbe4d699e7..0f0c524fffd 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/OptionalRulesTestInput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/OptionalRulesTestInput.java @@ -119,4 +119,8 @@ ImmutableSet> testOptionalFilter() { Optional testOptionalMap() { return Optional.of(1).stream().map(String::valueOf).findAny(); } + + ImmutableSet testOrElseToOrElseGet() { + return ImmutableSet.of(Optional.of("foo").orElse("bar"), Optional.of("foo").orElse(toString())); + } } diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/OptionalRulesTestOutput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/OptionalRulesTestOutput.java index e22d20066f7..d40efdc5adb 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/OptionalRulesTestOutput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/OptionalRulesTestOutput.java @@ -112,4 +112,9 @@ ImmutableSet> testOptionalFilter() { Optional testOptionalMap() { return Optional.of(1).map(String::valueOf); } + + ImmutableSet testOrElseToOrElseGet() { + return ImmutableSet.of( + Optional.of("foo").orElse("bar"), Optional.of("foo").orElseGet(() -> toString())); + } }