From ea90846d6214b6f5f30fb630d9bc7e2523ebc256 Mon Sep 17 00:00:00 2001 From: Marc Bruggmann Date: Thu, 15 Aug 2024 17:05:54 +0200 Subject: [PATCH 1/5] Handle generics in PreferJavaUtilObjectsRequireNonNull Before this patch, the PreferJavaUtilObjectsRequireNonNull recipe would only migrate usage of exactly `checkNotNull(Object)` but not any other (sub)types. We now match invocations of checkNotNull with exactly one or two arguments (both in refaster). Note that there is also a three argument version that doesn't have a straight-forward replacement, I skipped that for now and added a testcase. --- .../java/migrate/guava/NoGuavaRefaster.java | 16 +++++++ .../resources/META-INF/rewrite/no-guava.yml | 16 ------- .../guava/PreferJavaUtilObjectsTest.java | 45 +++++++++++++++++++ 3 files changed, 61 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java b/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java index 9f03d57065..bc40193a79 100644 --- a/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java +++ b/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java @@ -30,6 +30,22 @@ public class NoGuavaRefaster { description = "Migrate from Guava `Preconditions.checkNotNull` to Java 8 `java.util.Objects.requireNonNull`." ) public static class PreconditionsCheckNotNullToObjectsRequireNonNull { + @BeforeTemplate + Object before(Object object) { + return com.google.common.base.Preconditions.checkNotNull(object); + } + + @AfterTemplate + Object after(Object object) { + return java.util.Objects.requireNonNull(object); + } + } + + @RecipeDescriptor( + name = "`Preconditions.checkNotNull` to `Objects.requireNonNull`", + description = "Migrate from Guava `Preconditions.checkNotNull` to Java 8 `java.util.Objects.requireNonNull`." + ) + public static class PreconditionsCheckNotNullWithMessageToObjectsRequireNonNull { @BeforeTemplate Object before(Object object, Object message) { return com.google.common.base.Preconditions.checkNotNull(object, message); diff --git a/src/main/resources/META-INF/rewrite/no-guava.yml b/src/main/resources/META-INF/rewrite/no-guava.yml index f382c46952..6fdbaa1bbb 100644 --- a/src/main/resources/META-INF/rewrite/no-guava.yml +++ b/src/main/resources/META-INF/rewrite/no-guava.yml @@ -42,7 +42,6 @@ recipeList: - org.openrewrite.java.migrate.guava.PreferJavaUtilSupplier - org.openrewrite.java.migrate.guava.PreferJavaUtilObjectsEquals - org.openrewrite.java.migrate.guava.PreferJavaUtilObjectsHashCode - - org.openrewrite.java.migrate.guava.PreferJavaUtilObjectsRequireNonNull - org.openrewrite.java.migrate.guava.PreferJavaUtilCollectionsUnmodifiableNavigableMap - org.openrewrite.java.migrate.guava.PreferJavaUtilCollectionsSynchronizedNavigableMap - org.openrewrite.java.migrate.guava.PreferCharCompare @@ -215,21 +214,6 @@ recipeList: methodPattern: com.google.common.base.Objects hash(..) fullyQualifiedTargetTypeName: java.util.Objects ---- -type: specs.openrewrite.org/v1beta/recipe -name: org.openrewrite.java.migrate.guava.PreferJavaUtilObjectsRequireNonNull -displayName: Prefer `java.util.Objects#requireNonNull` -description: Prefer `java.util.Objects#requireNonNull` instead of using `com.google.common.base.Preconditions#checkNotNull`. -tags: - - guava -recipeList: - - org.openrewrite.java.ChangeMethodName: - methodPattern: com.google.common.base.Preconditions checkNotNull(Object) - newMethodName: requireNonNull - - org.openrewrite.java.ChangeMethodTargetToStatic: - methodPattern: com.google.common.base.Preconditions requireNonNull(Object) - fullyQualifiedTargetTypeName: java.util.Objects - --- type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.migrate.guava.PreferJavaUtilObjectsRequireNonNullElse diff --git a/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java b/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java index 2a340b6195..63d3ad00f2 100644 --- a/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java +++ b/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java @@ -58,6 +58,33 @@ Object foo(Object obj) { ); } + @Test + void preconditionsCheckNotNullToObjectsRequireNonNullStringArgument() { + rewriteRun( + //language=java + java( + """ + import com.google.common.base.Preconditions; + + class A { + String foo(String str) { + return Preconditions.checkNotNull(str); + } + } + """, + """ + import java.util.Objects; + + class A { + String foo(String str) { + return Objects.requireNonNull(str); + } + } + """ + ) + ); + } + @Test void preconditionsCheckNotNullToObjectsRequireNonNullTwoArguments() { rewriteRun( @@ -139,6 +166,24 @@ Object foo(Object obj) { ); } + @Test + void preconditionsCheckNotNullWithTemplateArgument() { + rewriteRun( + //language=java + java( + """ + import com.google.common.base.Preconditions; + + class A { + Object foo(Object obj) { + return Preconditions.checkNotNull(obj, "%s", "foo"); + } + } + """ + ) + ); + } + @Test void moreObjectsFirstNonNullToObjectsRequireNonNullElse() { rewriteRun(spec -> spec.recipeFromResource("/META-INF/rewrite/no-guava.yml", "org.openrewrite.java.migrate.guava.NoGuavaJava11"), From e93f9fa96be04066ed45536a4ce3fc9c9d37974a Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 15 Aug 2024 20:51:20 +0200 Subject: [PATCH 2/5] Expect non-static import for now --- .../java/migrate/guava/PreferJavaUtilObjectsTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java b/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java index 63d3ad00f2..8dc5e940a0 100644 --- a/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java +++ b/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java @@ -154,11 +154,11 @@ Object foo(Object obj) { } """, """ - import static java.util.Objects.requireNonNull; + import java.util.Objects; class A { Object foo(Object obj) { - return requireNonNull(obj); + return Objects.requireNonNull(obj); } } """ @@ -168,6 +168,7 @@ Object foo(Object obj) { @Test void preconditionsCheckNotNullWithTemplateArgument() { + // There's no direct replacement for this three arg lenient format variant rewriteRun( //language=java java( From b86613df25b7195cd7ab91ff1110d5e36cc56b57 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 15 Aug 2024 20:55:43 +0200 Subject: [PATCH 3/5] Exclusively test with generated NoGuavaRefasterRecipes --- .../java/migrate/guava/PreferJavaUtilObjectsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java b/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java index 8dc5e940a0..9684e11e83 100644 --- a/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java +++ b/src/test/java/org/openrewrite/java/migrate/guava/PreferJavaUtilObjectsTest.java @@ -26,7 +26,7 @@ class PreferJavaUtilObjectsTest implements RewriteTest { @Override public void defaults(RecipeSpec spec) { - spec.recipeFromResource("/META-INF/rewrite/no-guava.yml", "org.openrewrite.java.migrate.guava.NoGuava") + spec.recipe(new NoGuavaRefasterRecipes()) .parser(JavaParser.fromJavaVersion().classpath("rewrite-java", "guava")); } From 272ba238dbc220785427662bd0cc90151fccd763 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 15 Aug 2024 21:06:33 +0200 Subject: [PATCH 4/5] Use a unique name for the new recipe --- .../org/openrewrite/java/migrate/guava/NoGuavaRefaster.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java b/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java index bc40193a79..12893163ec 100644 --- a/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java +++ b/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java @@ -42,7 +42,7 @@ Object after(Object object) { } @RecipeDescriptor( - name = "`Preconditions.checkNotNull` to `Objects.requireNonNull`", + name = "`Preconditions.checkNotNull` with message to `Objects.requireNonNull`", description = "Migrate from Guava `Preconditions.checkNotNull` to Java 8 `java.util.Objects.requireNonNull`." ) public static class PreconditionsCheckNotNullWithMessageToObjectsRequireNonNull { From f513c9b43fc9e28ab83f79c48f2eabe09d69b8bb Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Thu, 15 Aug 2024 21:07:39 +0200 Subject: [PATCH 5/5] Suppress warning --- .../java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java b/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java index 12893163ec..37db830d96 100644 --- a/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java +++ b/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaRefaster.java @@ -63,6 +63,7 @@ Object after(Object object, Object message) { ) public static class StringValueOfString { @BeforeTemplate + @SuppressWarnings("UnnecessaryCallToStringValueOf") String before(String string) { return String.valueOf(string); }