diff --git a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/PreconditionsRules.java b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/PreconditionsRules.java index 0d11cc3627..e5e73f82b6 100644 --- a/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/PreconditionsRules.java +++ b/error-prone-contrib/src/main/java/tech/picnic/errorprone/refasterrules/PreconditionsRules.java @@ -9,8 +9,11 @@ import static java.util.Objects.requireNonNull; import com.google.common.base.Preconditions; +import com.google.errorprone.annotations.FormatMethod; +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.Repeated; import com.google.errorprone.refaster.annotation.UseImportPolicy; import java.util.Objects; import tech.picnic.errorprone.refaster.annotation.OnlineDocumentation; @@ -52,6 +55,26 @@ void after(boolean condition, String message) { } } + /** + * Prefer {@link Preconditions#checkArgument(boolean, String, Object...)} over more verbose + * alternatives. + */ + // XXX: This check assumes that the format string only uses `%s` placeholders. + static final class CheckArgumentWithMessageAndArguments { + @BeforeTemplate + @FormatMethod + void before(boolean condition, String message, @Repeated Object... args) { + checkArgument( + condition, Refaster.anyOf(String.format(message, args), message.formatted(args))); + } + + @AfterTemplate + @UseImportPolicy(STATIC_IMPORT_ALWAYS) + void after(boolean condition, String message, @Repeated Object... args) { + checkArgument(condition, message, args); + } + } + /** * Prefer {@link Preconditions#checkElementIndex(int, int, String)} over less descriptive or more * verbose alternatives. @@ -205,4 +228,23 @@ void after(boolean condition, String message) { checkState(!condition, message); } } + + /** + * Prefer {@link Preconditions#checkState(boolean, String, Object...)} over more verbose + * alternatives. + */ + // XXX: This check assumes that the format string only uses `%s` placeholders. + static final class CheckStateWithMessageAndArguments { + @BeforeTemplate + @FormatMethod + void before(boolean condition, String message, @Repeated Object... args) { + checkState(condition, Refaster.anyOf(String.format(message, args), message.formatted(args))); + } + + @AfterTemplate + @UseImportPolicy(STATIC_IMPORT_ALWAYS) + void after(boolean condition, String message, @Repeated Object... args) { + checkState(condition, message, args); + } + } } diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/PreconditionsRulesTestInput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/PreconditionsRulesTestInput.java index 337c929827..c08d20dd92 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/PreconditionsRulesTestInput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/PreconditionsRulesTestInput.java @@ -1,6 +1,8 @@ package tech.picnic.errorprone.refasterrules; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; import com.google.common.collect.ImmutableSet; import tech.picnic.errorprone.refaster.test.RefasterRuleCollectionTestCase; @@ -24,6 +26,11 @@ void testCheckArgumentWithMessage() { } } + void testCheckArgumentWithMessageAndArguments() { + checkArgument("foo".isEmpty(), String.format("The %s is empty", 1)); + checkArgument("bar".isEmpty(), "The %s is %s".formatted(2.0, false)); + } + void testCheckElementIndexWithMessage() { if (1 < 0 || 1 >= 2) { throw new IndexOutOfBoundsException("My index"); @@ -73,4 +80,9 @@ void testCheckStateWithMessage() { throw new IllegalStateException("The string is empty"); } } + + void testCheckStateWithMessageAndArguments() { + checkState("foo".isEmpty(), String.format("The %s is empty", 1)); + checkState("bar".isEmpty(), "The %s is %s".formatted(2.0, false)); + } } diff --git a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/PreconditionsRulesTestOutput.java b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/PreconditionsRulesTestOutput.java index 1b95c23444..b155abc184 100644 --- a/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/PreconditionsRulesTestOutput.java +++ b/error-prone-contrib/src/test/resources/tech/picnic/errorprone/refasterrules/PreconditionsRulesTestOutput.java @@ -25,6 +25,11 @@ void testCheckArgumentWithMessage() { checkArgument(!"foo".isEmpty(), "The string is empty"); } + void testCheckArgumentWithMessageAndArguments() { + checkArgument("foo".isEmpty(), "The %s is empty", 1); + checkArgument("bar".isEmpty(), "The %s is %s", 2.0, false); + } + void testCheckElementIndexWithMessage() { checkElementIndex(1, 2, "My index"); } @@ -60,4 +65,9 @@ void testCheckState() { void testCheckStateWithMessage() { checkState(!"foo".isEmpty(), "The string is empty"); } + + void testCheckStateWithMessageAndArguments() { + checkState("foo".isEmpty(), "The %s is empty", 1); + checkState("bar".isEmpty(), "The %s is %s", 2.0, false); + } }