diff --git a/src/main/java/org/openrewrite/java/template/processor/RefasterTemplateProcessor.java b/src/main/java/org/openrewrite/java/template/processor/RefasterTemplateProcessor.java index 9a29a9dd..8e0de89c 100644 --- a/src/main/java/org/openrewrite/java/template/processor/RefasterTemplateProcessor.java +++ b/src/main/java/org/openrewrite/java/template/processor/RefasterTemplateProcessor.java @@ -67,8 +67,7 @@ public class RefasterTemplateProcessor extends TypeAwareProcessor { "com.google.errorprone.refaster.annotation.NotMatches", "com.google.errorprone.refaster.annotation.OfKind", "com.google.errorprone.refaster.annotation.Placeholder", - "com.google.errorprone.refaster.annotation.Repeated", - "com.google.errorprone.refaster.annotation.UseImportPolicy" + "com.google.errorprone.refaster.annotation.Repeated" ).collect(Collectors.toSet()); static ClassValue> LST_TYPE_MAP = new ClassValue>() { diff --git a/src/test/java/com/google/errorprone/refaster/ImportPolicy.java b/src/test/java/com/google/errorprone/refaster/ImportPolicy.java new file mode 100644 index 00000000..7afa7cf6 --- /dev/null +++ b/src/test/java/com/google/errorprone/refaster/ImportPolicy.java @@ -0,0 +1,22 @@ +/* + * Copyright 2023 the original author or authors. + *

+ * 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 + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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 com.google.errorprone.refaster; + +public enum ImportPolicy { + IMPORT_TOP_LEVEL, + IMPORT_CLASS_DIRECTLY, + STATIC_IMPORT_ALWAYS +} \ No newline at end of file diff --git a/src/test/java/com/google/errorprone/refaster/annotation/UseImportPolicy.java b/src/test/java/com/google/errorprone/refaster/annotation/UseImportPolicy.java new file mode 100644 index 00000000..15562ec1 --- /dev/null +++ b/src/test/java/com/google/errorprone/refaster/annotation/UseImportPolicy.java @@ -0,0 +1,28 @@ +/* + * Copyright 2023 the original author or authors. + *

+ * 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 + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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 com.google.errorprone.refaster.annotation; + +import com.google.errorprone.refaster.ImportPolicy; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.SOURCE) +public @interface UseImportPolicy { + ImportPolicy value(); +} diff --git a/src/test/resources/refaster/ShouldAddImports.java b/src/test/resources/refaster/ShouldAddImports.java index 76a0cd42..fffb994a 100644 --- a/src/test/resources/refaster/ShouldAddImports.java +++ b/src/test/resources/refaster/ShouldAddImports.java @@ -15,11 +15,15 @@ */ package foo; +import com.google.errorprone.refaster.ImportPolicy; import com.google.errorprone.refaster.annotation.AfterTemplate; import com.google.errorprone.refaster.annotation.BeforeTemplate; +import com.google.errorprone.refaster.annotation.UseImportPolicy; +import java.nio.file.Path; import java.util.Objects; +import static java.nio.file.Files.exists; import static java.util.Objects.hash; public class ShouldAddImports { @@ -63,4 +67,17 @@ int after(String s) { return s.hashCode(); } } + + public static class FileExists { + @BeforeTemplate + boolean before(Path path) { + return path.toFile().exists(); + } + + @AfterTemplate + @UseImportPolicy(ImportPolicy.STATIC_IMPORT_ALWAYS) + boolean after(Path path) { + return exists(path); + } + } } diff --git a/src/test/resources/refaster/ShouldAddImportsRecipes.java b/src/test/resources/refaster/ShouldAddImportsRecipes.java index ca440105..8d573dd4 100644 --- a/src/test/resources/refaster/ShouldAddImportsRecipes.java +++ b/src/test/resources/refaster/ShouldAddImportsRecipes.java @@ -34,12 +34,13 @@ import static org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor.EmbeddingOption.*; import java.util.Objects; +import java.nio.file.Path; +import static java.nio.file.Files.exists; import static java.util.Objects.hash; @SuppressWarnings("all") public class ShouldAddImportsRecipes extends Recipe { - public ShouldAddImportsRecipes() {} @Override @@ -57,7 +58,8 @@ public List getRecipeList() { return Arrays.asList( new StringValueOfRecipe(), new ObjectsEqualsRecipe(), - new StaticImportObjectsHashRecipe() + new StaticImportObjectsHashRecipe(), + new FileExistsRecipe() ); } @@ -210,4 +212,52 @@ public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { } } + @SuppressWarnings("all") + @NonNullApi + public static class FileExistsRecipe extends Recipe { + + public FileExistsRecipe() {} + + @Override + public String getDisplayName() { + return "Refaster template `ShouldAddImports.FileExists`"; + } + + @Override + public String getDescription() { + return "Recipe created for the following Refaster template:\n```java\npublic static class FileExists {\n \n @BeforeTemplate()\n boolean before(Path path) {\n return path.toFile().exists();\n }\n \n @AfterTemplate()\n @UseImportPolicy(value = ImportPolicy.STATIC_IMPORT_ALWAYS)\n boolean after(Path path) {\n return exists(path);\n }\n}\n```\n."; + } + + @Override + public TreeVisitor getVisitor() { + JavaVisitor javaVisitor = new AbstractRefasterJavaVisitor() { + final JavaTemplate before = Semantics.expression(this, "before", (java.nio.file.Path path) -> path.toFile().exists()).build(); + final JavaTemplate after = Semantics.expression(this, "after", (java.nio.file.Path path) -> exists(path)).build(); + + @Override + public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { + JavaTemplate.Matcher matcher; + if ((matcher = before.matcher(getCursor())).find()) { + return embed( + after.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)), + getCursor(), + ctx, + SHORTEN_NAMES, SIMPLIFY_BOOLEANS + ); + } + return super.visitMethodInvocation(elem, ctx); + } + + }; + return Preconditions.check( + Preconditions.and( + new UsesType<>("java.nio.file.Path", true), + new UsesMethod<>("java.io.File exists(..)"), + new UsesMethod<>("java.nio.file.Path toFile(..)") + ), + javaVisitor + ); + } + } + }