Skip to content

Commit

Permalink
Allow JavaTemplate to replace J.FieldAccess in annotation
Browse files Browse the repository at this point in the history
`JavaTemplate` can now also replace a `J.FieldAccess` which is used as an argument to an annotation parameter. In any case this currently works when the annotation is declared on a class or a method. More work is required to also make this work as expected in other locations.

Fixes: openrewrite#3154
  • Loading branch information
knutwannheden committed Apr 24, 2023
1 parent 1afee4c commit 454f2e7
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,45 @@ public void defaults(RecipeSpec spec) {
.classpath("guava"));
}

@Test
void replaceConstantInAnnotation() {
rewriteRun(
spec -> spec.recipe(new ReplaceConstantWithAnotherConstant("com.google.common.base.Charsets.UTF_8", "com.constant.B.UTF_8")),
java(
"""
package com.constant;
public class B {
public static final String UTF_8 = "UTF_8";
}
"""
),
java(
"""
import com.google.common.base.Charsets;
@SuppressWarnings(Charsets.UTF_8)
class Test {
@SuppressWarnings(value = Charsets.UTF_8)
void foo() {
System.out.println("Annotation");
}
}
""",
"""
import com.constant.B;
@SuppressWarnings(B.UTF_8)
class Test {
@SuppressWarnings(value = B.UTF_8)
void foo() {
System.out.println("Annotation");
}
}
"""
)
);
}

@Test
void replaceConstant() {
rewriteRun(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,28 @@ private void template(Cursor cursor, J prior, StringBuilder before, StringBuilde
after.append(';');
}
after.append('}');
} else if (j instanceof J.Annotation) {
J.Annotation annotation = (J.Annotation) j;
Optional<Expression> arg = annotation.getArguments().stream().filter(a -> a == prior).findFirst();
if (arg.isPresent()) {
StringBuilder beforeBuffer = new StringBuilder();
beforeBuffer.append('@').append(((JavaType.Class) annotation.getType()).getFullyQualifiedName()).append('(');
before.insert(0, beforeBuffer);
after.append(')').append('\n');

J parent = next(cursor).getValue();
if (parent instanceof J.ClassDeclaration) {
J.ClassDeclaration cd = (J.ClassDeclaration) parent;
after.append(cd.withBody(null).withLeadingAnnotations(null).withPrefix(Space.EMPTY).printTrimmed(cursor).trim()).append("{}");
} else if (parent instanceof J.MethodDeclaration) {
J.MethodDeclaration md = (J.MethodDeclaration) parent;
after.append(md.withBody(null)
.withLeadingAnnotations(emptyList())
.withPrefix(Space.EMPTY)
.printTrimmed(cursor).trim()).append("{}");
}
// TODO cover more cases where annotations can appear, ideally not by "inlining" template for parent
}
} else if (j instanceof J.DoWhileLoop) {
J.DoWhileLoop dw = (J.DoWhileLoop) j;
if (referToSameElement(prior, dw.getWhileCondition())) {
Expand Down

0 comments on commit 454f2e7

Please sign in to comment.