diff --git a/rewrite-java/src/main/java/org/openrewrite/java/AnnotationMatcher.java b/rewrite-java/src/main/java/org/openrewrite/java/AnnotationMatcher.java index e37d088fe21..dab32a09e00 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/AnnotationMatcher.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/AnnotationMatcher.java @@ -158,6 +158,7 @@ private boolean argumentValueMatches(String matchOnArgumentName, Expression arg, return false; } + //todo the problem is, that varType is null for inner Enums even fa.getType() is null JavaType.Variable varType = fa.getName().getFieldType(); if (varType != null) { JavaType.FullyQualified owner = TypeUtils.asFullyQualified(varType.getOwner()); diff --git a/rewrite-java/src/test/java/org/openrewrite/java/trait/AnnotatedTest.java b/rewrite-java/src/test/java/org/openrewrite/java/trait/AnnotatedTest.java index 4f55f333154..8e6a025d8e3 100644 --- a/rewrite-java/src/test/java/org/openrewrite/java/trait/AnnotatedTest.java +++ b/rewrite-java/src/test/java/org/openrewrite/java/trait/AnnotatedTest.java @@ -15,6 +15,7 @@ */ package org.openrewrite.java.trait; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.openrewrite.marker.SearchResult; import org.openrewrite.test.RewriteTest; @@ -24,42 +25,291 @@ class AnnotatedTest implements RewriteTest { - @Test - void attributes() { - rewriteRun( - spec -> spec.recipe(RewriteTest.toRecipe(() -> - annotated("@Example").asVisitor(a -> SearchResult.found(a.getTree(), - a.getDefaultAttribute("name") - .map(lit -> lit.getValue(String.class)) - .orElse("unknown")) - ) - )), - java( - """ - import java.lang.annotation.Repeatable; - @Repeatable - @interface Example { - String value() default ""; - String name() default ""; - } - """ - ), - java( - """ - @Example("test") - @Example(value = "test") - @Example(name = "test") - class Test { - } - """, - """ - /*~~(test)~~>*/@Example("test") - /*~~(test)~~>*/@Example(value = "test") - /*~~(test)~~>*/@Example(name = "test") - class Test { - } - """ - ) - ); + @Nested + class PrimitiveValues { + @Test + void attributes() { + rewriteRun( + spec -> spec.recipe(RewriteTest.toRecipe(() -> + annotated("@Example").asVisitor(a -> SearchResult.found(a.getTree(), + a.getDefaultAttribute("name") + .map(lit -> lit.getValue(String.class)) + .orElse("unknown")) + ) + )), + java( + """ + import java.lang.annotation.Repeatable; + @Repeatable + @interface Example { + String value() default ""; + String name() default ""; + } + """ + ), + java( + """ + @Example("test") + @Example(value = "test") + @Example(name = "test") + class Test { + } + """, + """ + /*~~(test)~~>*/@Example("test") + /*~~(test)~~>*/@Example(value = "test") + /*~~(test)~~>*/@Example(name = "test") + class Test { + } + """ + ) + ); + } + + @Test + void match() { + rewriteRun( + spec -> spec.recipe(RewriteTest.toRecipe(() -> + annotated("@Example(name=\"test\")").asVisitor(a -> SearchResult.found(a.getTree())))), + java( + """ + import java.lang.annotation.Repeatable; + @Repeatable + @interface Example { + String value() default ""; + String name() default ""; + } + """ + ), + java( + """ + @Example(name = "test") + @Example(name = "other") + class Test { + } + """, + """ + /*~~>*/@Example(name = "test") + @Example(name = "other") + class Test { + } + """ + ) + ); + } + + @Test + void withField() { + rewriteRun( + spec -> spec.recipe(RewriteTest.toRecipe(() -> + annotated("@Example(name=Test.TEST)").asVisitor(a -> SearchResult.found(a.getTree())))), + java( + """ + import java.lang.annotation.Repeatable; + @Repeatable + @interface Example { + String value() default ""; + String name() default ""; + } + """ + ), + java( + """ + @Example(name = Test.TEST) + @Example(name = "other") + class Test { + static final String TEST = "test"; + } + """, + """ + /*~~>*/@Example(name = Test.TEST) + @Example(name = "other") + class Test { + static final String TEST = "test"; + } + """ + ) + ); + } + } + + @Nested + class ClassValues { + @Test + void normalClass() { + rewriteRun( + spec -> spec.recipe(RewriteTest.toRecipe(() -> + annotated("@Example(name=FindMe.class)").asVisitor(a -> SearchResult.found(a.getTree())))), + java( + """ + import java.lang.annotation.Repeatable; + @Repeatable + @interface Example { + String value() default ""; + Class name() default ""; + } + class FindMe {} + class Other {} + """ + ), + java( + """ + @Example(name = FindMe.class) + @Example(name = Other.class) + class Test { + } + """, + """ + /*~~>*/@Example(name = FindMe.class) + @Example(name = Other.class) + class Test { + } + """ + ) + ); + } + + @Test + void innerCass() { + rewriteRun( + spec -> spec.recipe(RewriteTest.toRecipe(() -> + annotated("@Example(name=Example.FindMe.class)").asVisitor(a -> SearchResult.found(a.getTree())))), + java( + """ + import java.lang.annotation.Repeatable; + @Repeatable + @interface Example { + String value() default ""; + Class name() default ""; + class FindMe {} + class Other{} + } + """ + ), + java( + """ + @Example(name = Example.FindMe.class) + @Example(name = Example.Other.class) + class Test { + } + """, + """ + /*~~>*/@Example(name = Example.FindMe.class) + @Example(name = Example.Other.class) + class Test { + } + """ + ) + ); + } + } + + @Nested + class EnumValues { + @Test + void sameFile() { + rewriteRun( + spec -> spec.recipe(RewriteTest.toRecipe(() -> + annotated("@Example(name=Values.FindMe)") + .asVisitor(a -> SearchResult.found(a.getTree())))), + java( + """ + import java.lang.annotation.Repeatable; + @Repeatable + @interface Example { + String second() default ""; + Values name() default ""; + } + enum Values {FindMe,OTHER} + """ + ), + java( + """ + @Example(name = Values.FindMe, second="test") + @Example(name = Values.OTHER) + class Test { + } + """, + """ + /*~~>*/@Example(name = Values.FindMe, second="test") + @Example(name = Values.OTHER) + class Test { + } + """ + ) + ); + } + + @Test + void otherFile() { + rewriteRun( + spec -> spec.recipe(RewriteTest.toRecipe(() -> + annotated("@Example(name=Values.FindMe)") + .asVisitor(a -> SearchResult.found(a.getTree())))), + java( + """ + import java.lang.annotation.Repeatable; + @Repeatable + @interface Example { + String second() default ""; + Values name() default ""; + } + """ + ), + java( + """ + enum Values {FindMe,OTHER} + """ + ), + java( + """ + @Example(name = Values.FindMe, second="test") + @Example(name = Values.OTHER) + class Test { + } + """, + """ + /*~~>*/@Example(name = Values.FindMe, second="test") + @Example(name = Values.OTHER) + class Test { + } + """ + ) + ); + } + + @Test + void innerEnum() { + rewriteRun( + spec -> spec.recipe(RewriteTest.toRecipe(() -> + annotated("@Example(name=Example.Values.FindMe)") + .asVisitor(a -> SearchResult.found(a.getTree())))), + java( + """ + import java.lang.annotation.Repeatable; + @Repeatable + @interface Example { + String second() default ""; + Values name() default ""; + enum Values {FindMe,OTHER} + } + """ + ), + java( + """ + @Example(name = Example.Values.FindMe, second="test") + @Example(name = Example.Values.OTHER) + class Test { + } + """, + """ + /*~~>*/@Example(name = Example.Values.FindMe, second="test") + @Example(name = Example.Values.OTHER) + class Test { + } + """ + ) + ); + } } }