diff --git a/src/test/java/org/openrewrite/java/template/RefasterTemplateProcessorTest.java b/src/test/java/org/openrewrite/java/template/RefasterTemplateProcessorTest.java index 07e12fc7..b05d60c5 100644 --- a/src/test/java/org/openrewrite/java/template/RefasterTemplateProcessorTest.java +++ b/src/test/java/org/openrewrite/java/template/RefasterTemplateProcessorTest.java @@ -30,11 +30,11 @@ import static com.google.testing.compile.CompilationSubject.assertThat; import static com.google.testing.compile.Compiler.javac; +import static org.junit.jupiter.api.Assertions.assertEquals; class RefasterTemplateProcessorTest { @ParameterizedTest @ValueSource(strings = { - "ConstantsFormat", "MethodThrows", "NestedPreconditions", "ParameterReuse", @@ -42,11 +42,7 @@ class RefasterTemplateProcessorTest { "SimplifyBooleans", }) void generateRecipe(String recipeName) { - // As per https://github.com/google/compile-testing/blob/v0.21.0/src/main/java/com/google/testing/compile/package-info.java#L53-L55 - Compilation compilation = javac() - .withProcessors(new RefasterTemplateProcessor()) - .withClasspath(classpath()) - .compile(JavaFileObjects.forResource("refaster/" + recipeName + ".java")); + Compilation compilation = compile("refaster/" + recipeName + ".java"); assertThat(compilation).succeeded(); assertThat(compilation).hadNoteCount(0); assertThat(compilation) @@ -59,27 +55,22 @@ void generateRecipe(String recipeName) { "OrElseGetGet", "RefasterAnyOf", }) - void skipRecipeGeneration(String recipeName){ - Compilation compilation = javac() - .withProcessors(new RefasterTemplateProcessor()) - .withClasspath(classpath()) - .compile(JavaFileObjects.forResource("refaster/" + recipeName + ".java")); + void skipRecipeGeneration(String recipeName) { + Compilation compilation = compile("refaster/" + recipeName + ".java"); assertThat(compilation).succeeded(); - assert compilation.generatedSourceFiles().isEmpty(); + assertEquals(0, compilation.generatedSourceFiles().size(), "Should not generate recipe for " + recipeName); } @ParameterizedTest @ValueSource(strings = { - "ShouldSupportNestedClasses", - "ShouldAddImports", - "MultipleDereferences", + "Escapes", "Matching", + "MultipleDereferences", + "ShouldAddImports", + "ShouldSupportNestedClasses", }) void nestedRecipes(String recipeName) { - Compilation compilation = javac() - .withProcessors(new RefasterTemplateProcessor()) - .withClasspath(classpath()) - .compile(JavaFileObjects.forResource("refaster/" + recipeName + ".java")); + Compilation compilation = compile("refaster/" + recipeName + ".java"); assertThat(compilation).succeeded(); assertThat(compilation).hadNoteCount(0); assertThat(compilation) // Recipes (plural) @@ -87,6 +78,14 @@ void nestedRecipes(String recipeName) { .hasSourceEquivalentTo(JavaFileObjects.forResource("refaster/" + recipeName + "Recipes.java")); } + private static Compilation compile(String resourceName) { + // As per https://github.com/google/compile-testing/blob/v0.21.0/src/main/java/com/google/testing/compile/package-info.java#L53-L55 + return javac() + .withProcessors(new RefasterTemplateProcessor()) + .withClasspath(classpath()) + .compile(JavaFileObjects.forResource(resourceName)); + } + static Collection classpath() { return Arrays.asList( fileForClass(BeforeTemplate.class), @@ -100,7 +99,7 @@ static Collection classpath() { } // As per https://github.com/google/auto/blob/auto-value-1.10.2/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryProcessorTest.java#L99 - static File fileForClass(Class c) { + private static File fileForClass(Class c) { URL url = c.getProtectionDomain().getCodeSource().getLocation(); assert url.getProtocol().equals("file") || url.getProtocol().equals("jrt") : "Unexpected URL: " + url; return new File(url.getPath()); diff --git a/src/test/java/org/openrewrite/java/template/TemplateProcessorTest.java b/src/test/java/org/openrewrite/java/template/TemplateProcessorTest.java index 333eb814..be9ffb8d 100644 --- a/src/test/java/org/openrewrite/java/template/TemplateProcessorTest.java +++ b/src/test/java/org/openrewrite/java/template/TemplateProcessorTest.java @@ -37,12 +37,8 @@ class TemplateProcessorTest { }) void qualification(String qualifier) { // As per https://github.com/google/compile-testing/blob/v0.21.0/src/main/java/com/google/testing/compile/package-info.java#L53-L55 - Compilation compilation = javac() - .withProcessors(new RefasterTemplateProcessor(), new TemplateProcessor()) - .withClasspath(classpath()) - .compile(JavaFileObjects.forResource("template/ShouldAddClasspath.java")); + Compilation compilation = compile("template/ShouldAddClasspath.java"); assertThat(compilation).succeeded(); - compilation.generatedSourceFiles().forEach(System.out::println); assertThat(compilation) .generatedSourceFile("foo/ShouldAddClasspathRecipes$" + qualifier + "Recipe$1_before") .hasSourceEquivalentTo(JavaFileObjects.forResource("template/ShouldAddClasspathRecipe$" + qualifier + "Recipe$1_before.java")); @@ -53,14 +49,17 @@ void qualification(String qualifier) { @Test void parameterReuse() { - Compilation compilation = javac() - .withProcessors(new RefasterTemplateProcessor(), new TemplateProcessor()) - .withClasspath(classpath()) - .compile(JavaFileObjects.forResource("template/ParameterReuse.java")); + Compilation compilation = compile("template/ParameterReuse.java"); assertThat(compilation).succeeded(); - compilation.generatedSourceFiles().forEach(System.out::println); assertThat(compilation) .generatedSourceFile("foo/ParameterReuseRecipe$1_before") .hasSourceEquivalentTo(JavaFileObjects.forResource("template/ParameterReuseRecipe$1_before.java")); } + + private static Compilation compile(String resourceName) { + return javac() + .withProcessors(new RefasterTemplateProcessor(), new TemplateProcessor()) + .withClasspath(classpath()) + .compile(JavaFileObjects.forResource(resourceName)); + } } diff --git a/src/test/resources/refaster/ConstantsFormatRecipe.java b/src/test/resources/refaster/ConstantsFormatRecipe.java deleted file mode 100644 index 9a826a7d..00000000 --- a/src/test/resources/refaster/ConstantsFormatRecipe.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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 foo; - -import org.openrewrite.ExecutionContext; -import org.openrewrite.Preconditions; -import org.openrewrite.Recipe; -import org.openrewrite.TreeVisitor; -import org.openrewrite.internal.lang.NonNullApi; -import org.openrewrite.java.JavaTemplate; -import org.openrewrite.java.JavaVisitor; -import org.openrewrite.java.search.*; -import org.openrewrite.java.template.Primitive; -import org.openrewrite.java.template.Semantics; -import org.openrewrite.java.template.function.*; -import org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor; -import org.openrewrite.java.tree.*; - -import java.util.*; - -import static org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor.EmbeddingOption.*; - -import com.sun.tools.javac.util.Convert; -import com.sun.tools.javac.util.Constants; - -@NonNullApi -public class ConstantsFormatRecipe extends Recipe { - - @Override - public String getDisplayName() { - return "Refaster template `ConstantsFormat`"; - } - - @Override - public String getDescription() { - return "Recipe created for the following Refaster template:\n```java\nclass ConstantsFormat {\n \n @BeforeTemplate()\n String before(String value) {\n return String.format(\"\\\"%s\\\"\", Convert.quote(value));\n }\n \n @AfterTemplate()\n String after(String value) {\n return Constants.format(value);\n }\n}\n```\n."; - } - - @Override - public TreeVisitor getVisitor() { - JavaVisitor javaVisitor = new AbstractRefasterJavaVisitor() { - final JavaTemplate before = Semantics.expression(this, "before", (String value) -> String.format("\"%s\"", com.sun.tools.javac.util.Convert.quote(value))).build(); - final JavaTemplate after = Semantics.expression(this, "after", (String value) -> com.sun.tools.javac.util.Constants.format(value)).build(); - - @Override - public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { - JavaTemplate.Matcher matcher; - if ((matcher = before.matcher(getCursor())).find()) { - maybeRemoveImport("com.sun.tools.javac.util.Convert"); - return embed( - after.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)), - getCursor(), - ctx, - SHORTEN_NAMES - ); - } - return super.visitMethodInvocation(elem, ctx); - } - - }; - return Preconditions.check( - Preconditions.and( - new UsesType<>("com.sun.tools.javac.util.Convert", true), - new UsesMethod<>("java.lang.String format(..)"), - new UsesMethod<>("com.sun.tools.javac.util.Convert quote(..)") - ), - javaVisitor - ); - } -} diff --git a/src/test/resources/refaster/ConstantsFormat.java b/src/test/resources/refaster/Escapes.java similarity index 60% rename from src/test/resources/refaster/ConstantsFormat.java rename to src/test/resources/refaster/Escapes.java index 1282466d..10c1015e 100644 --- a/src/test/resources/refaster/ConstantsFormat.java +++ b/src/test/resources/refaster/Escapes.java @@ -20,14 +20,28 @@ import com.sun.tools.javac.util.Constants; import com.sun.tools.javac.util.Convert; -class ConstantsFormat { - @BeforeTemplate - String before(String value) { - return String.format("\"%s\"", Convert.quote(value)); +public class Escapes { + public static class ConstantsFormat { + @BeforeTemplate + String before(String value) { + return String.format("\"%s\"", Convert.quote(value)); + } + + @AfterTemplate + String after(String value) { + return Constants.format(value); + } } - @AfterTemplate - String after(String value) { - return Constants.format(value); + public static class Split { + @BeforeTemplate + String[] before(String s) { + return s.split("[^\\S]+"); + } + + @AfterTemplate + String[] after(String s) { + return s.split("\\s+"); + } } } diff --git a/src/test/resources/refaster/EscapesRecipes.java b/src/test/resources/refaster/EscapesRecipes.java new file mode 100644 index 00000000..538ebf8c --- /dev/null +++ b/src/test/resources/refaster/EscapesRecipes.java @@ -0,0 +1,145 @@ +/* + * 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 foo; + +import org.openrewrite.ExecutionContext; +import org.openrewrite.Preconditions; +import org.openrewrite.Recipe; +import org.openrewrite.TreeVisitor; +import org.openrewrite.internal.lang.NonNullApi; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.JavaVisitor; +import org.openrewrite.java.search.*; +import org.openrewrite.java.template.Primitive; +import org.openrewrite.java.template.Semantics; +import org.openrewrite.java.template.function.*; +import org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor; +import org.openrewrite.java.tree.*; + +import java.util.*; + +import static org.openrewrite.java.template.internal.AbstractRefasterJavaVisitor.EmbeddingOption.*; + +import com.sun.tools.javac.util.Convert; +import com.sun.tools.javac.util.Constants; + +public class EscapesRecipes extends Recipe { + @Override + public String getDisplayName() { + return "`Escapes` Refaster recipes"; + } + + @Override + public String getDescription() { + return "Refaster template recipes for `foo.Escapes`."; + } + + @Override + public List getRecipeList() { + return Arrays.asList( + new ConstantsFormatRecipe(), + new SplitRecipe() + ); + } + + @NonNullApi + public static class ConstantsFormatRecipe extends Recipe { + + @Override + public String getDisplayName() { + return "Refaster template `Escapes.ConstantsFormat`"; + } + + @Override + public String getDescription() { + return "Recipe created for the following Refaster template:\n```java\npublic static class ConstantsFormat {\n \n @BeforeTemplate()\n String before(String value) {\n return String.format(\"\\\"%s\\\"\", Convert.quote(value));\n }\n \n @AfterTemplate()\n String after(String value) {\n return Constants.format(value);\n }\n}\n```\n."; + } + + @Override + public TreeVisitor getVisitor() { + JavaVisitor javaVisitor = new AbstractRefasterJavaVisitor() { + final JavaTemplate before = Semantics.expression(this, "before", (String value) -> String.format("\"%s\"", com.sun.tools.javac.util.Convert.quote(value))).build(); + final JavaTemplate after = Semantics.expression(this, "after", (String value) -> com.sun.tools.javac.util.Constants.format(value)).build(); + + @Override + public J visitMethodInvocation(J.MethodInvocation elem, ExecutionContext ctx) { + JavaTemplate.Matcher matcher; + if ((matcher = before.matcher(getCursor())).find()) { + maybeRemoveImport("com.sun.tools.javac.util.Convert"); + return embed( + after.apply(getCursor(), elem.getCoordinates().replace(), matcher.parameter(0)), + getCursor(), + ctx, + SHORTEN_NAMES + ); + } + return super.visitMethodInvocation(elem, ctx); + } + + }; + return Preconditions.check( + Preconditions.and( + new UsesType<>("com.sun.tools.javac.util.Convert", true), + new UsesMethod<>("java.lang.String format(..)"), + new UsesMethod<>("com.sun.tools.javac.util.Convert quote(..)") + ), + javaVisitor + ); + } + } + + @NonNullApi + public static class SplitRecipe extends Recipe { + + @Override + public String getDisplayName() { + return "Refaster template `Escapes.Split`"; + } + + @Override + public String getDescription() { + return "Recipe created for the following Refaster template:\n```java\npublic static class Split {\n \n @BeforeTemplate()\n String[] before(String s) {\n return s.split(\"[^\\\\S]+\");\n }\n \n @AfterTemplate()\n String[] after(String s) {\n return s.split(\"\\\\s+\");\n }\n}\n```\n."; + } + + @Override + public TreeVisitor getVisitor() { + JavaVisitor javaVisitor = new AbstractRefasterJavaVisitor() { + final JavaTemplate before = Semantics.expression(this, "before", (String s) -> s.split("[^\\S]+")).build(); + final JavaTemplate after = Semantics.expression(this, "after", (String s) -> s.split("\\s+")).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 + ); + } + return super.visitMethodInvocation(elem, ctx); + } + + }; + return Preconditions.check( + new UsesMethod<>("java.lang.String split(..)"), + javaVisitor + ); + } + } + +} \ No newline at end of file