Skip to content

Commit

Permalink
Find Refaster style recipes as well (#4693)
Browse files Browse the repository at this point in the history
  • Loading branch information
timtebeek authored Nov 20, 2024
1 parent df6a2c9 commit 284e5f6
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public static class Row {

public enum RecipeType {
Java,
Refaster,
Yaml
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,24 @@
import org.openrewrite.DocumentExample;
import org.openrewrite.java.JavaParser;
import org.openrewrite.table.RewriteRecipeSource;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;

import static org.assertj.core.api.Assertions.assertThat;
import static org.openrewrite.java.Assertions.java;

class FindRecipesTest implements RewriteTest {

@Override
public void defaults(RecipeSpec spec) {
spec.recipe(new FindRecipes()).parser(JavaParser.fromJavaVersion().classpath(JavaParser.runtimeClasspath()));
}

@DocumentExample
@Test
void findRecipes() {
rewriteRun(
spec -> spec
.recipe(new FindRecipes())
.parser(JavaParser.fromJavaVersion()
.classpath(JavaParser.runtimeClasspath()))
.dataTable(RewriteRecipeSource.Row.class, rows -> {
assertThat(rows).hasSize(1);
RewriteRecipeSource.Row row = rows.get(0);
Expand Down Expand Up @@ -66,7 +69,7 @@ class MyRecipe extends Recipe {
public String getDisplayName() {
return "My recipe";
}
@Override
public String getDescription() {
return "This is my recipe.";
Expand All @@ -85,19 +88,19 @@ class /*~~>*/MyRecipe extends Recipe {
description = "A method pattern that is used to find matching method declarations/invocations.",
example = "org.mockito.Matchers anyVararg()")
String methodPattern;
@Option(displayName = "New access level",
description = "New method access level to apply to the method, like \\"public\\".",
example = "public",
valid = {"private", "protected", "package", "public"},
required = false)
String newAccessLevel;
@Override
public String getDisplayName() {
return "My recipe";
}
@Override
public String getDescription() {
return "This is my recipe.";
Expand All @@ -111,7 +114,6 @@ public String getDescription() {
@Test
void returnInLambda() {
rewriteRun(
spec -> spec.recipe(new FindRecipes()),
java(
"""
import java.util.function.UnaryOperator;
Expand All @@ -126,4 +128,50 @@ class SomeTest {
)
);
}

@Test
void findRefasterRecipe() {
rewriteRun(
spec -> spec.parser(JavaParser.fromJavaVersion().dependsOn(
"""
package org.openrewrite.java.template;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
public @interface RecipeDescriptor {
String name();
String description();
}
"""
))
.dataTable(RewriteRecipeSource.Row.class, rows -> {
assertThat(rows).hasSize(1);
RewriteRecipeSource.Row row = rows.get(0);
assertThat(row.getDisplayName()).isEqualTo("Some refaster rule");
assertThat(row.getDescription()).isEqualTo("This is a refaster rule.");
}),
java(
"""
import org.openrewrite.java.template.RecipeDescriptor;
@RecipeDescriptor(
name = "Some refaster rule",
description = "This is a refaster rule."
)
class SomeRefasterRule {
}
""",
"""
import org.openrewrite.java.template.RecipeDescriptor;
/*~~>*/@RecipeDescriptor(
name = "Some refaster rule",
description = "This is a refaster rule."
)
class SomeRefasterRule {
}
"""
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.ValueNode;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Preconditions;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.*;
import org.openrewrite.java.AnnotationMatcher;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.MethodMatcher;
Expand Down Expand Up @@ -55,6 +53,65 @@ public String getDescription() {

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
TreeVisitor<?, ExecutionContext> findRefasterRecipes = findRefasterRecipes();
TreeVisitor<?, ExecutionContext> findImperativeRecipes = findImperativeRecipes();
return new TreeVisitor<Tree, ExecutionContext>() {
@Override
public @Nullable Tree preVisit(@NonNull Tree tree, ExecutionContext ctx) {
stopAfterPreVisit();
tree = findRefasterRecipes.visit(tree, ctx);
tree = findImperativeRecipes.visit(tree, ctx);
return tree;
}
};
}

private TreeVisitor<?, ExecutionContext> findRefasterRecipes() {
String recipeDescriptor = "org.openrewrite.java.template.RecipeDescriptor";
AnnotationMatcher annotationMatcher = new AnnotationMatcher("@" + recipeDescriptor);
return Preconditions.check(new UsesType<>(recipeDescriptor, false), new JavaIsoVisitor<ExecutionContext>() {
@Override
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext ctx) {
J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, ctx);
for (J.Annotation annotation : cd.getLeadingAnnotations()) {
if (annotationMatcher.matches(annotation)) {
String name = null;
String description = null;
for (Expression argument : annotation.getArguments()) {
if (argument instanceof J.Assignment) {
J.Assignment assignment = (J.Assignment) argument;
if (assignment.getVariable() instanceof J.Identifier) {
String simpleName = ((J.Identifier) assignment.getVariable()).getSimpleName();
if ("name".equals(simpleName)) {
if (assignment.getAssignment() instanceof J.Literal) {
name = (String) ((J.Literal) assignment.getAssignment()).getValue();
}
} else if ("description".equals(simpleName)) {
if (assignment.getAssignment() instanceof J.Literal) {
description = (String) ((J.Literal) assignment.getAssignment()).getValue();
}
}
}
}
}
if (name != null && description != null) {
recipeSource.insertRow(ctx, new RewriteRecipeSource.Row(
name,
description,
RewriteRecipeSource.RecipeType.Refaster,
cd.printTrimmed(getCursor()),
"[]"
));
return SearchResult.found(cd);
}
}
}
return cd;
}
});
}

private TreeVisitor<?, ExecutionContext> findImperativeRecipes() {
MethodMatcher getDisplayName = new MethodMatcher("org.openrewrite.Recipe getDisplayName()", true);
MethodMatcher getDescription = new MethodMatcher("org.openrewrite.Recipe getDescription()", true);
AnnotationMatcher optionAnnotation = new AnnotationMatcher("@org.openrewrite.Option");
Expand Down

0 comments on commit 284e5f6

Please sign in to comment.