groovy
  1. groovy
  2. GROOVY-2827

org.codehaus.groovy.ast.expr.PropertyExpression when using external constants in annotations

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Duplicate
    • Affects Version/s: 1.5.6
    • Fix Version/s: None
    • Component/s: ast builder
    • Labels:
      None
    • Number of attachments :
      0

      Description

      On annotation attributes, when assigning a constant with a "." in its name (as is the case when the constant is defined in a different class than the one being compiled), groovy generates org.codehaus.groovy.ast.expr.PropertyExpression.

      See simple test case below.

      — Tag.java

      package pkg;
      
      import java.lang.annotation.Target;
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      
      
      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.METHOD,ElementType.FIELD})
      public @interface Tag {
              String value() default "";
      }
      

      — TagType.java

      package pkg;
      
      import org.apache.log4j.Logger;
      
      public class TagType {
              private final static Logger theLogger = Logger.getLogger(TagType.class);
              public static final String TAG_1 = "tag_1";
              public static final String TAG_2 = "tag_2";
      }
      

      — GroovyClassWithAnnotationsAndConstants.groovy

      package pkg;
      
      import pkg.Tag;
      import pkg.TagType
      
      class GroovyClassWithAnnotationsAndConstants {
      
              int myIntField;
      
              @Tag( value = TagType.TAG_1) // this will not compile and generate org.codehaus.groovy.ast.expr.PropertyExpression
              //@Tag( value = "tag_1") //the commented version, which uses a string literal does compile
              public int getIntField() {
                      return myIntField;
              }
      
              public void setIntField(int value) {
                      myIntField = value;
              }
      }
      

        Issue Links

          Activity

          Hide
          Guillaume Laforge added a comment -

          Additional test we could add to AnnotationTest and improve:

              void testUsingClassStaticPublicFieldsAsAnnotationParameterValue() {
                  assertScript """
                      import java.lang.annotation.*
          
                      @Retention(RetentionPolicy.RUNTIME)
                      @Target([ElementType.METHOD, ElementType.FIELD])
                      @interface Tag {
                          String value() default ""
                          String[] array() default []
                      }
          
                      class TagType {
                          public static final String TAG_ONE = "1"
                          public static final String[] TAG_TWO = ["2a", "2b"]
                      }
          
                      class GroovyClassWithAnnotationsAndConstants {
          
                          @Tag(TagType.TAG_ONE)
                          private String annotatedField
          
                          @Tag(value = TagType.TAG_ONE)
                          void annotatedMethod() { }
          
                          @Tag(array = TagType.TAG_TWO)
                          String annotatedProperty
          
                          @Tag(array = TagType.TAG_TWO)
                          int otherAnnotatedMethod(int i) { i }
          
                          @Tag(array = TagType.TAG_ONE)
                          String helloAnnotatedMethod() { "hello" }
          
                          @Tag(array = [TagType.TAG_ONE])
                          String hiAnnotatedMethod() { "hi" }
          
                          @Tag(array = [TagType.TAG_ONE, TagType.TAG_ONE])
                          String byeAnnotatedMethod() { "bye" }
                      }
          
                      assertEquals TagType.TAG_ONE, GroovyClassWithAnnotationsAndConstants.class.getDeclaredField('annotatedField').annotations[0].value()
                      // more asserts here
                  """
              }
          
          
          Show
          Guillaume Laforge added a comment - Additional test we could add to AnnotationTest and improve: void testUsingClassStaticPublicFieldsAsAnnotationParameterValue() { assertScript """ import java.lang.annotation.* @Retention(RetentionPolicy.RUNTIME) @Target([ElementType.METHOD, ElementType.FIELD]) @ interface Tag { String value() default "" String [] array() default [] } class TagType { public static final String TAG_ONE = "1" public static final String [] TAG_TWO = [ "2a" , "2b" ] } class GroovyClassWithAnnotationsAndConstants { @Tag(TagType.TAG_ONE) private String annotatedField @Tag(value = TagType.TAG_ONE) void annotatedMethod() { } @Tag(array = TagType.TAG_TWO) String annotatedProperty @Tag(array = TagType.TAG_TWO) int otherAnnotatedMethod( int i) { i } @Tag(array = TagType.TAG_ONE) String helloAnnotatedMethod() { "hello" } @Tag(array = [TagType.TAG_ONE]) String hiAnnotatedMethod() { "hi" } @Tag(array = [TagType.TAG_ONE, TagType.TAG_ONE]) String byeAnnotatedMethod() { "bye" } } assertEquals TagType.TAG_ONE, GroovyClassWithAnnotationsAndConstants.class.getDeclaredField('annotatedField').annotations[0].value() // more asserts here """ }
          Hide
          Paul King added a comment -

          Checked into it further and this is indeed a duplicate of GROOVY-3278. Other notes in that issue.

          Show
          Paul King added a comment - Checked into it further and this is indeed a duplicate of GROOVY-3278 . Other notes in that issue.

            People

            • Assignee:
              Guillaume Laforge
              Reporter:
              Xavier Sautejeau
            • Votes:
              1 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: