Request for revised terminology describing ways annotations can be present or not
Joe Darcy
joe.darcy at oracle.com
Tue Apr 2 12:03:47 PDT 2013
Hi Mike,
On 04/02/2013 10:14 AM, michael keith wrote:
> 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.
That is the intention :-)
>
> 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
Correct.
>
> 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
Yes.
>
> c) There will be no look-through performed by
> RoundEnvironment.getElementsAnnotatedWith(Foo.class). No additional
> methods will be added to RoundEnvironment?
I hadn't planned to add methods to RoundEnvironment that did look
through, but it is technically possible. Do you find the round
environment methods to be heavily used?
>
> d) A processor may invoke getAnnotationsByType(Foo.class) on the
> Elements returned from getElementsAnnotatedWith(FooContainer.class)
> and look-through will occur
Yes; the getAnnotationsByType method will perform look through on any
element it is called on.
>
> 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 ;-)
Hmm. I hadn't planned for anything here, but I'll keep that in mind. As
you suggest, the AbstractProcessor.getSupportedAnnotationTypes method
could be enhanced in various ways to make handling the base annotation
and its container more convenient:
* New annotation type defined -- SupportedBaseAnnotationType -- which
would cover the base annotation and its container.
* Augmenting the grammar in SupportedAnnotationType to indicate an
annotation and its container, if any, should be covered
Things like this are not terribly hard to add, but I suspect they would
introduce a disproportionate number of conditions to check. If the base
annotations and its container are typically in the same package, the
existing "foo.bar.*" notation would allow both annotations to be
specified in one go. Given that, my inclination is to not add any
additional support for container annotations to the discovery part of
the API.
Thanks,
-Joe
>
> -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
I'll make sure to fix that :-)
>
> 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