1616package org .openrewrite .java ;
1717
1818import org .intellij .lang .annotations .Language ;
19+ import org .junit .jupiter .api .Nested ;
1920import org .junit .jupiter .api .Test ;
2021import org .openrewrite .DocumentExample ;
2122import org .openrewrite .ExecutionContext ;
2223import org .openrewrite .Issue ;
24+ import org .openrewrite .Recipe ;
2325import org .openrewrite .java .tree .J ;
2426import org .openrewrite .test .RewriteTest ;
2527
@@ -161,10 +163,10 @@ public record Person(
161163 }
162164
163165 @ Issue ("https://github.com/openrewrite/rewrite/issues/5712" )
164- @ Test
165- void replaceArgumentsInNestedAnnotation () {
166+ @ Nested
167+ class NestedAnnotations {
166168 @ Language ("java" )
167- String annotations = """
169+ private final String annotations = """
168170 package foo;
169171
170172 import java.lang.annotation.*;
@@ -179,55 +181,313 @@ void replaceArgumentsInNestedAnnotation() {
179181 NestedAnnotation[] value();
180182 }
181183 """ ;
182- rewriteRun (
183- spec -> spec
184- .parser (JavaParser .fromJavaVersion ().dependsOn (annotations ))
185- .recipe (toRecipe (() -> new JavaIsoVisitor <>() {
186- @ Override
187- public J .Annotation visitAnnotation (J .Annotation annotation , ExecutionContext ctx ) {
188- if (annotation .getSimpleName ().equals ("NestedAnnotation" ) &&
189- !annotation .getArguments ().isEmpty ()) {
190- // Check if this annotation still has the 'a' attribute that needs to be replaced
191- J .Assignment arg = (J .Assignment ) annotation .getArguments ().get (0 );
192- if (arg .getVariable () instanceof J .Identifier &&
193- ((J .Identifier ) arg .getVariable ()).getSimpleName ().equals ("a" )) {
194- // Only apply the template if we haven't already transformed this annotation
195- J .Literal value = (J .Literal ) arg .getAssignment ();
196-
197- // Replace 'a' with 'b' in the annotation
198- return JavaTemplate .builder ("@NestedAnnotation(b = #{any(java.lang.String)})" )
199- .javaParser (JavaParser .fromJavaVersion ().dependsOn (annotations ))
200- .imports ("foo.*" )
201- .build ()
202- .apply (getCursor (), annotation .getCoordinates ().replace (), value );
203- }
184+
185+ private final Recipe recipe = toRecipe (() -> new JavaIsoVisitor <>() {
186+ @ Override
187+ public J .Annotation visitAnnotation (J .Annotation annotation , ExecutionContext ctx ) {
188+ if (annotation .getSimpleName ().equals ("NestedAnnotation" ) &&
189+ !annotation .getArguments ().isEmpty ()) {
190+ // Check if this annotation still has the 'a' attribute that needs to be replaced
191+ J .Assignment arg = (J .Assignment ) annotation .getArguments ().get (0 );
192+ if (arg .getVariable () instanceof J .Identifier &&
193+ ((J .Identifier ) arg .getVariable ()).getSimpleName ().equals ("a" )) {
194+ // Only apply the template if we haven't already transformed this annotation
195+ J .Literal value = (J .Literal ) arg .getAssignment ();
196+
197+ // Replace 'a' with 'b' in the annotation
198+ return JavaTemplate .builder ("@NestedAnnotation(b = #{any(java.lang.String)})" )
199+ .javaParser (JavaParser .fromJavaVersion ().dependsOn (annotations ))
200+ .imports ("foo.*" )
201+ .build ()
202+ .apply (getCursor (), annotation .getCoordinates ().replace (), value );
204203 }
205- return super .visitAnnotation (annotation , ctx );
206204 }
207- })),
208- java (
209- """
210- import foo.*;
205+ return super .visitAnnotation (annotation , ctx );
206+ }
207+ });
211208
212- @NestedAnnotations({
213- @NestedAnnotation(a = "1"),
214- @NestedAnnotation(a = "2")
215- })
216- class Test {
217- }
218- """ ,
219- """
220- import foo.*;
209+ @ Test
210+ void replaceWhenFieldAnnotatedNoIdentifier () {
211+ rewriteRun (
212+ spec -> spec
213+ .parser (JavaParser .fromJavaVersion ().dependsOn (annotations ))
214+ .recipe (recipe ),
215+ //language=java
216+ java (
217+ """
218+ import foo.*;
219+
220+ class A {
221+ @NestedAnnotations({
222+ @NestedAnnotation(a = "first"),
223+ @NestedAnnotation(a = "second")
224+ })
225+ String field;
226+ void method() {}
227+ }
228+ """ ,
229+ """
230+ import foo.*;
231+
232+ class A {
233+ @NestedAnnotations({
234+ @NestedAnnotation(b = "first"),
235+ @NestedAnnotation(b = "second")
236+ })
237+ String field;
238+ void method() {}
239+ }
240+ """
241+ )
242+ );
243+ }
221244
222- @NestedAnnotations({
223- @NestedAnnotation(b = "1"),
224- @NestedAnnotation(b = "2")
225- })
226- class Test {
227- }
228- """
229- )
230- );
231- }
245+ @ Test
246+ void replaceWhenFieldAnnotatedWithIdentifier () {
247+ rewriteRun (
248+ spec -> spec
249+ .parser (JavaParser .fromJavaVersion ().dependsOn (annotations ))
250+ .recipe (recipe ),
251+ //language=java
252+ java (
253+ """
254+ import foo.*;
255+
256+ class A {
257+ @NestedAnnotations(value = {
258+ @NestedAnnotation(a = "first"),
259+ @NestedAnnotation(a = "second")
260+ })
261+ String field;
262+ void method() {}
263+ }
264+ """ ,
265+ """
266+ import foo.*;
267+
268+ class A {
269+ @NestedAnnotations(value = {
270+ @NestedAnnotation(b = "first"),
271+ @NestedAnnotation(b = "second")
272+ })
273+ String field;
274+ void method() {}
275+ }
276+ """
277+ )
278+ );
279+ }
232280
281+ @ Test
282+ void replaceWhenMethodAnnotatedNoIdentifier () {
283+ rewriteRun (
284+ spec -> spec
285+ .parser (JavaParser .fromJavaVersion ().dependsOn (annotations ))
286+ .recipe (recipe ),
287+ //language=java
288+ java (
289+ """
290+ import foo.*;
291+
292+ class A {
293+ @NestedAnnotations({
294+ @NestedAnnotation(a = "first"),
295+ @NestedAnnotation(a = "second")
296+ })
297+ void method() {}
298+ }
299+ """ ,
300+ """
301+ import foo.*;
302+
303+ class A {
304+ @NestedAnnotations({
305+ @NestedAnnotation(b = "first"),
306+ @NestedAnnotation(b = "second")
307+ })
308+ void method() {}
309+ }
310+ """
311+ )
312+ );
313+ }
314+
315+ @ Test
316+ void replaceWhenMethodAnnotatedWithIdentifier () {
317+ rewriteRun (
318+ spec -> spec
319+ .parser (JavaParser .fromJavaVersion ().dependsOn (annotations ))
320+ .recipe (recipe ),
321+ //language=java
322+ java (
323+ """
324+ import foo.*;
325+
326+ class A {
327+ @NestedAnnotations(value = {
328+ @NestedAnnotation(a = "first"),
329+ @NestedAnnotation(a = "second")
330+ })
331+ void method() {}
332+ }
333+ """ ,
334+ """
335+ import foo.*;
336+
337+ class A {
338+ @NestedAnnotations(value = {
339+ @NestedAnnotation(b = "first"),
340+ @NestedAnnotation(b = "second")
341+ })
342+ void method() {}
343+ }
344+ """
345+ )
346+ );
347+ }
348+
349+ @ Test
350+ void replaceWhenOuterClassAnnotatedNoIdentifier () {
351+ rewriteRun (
352+ spec -> spec
353+ .parser (JavaParser .fromJavaVersion ().dependsOn (annotations ))
354+ .recipe (recipe ),
355+ //language=java
356+ java (
357+ """
358+ import foo.*;
359+
360+ @NestedAnnotations({
361+ @NestedAnnotation(a = "first"),
362+ @NestedAnnotation(a = "second")
363+ })
364+ class A {
365+ void method() {}
366+ }
367+ """ ,
368+ """
369+ import foo.*;
370+
371+ @NestedAnnotations({
372+ @NestedAnnotation(b = "first"),
373+ @NestedAnnotation(b = "second")
374+ })
375+ class A {
376+ void method() {}
377+ }
378+ """
379+ )
380+ );
381+ }
382+
383+ @ Test
384+ void replaceWhenOuterClassAnnotatedWithIdentifier () {
385+ rewriteRun (
386+ spec -> spec
387+ .parser (JavaParser .fromJavaVersion ().dependsOn (annotations ))
388+ .recipe (recipe ),
389+ //language=java
390+ java (
391+ """
392+ import foo.*;
393+
394+ @NestedAnnotations(value = {
395+ @NestedAnnotation(a = "first"),
396+ @NestedAnnotation(a = "second")
397+ })
398+ class A {
399+ void method() {}
400+ }
401+ """ ,
402+ """
403+ import foo.*;
404+
405+ @NestedAnnotations(value = {
406+ @NestedAnnotation(b = "first"),
407+ @NestedAnnotation(b = "second")
408+ })
409+ class A {
410+ void method() {}
411+ }
412+ """
413+ )
414+ );
415+ }
416+
417+ @ Test
418+ void replaceWhenInnerClassAnnotatedNoIdentifier () {
419+ rewriteRun (
420+ spec -> spec
421+ .parser (JavaParser .fromJavaVersion ().dependsOn (annotations ))
422+ .recipe (recipe ),
423+ //language=java
424+ java (
425+ """
426+ import foo.*;
427+
428+ class A {
429+ @NestedAnnotations({
430+ @NestedAnnotation(a = "first"),
431+ @NestedAnnotation(a = "second")
432+ })
433+ class B {
434+ void method() {}
435+ }
436+ }
437+ """ ,
438+ """
439+ import foo.*;
440+
441+ class A {
442+ @NestedAnnotations({
443+ @NestedAnnotation(b = "first"),
444+ @NestedAnnotation(b = "second")
445+ })
446+ class B {
447+ void method() {}
448+ }
449+ }
450+ """
451+ )
452+ );
453+ }
454+
455+ @ Test
456+ void replaceWhenInnerClassAnnotatedWithIdentifier () {
457+ rewriteRun (
458+ spec -> spec
459+ .parser (JavaParser .fromJavaVersion ().dependsOn (annotations ))
460+ .recipe (recipe ),
461+ //language=java
462+ java (
463+ """
464+ import foo.*;
465+
466+ class A {
467+ @NestedAnnotations(value = {
468+ @NestedAnnotation(a = "first"),
469+ @NestedAnnotation(a = "second")
470+ })
471+ class B {
472+ void method() {}
473+ }
474+ }
475+ """ ,
476+ """
477+ import foo.*;
478+
479+ class A {
480+ @NestedAnnotations(value = {
481+ @NestedAnnotation(b = "first"),
482+ @NestedAnnotation(b = "second")
483+ })
484+ class B {
485+ void method() {}
486+ }
487+ }
488+ """
489+ )
490+ );
491+ }
492+ }
233493}
0 commit comments