Request for revised terminology describing ways annotations can be present or not

michael keith michael.keith at oracle.com
Tue Apr 2 10:14:58 PDT 2013


Hi Joe,

Thanks for working on the compatibility part of the annotation 
processing part and bringing this up.
The compatibility story sounds great to me. Current processors will 
continue to work just as they are.

I was wondering about new processors, though. I might have 
misunderstood, but just so that I am clear, are the following statements 
true, given Foo and FooContainer?

a) The processor will need to list both Foo and FooContainer in the set 
of Supported Annotation Types

b) During discovery, look-through will not occur and the set of 
annotations passed into the process() method will include FooContainer 
if an element was multiply annotated with @Foo

c) There will be no look-through performed by 
RoundEnvironment.getElementsAnnotatedWith(Foo.class). No additional 
methods will be added to RoundEnvironment?

d) A processor may invoke getAnnotationsByType(Foo.class) on the 
Elements returned from getElementsAnnotatedWith(FooContainer.class) and 
look-through will occur

If these statements are true then is there any plan for new processors 
to be able to benefit from look-through? I guess I was expecting that 
there might be a new SupportedOption or some such thing, with a 
getElementsAnnotatedByTypeWith() method, to support look-through just so 
that new processors did not need to handle container annotations. It 
would be an easy thing to add in a subsequent release, I suppose, if no 
such support is planned for this release. (I mean easy to define in a 
backward compatible way, not necessarily that it would be easy to 
implement ;-)

-Mike

P.S. In case it is not already caught, there is a typo in the added 
language below that makes it a little weird to read:
     represent -> present

On 28/03/2013 9:20 PM, Joe Darcy wrote:
> Hello,
>
> To provide some context, here is an excerpt from the 
> javax.annotation.processing.Processor interfaces which describes part 
> of the tool <-> processor protocol:
>
> "The tool uses a discovery process to find annotation processors and 
> decide whether or not they should be run. [...] Which processors the 
> tool asks to run is a function of what annotations are present on the 
> root elements, what annotation types a processor processes, and 
> whether or not a processor claims the annotations it processes. [...] 
> For a given round, the tool computes the set of annotation types on 
> the root elements. If there is at least one annotation type present, 
> as processors claim annotation types, they are removed from the set of 
> unmatched annotations."
>
> To this, I will add a paragraph explaining how repeating annotations 
> affect this discovery process.
>
> "<p>An annotation type is considered present if there is at least one
> annotation of that type on a declaration enclosed within the root
> elements of a round. For this purpose, a type parameter is considered
> to be enclosed by its generic element. Annotations on type uses are
> <em>not</em> considered as part of the computation.
>
> An annotation is <em>present</em> on a declaration if it is present as
> defined in {@link AnnotatedConstruct}. That is, the annotation may be
> directly present or present via inheritance. An annotation indirectly
> present by virtue of a repeatable annotation type is <em>not</em>
> considered represent for the purposes of the discovery process.
>
> Therefore, to properly process repeatable annotation types, processors
> are advised to include both the annotation and its container in the
> set of {@linkplain #getSupportedAnnotationTypes() supported annotation
> types}."
>
> Thanks,
>
> -Joe
>
>
> On 03/26/2013 08:09 PM, Alex Buckley wrote:
>> On 3/26/2013 4:10 PM, Joe Darcy wrote:
>>> In brief, and processing API requires that the set of annotations
>>> present on a body of code be computed. To preserve behavioral
>>> compatibility, "present" in this context means directly present in the
>>> source code or class file representation of a declaration or present 
>>> via
>>> inheritance. Container look-through should *not* be considered.
>>>
>>> I was hoping to describe this arrangement using the "directly present"
>>> and "present" terminology from java.lang.reflect.AnnotatedElement or
>>> javax.lang.model.AnnotatedConstruct. Unfortunately, those terms allow
>>> look though to occur based on which method is being called.
>>>
>>> So what I'd like to have is a set of definition in the
>>> AnnotatedElement/AnnotatedConstruct types which support the following
>>> distinctions:
>>>
>>> 1) directly present (no inheritance, no container look through)
>>> 2) present directly or present indirectly via inheritance
>>> 3) present directly or present indirectly via container look through
>>> 4) present directly or via the supported interaction of inheritance and
>>> look through
>>
>> The building blocks are easy:
>>
>> a) An annotation A is DIRECTLY PRESENT on an element E if E is 
>> associated with a RuntimeVisibleAnnotations or 
>> RuntimeVisibleParameterAnnotations attribute, and the attribute 
>> contains A.
>>
>> b) An annotation A is INDIRECTLY PRESENT on an element E if E is 
>> associated with a RuntimeVisibleAnnotations or 
>> RuntimeVisibleParameterAnnotations attribute, and A's type is 
>> repeatable, and E contains exactly one annotation whose value element 
>> contains A and whose type is the containing annotation type of A's 
>> type (§9.6).
>>
>> The trouble is PRESENT. If it's an SE7-era PRESENT - aware of 
>> inheritance but not containment - then it's very hard to find a term 
>> for an SE8-era PRESENT which knows both inheritance and containment. 
>> Still, let's start with an SE7-era PRESENT and see what happens:
>>
>> c) An annotation A is PRESENT on an element E if either:
>> - A is DIRECTLY PRESENT on E; or
>> - No annotation of A's type is DIRECTLY PRESENT on E, and E is a 
>> class, and A's type is inheritable (§9.6.3.3), and A is PRESENT on 
>> the superclass of E.
>>
>> The javadoc for getDeclaredAnnotationsByType(Class) can simply say:
>>
>> "Returns the annotations which are directly or indirectly present on 
>> this element."
>>
>> The javadoc for getAnnotationsByType(Class) will have to embody a 
>> recursive-lookup-with-overriding policy:
>>
>> "Returns the annotations which are directly or indirectly present on 
>> this element. If there are none, then if this element is a class, 
>> returns the annotations of inheritable type which are returned by an 
>> invocation of getAnnotationsByType(Class) on the superclass of this 
>> element."
>>
>> Yuk. This operational description is patterned after (c)'s definition 
>> of PRESENT, but you'd never guess that. I'm going to bite the bullet 
>> and introduce a new term:
>>
>> d) An annotation A is ASSOCIATED with an element E if either:
>> - A is DIRECTLY OR INDIRECTLY PRESENT on E; or
>> - No annotation of A's type is DIRECTLY OR INDIRECTLY PRESENT on E, 
>> and E is a class, and A's type is inheritable (§9.6.3.3), and A is 
>> ASSOCIATED with the superclass of E.
>>
>> The similarity of PRESENT and ASSOCIATED is clear. 
>> getAnnotationsByType(Class) is just:
>>
>> "Returns the annotations which are associated with this element."
>>
>> If that sounds OK, I'll modify the spec PDF and file a bug to change 
>> the core reflection and language model javadocs. No changes should be 
>> needed in any method implementation.
>>
>> Alex
>




More information about the enhanced-metadata-spec-discuss mailing list