Tweaking the language model API for repeating annotations
Joseph Darcy
joe.darcy at oracle.com
Thu Dec 6 17:22:49 PST 2012
Hello,
On 12/5/2012 2:46 PM, Alex Buckley wrote:
> We discovered two small issues with section 1.3 of the spec:
>
>
> 1. The spec proposes a new method, Element.getAnnotations().
>
> This method is proposed for consistency with
> AnnotatedElement.getAnnotations(), but it turns out to be difficult to
> implement in the context of the language model. The problem is that,
> at compile-time, there might not be instances of Class objects for the
> annotations we try to look at. The other new methods -
> Element.getAnnotation[s](Class<T>) - do not have this issue since
> their callers must supply a Class object.
>
> It would be possible for Element.getAnnotations() to throw exceptions
> if necessary Class objects were not found, but there is no good
> unchecked exception type available in the language model API. It would
> also be possible to skip over annotations for which Class objects are
> unavailable, and return incomplete results, but this seems undesirable.
>
> I propose to drop the method. Essentially, it's fine in core
> reflection but too brittle for the language model.
I vaguely recall that during JSR 269 we didn't provide the
getAnnotations() method on javax.lang.model.element to avoid the
problems of potentially missing Class objects so I agree we can drop
this from the model API.
>
>
> 2. The spec proposes to refine Element.getAnnotationMirrors() and
> Elements.getAllAnnotationMirrors().
>
> If the language model API only has a class file available for the
> element on which annotation mirrors are requested, then the API cannot
> be sure that it's right to "look through" @FooContainer (if directly
> present on the element) and return @Foo mirrors.
>
> This is true even if FooContainer is a well-formed containing
> annotation type available to the API. The source code of the element -
> which the API strives to reflect - could literally have said
> @FooContainer(...). Unfortunately, a compiler has no way to mark a
> container annotation as "synthesized" during class file generation.
>
> It would be possible to adopt a policy of always looking through
> container annotations on an element. This requires the language model
> API to recognize container annotations, which in turn requires loading
> the annotation's class file, which might not always be available.
>
> I propose to adopt this policy, while allowing the methods to
> sometimes expose container annotations even if not present in source
> code.
>
>
There are existing cases where the answered returned by the language
model depends on whether the "backing store" for the type is a source
file or a class file:
> However, the process of translating source code to executable output
> may not permit recovering some aspects of the source code
> representation. For example, annotations with source
> <http://download.java.net/jdk8/docs/api/java/lang/annotation/RetentionPolicy.html#SOURCE>
> retention
> <http://download.java.net/jdk8/docs/api/java/lang/annotation/Retention.html>
> cannot be recovered from class files and class files might not be able
> to provide source position information. The modifiers
> <http://download.java.net/jdk8/docs/api/javax/lang/model/element/Modifier.html>
> on an element may differ in some cases including
>
> * |strictfp| on a class or interface
> * |final| on a parameter
> * |protected|, |private|, and |static| on classes and interfaces
>
> Additionally, synthetic constructs in a class file, such as accessor
> methods used in implementing nested classes and bridge methods used in
> implementing covariant returns, are translation artifacts outside of
> this model.
http://download.java.net/jdk8/docs/api/javax/lang/model/element/package-summary.html
So we might judge it acceptable to get different answers to the question
of what annotation mirrors are present depending on source vs class file
backing store.
-Joe
More information about the enhanced-metadata-spec-discuss
mailing list