Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Refaster style recipes for Guava #522

Merged
merged 2 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.java.migrate.guava;
timtebeek marked this conversation as resolved.
Show resolved Hide resolved

import com.google.errorprone.refaster.annotation.AfterTemplate;
import com.google.errorprone.refaster.annotation.BeforeTemplate;
import org.openrewrite.java.template.RecipeDescriptor;

@RecipeDescriptor(
name = "Refaster style Guava to Java migration recipes.",
description = "Recipes that migrate from Guava to Java, using Refaster style templates for cases beyond what declarative recipes can cover."
)
public class NoGuavaRefaster {

@RecipeDescriptor(
name = "`Preconditions.checkNotNull` to `Objects.requireNonNull`",
description = "Migrate from Guava `Preconditions.checkNotNull` to Java 8 `java.util.Objects.requireNonNull`."
)
public static class PreconditionsCheckNotNullToObjectsRequireNonNull {
@BeforeTemplate
Object before(Object object, Object message) {
return com.google.common.base.Preconditions.checkNotNull(object, message);
}

@AfterTemplate
Object after(Object object, Object message) {
return java.util.Objects.requireNonNull(object, String.valueOf(message));
}
}

@RecipeDescriptor(
name = "`String.valueof(String)` to `String`",
description = "Migrate from `String.valueof(String)` to `String`, mainly as a cleanup after other recipes."
)
public static class StringValueOfString {
@BeforeTemplate
String before(String string) {
return String.valueOf(string);
}

@AfterTemplate
String after(String string) {
return (string);
}
}
}
1 change: 1 addition & 0 deletions src/main/resources/META-INF/rewrite/no-guava.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ recipeList:
- org.openrewrite.java.migrate.guava.NoGuavaListsNewArrayList
- org.openrewrite.java.migrate.guava.NoGuavaListsNewCopyOnWriteArrayList
- org.openrewrite.java.migrate.guava.NoGuavaListsNewLinkedList
- org.openrewrite.java.migrate.guava.NoGuavaRefasterRecipes
- org.openrewrite.java.migrate.guava.NoGuavaSetsNewHashSet
- org.openrewrite.java.migrate.guava.NoGuavaSetsNewConcurrentHashSet
- org.openrewrite.java.migrate.guava.NoGuavaSetsNewLinkedHashSet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
package org.openrewrite.java.migrate.guava;

import org.junit.jupiter.api.Test;
import org.junitpioneer.jupiter.ExpectedToFail;
import org.openrewrite.DocumentExample;
import org.openrewrite.config.Environment;
import org.openrewrite.java.JavaParser;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;
Expand All @@ -28,114 +26,143 @@
class PreferJavaUtilObjectsTest implements RewriteTest {
@Override
public void defaults(RecipeSpec spec) {
spec.recipe(
Environment.builder()
.scanRuntimeClasspath("org.openrewrite.java.migrate.guava")
.build()
.activateRecipes("org.openrewrite.java.migrate.guava.NoGuava")
)
spec.recipeFromResource("/META-INF/rewrite/no-guava.yml", "org.openrewrite.java.migrate.guava.NoGuava")
.parser(JavaParser.fromJavaVersion().classpath("rewrite-java", "guava"));
}

@DocumentExample
@Test
void preconditionsCheckNotNullToObjectsRequireNonNull() {
//language=java
rewriteRun(java(
"""
import com.google.common.base.Preconditions;

class A {
Object foo(Object obj) {
return Preconditions.checkNotNull(obj);
rewriteRun(
//language=java
java(
"""
import com.google.common.base.Preconditions;

class A {
Object foo(Object obj) {
return Preconditions.checkNotNull(obj);
}
}
}
""", """
import java.util.Objects;
""",
"""
import java.util.Objects;

class A {
Object foo(Object obj) {
return Objects.requireNonNull(obj);
class A {
Object foo(Object obj) {
return Objects.requireNonNull(obj);
}
}
}
"""));
"""
)
);
}

@Test
@ExpectedToFail("""
Preconditions has both `checkNotNull(Object, Object)` and `checkNotNull(Object, String, Object...)`,
meaning we can't exactly match only the `(Object, String)` case which Objects.requireNonNull supports.
""")
void preconditionsCheckNotNullToObjectsRequireNonNullTwoArguments() {
//language=java
rewriteRun(java(
"""
import com.google.common.base.Preconditions;

class A {
Object foo(Object obj) {
return Preconditions.checkNotNull(obj, "foo");
rewriteRun(
//language=java
java(
"""
import com.google.common.base.Preconditions;

class A {
Object foo(Object obj) {
return Preconditions.checkNotNull(obj, "foo");
}
}
""",
"""
import java.util.Objects;

class A {
Object foo(Object obj) {
return Objects.requireNonNull(obj, "foo");
}
}
"""
)
);
}

@Test
void preconditionsCheckNotNullToObjectsRequireNonNullTwoArgumentsSecondObject() {
rewriteRun(
//language=java
java(
"""
import com.google.common.base.Preconditions;

class A {
Object foo(Object obj, StringBuilder description) {
return Preconditions.checkNotNull(obj, description);
}
}
}
""", """
import java.util.Objects;
""",
"""
import java.util.Objects;

class A {
Object foo(Object obj) {
return Objects.requireNonNull(obj, "foo");
class A {
Object foo(Object obj, StringBuilder description) {
return Objects.requireNonNull(obj, String.valueOf(description));
}
}
}
"""));
"""
)
);
}

@Test
void preconditionsCheckNotNullToObjectsRequireNonNullStatic() {
//language=java
rewriteRun(java(
"""
import static com.google.common.base.Preconditions.checkNotNull;

class A {
Object foo(Object obj) {
return checkNotNull(obj);
rewriteRun(
//language=java
java(
"""
import static com.google.common.base.Preconditions.checkNotNull;

class A {
Object foo(Object obj) {
return checkNotNull(obj);
}
}
}
""", """
import static java.util.Objects.requireNonNull;
""",
"""
import static java.util.Objects.requireNonNull;

class A {
Object foo(Object obj) {
return requireNonNull(obj);
class A {
Object foo(Object obj) {
return requireNonNull(obj);
}
}
}
"""));
"""
)
);
}

@Test
void moreObjectsFirstNonNullToObjectsRequireNonNullElse() {
//language=java
rewriteRun(spec -> {spec.recipes(Environment.builder()
.scanRuntimeClasspath("org.openrewrite.java.migrate.guava")
.build()
.activateRecipes("org.openrewrite.java.migrate.guava.NoGuavaJava11"));
},
rewriteRun(spec -> spec.recipeFromResource("/META-INF/rewrite/no-guava.yml", "org.openrewrite.java.migrate.guava.NoGuavaJava11"),
//language=java
java(
"""
import com.google.common.base.MoreObjects;
"""
import com.google.common.base.MoreObjects;

class A {
Object foo(Object obj) {
return MoreObjects.firstNonNull(obj, "default");
class A {
Object foo(Object obj) {
return MoreObjects.firstNonNull(obj, "default");
}
}
}
""", """
import java.util.Objects;
""",
"""
import java.util.Objects;

class A {
Object foo(Object obj) {
return Objects.requireNonNullElse(obj, "default");
class A {
Object foo(Object obj) {
return Objects.requireNonNullElse(obj, "default");
}
}
}
"""));
"""
)
);
}
}
Loading