Draft specification of repeating annotations language changes

Joe Darcy joe.darcy at oracle.com
Sun Mar 11 15:19:21 PDT 2012


Hello,

Work has commenced on the repeating annotations feature discussed in JEP 
120:

     JEP 120: Repeating Annotations
     http://openjdk.java.net/jeps/120

First, the meta-annotation type used to declare the containing 
annotation has been added to java.lang.annotation:

     7151008: Add library support for repeating annotations in 
java.lang.annotation
     http://hg.openjdk.java.net/jdk8/tl/jdk/rev/99b91217370d

Updates to the AnnotatedElement interface will be made later.

Next, with feedback from other members of the compiler team, I've 
written a draft specification of the needed language changes:

Updates to JLS 9.6

If annotation type T is annotated with an annotation a of type 
ContainerAnnotation then:

The value of the @ContainerAnnotation annotation is called the 
containing annotation type TC.

TC must declare a value() method whose return type is T[], or a 
compile-time error occurs.

(This implies that TC can be the containing annotation type for only a 
single annotation type.)

[Note: Since an annotation type T cannot declare a method that returns T 
or T[] as a value, that implies that it is a compile time error for an 
annotation type to specify itself as a container annotation type.]

TC may declare methods other than value(). Any such method must have a 
default clause, or a compile-time errors occurs.

[Note: this is a bit weird "action at a distance" in terms of compiler 
errors   The error message here is given at the site of the T since the 
containing annotation might only be present as a class file.]

It is a compile time error if the retention of T is not a subset of the 
retention of TC.  This comparison is made taking default retention into 
consideration.

    In more detail, if the retention of the TC is SOURCE, the retention 
of T must be SOURCE.
    If the retention of TC is CLASS, the retention of the T may be 
either CLASS or SOURCE.
   if the retention of the TC is RUNTIME, the retention of the T may be 
SOURCE, CLASS, or RUNTIME.

It is a compile time error if T is @Documented and TC is not @Documented.

[Note that it is permissible TC to be @Documented and for T to *not* be 
@Documented.]

It is a compile time error if T is @Inherited and TC is not @Inherited.

[Note that it is permissible TC to be @Inherited and for T to *not* be 
@Inherited.]

It is a compile time error if T has target values that are not included 
in the target set of TC, taking default target values into account.

Note that an annotation type TC may be a container type for annotation 
type T while also having its own container type TCC.

[However, two annotation types cannot be containers for each other 
because that would create an illegal cyclic annotation type situation.  
For example, the following program is rejected by javac:

public @interface Mutual {
     Omaha[] value() default {};
}

@interface Omaha {
     Mutual[] value() default {};
}

@Mutual({@Omaha, @Omaha})
@Omaha({@Mutual, @Mutual})
class Foo {
}

with the message

Mutual.java:2: error: cyclic annotation element type
     Omaha[] value() default {};
             ^
1 error ]

Updates to JLS 9.7

"It is a compile-time error if a declaration is annotated with more than 
one annotation for a given annotation type."

Change to "unless the annotation type is annotated with an 
@ContainerAnnotation."

Annotation types with an @ContainerAnnotation are known as repeatable 
annotation types.  The presence of an @ContainerAnnotation indicates 
multiple annotations of that annotation type will be logically replaced 
with a single annotation synthesized by the compiler.  The type of the 
synthesized annotation, TC, is the type given by the value of the 
ContainerAnnotation annotation on T. The order of the elements of the 
value() method of the synthesized TC annotation matches the left to 
right order of the base repeatable annotations.

If an element only has a single repeatable annotation, the annotation is 
not replaced.

It is conventional to place the repeatable annotations of a given type 
contiguously on an element, but this is not required.

It is a compile time error if an element is annotated with both multiple 
base annotations of a repeatable annotation type T and one or more 
annotations of the containing type TC.

[In other words, the collapsing of repeatable annotations to their 
containers is *not* recursive.]

Cheers,

-Joe




More information about the compiler-dev mailing list