JDK 9 request for specification changes of JDK-8032230: Enhance javax.a.p.RoundEnvironment after repeating annotations
joe darcy
joe.darcy at oracle.com
Wed May 18 21:02:03 UTC 2016
Combining suggestions, two methods
default Set<? extends Element>
getElementsAnnotatedWithAny(TypeElement... annotations)
default Set<? extends Element>
getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> annotations)
No varargs in the second case because of heap pollution with the
wildcarded Class type and the inability to use @SafeVarargs on this
method since it can be overridden.
I'd prefer a set of methods like the above that weren't only tied to
repeating annotations since I think there are other use cases where it
is helpful to find more than one annotation at a time.
Fuller diff below.
Thanks,
-Joe
/**
+ * Returns the elements annotated with one or more of the given
+ * annotation types.
+ *
+ * @apiNote This method may be useful when processing repeating
+ * annotations by looking for an annotation type and its
+ * containing annotation type at the same time.
+ *
+ * @implSpec The default implementation of this method creates an
+ * empty result set, iterates over the annotations in the argument
+ * set calling {@link #getElementsAnnotatedWith(TypeElement)} on
+ * each annotation and adding those results to the result
+ * set. Finally, the contents of the result set are returned as an
+ * unmodifiable set.
+ *
+ * @param annotations annotation types being requested
+ * @return the elements annotated with one or more of the given
+ * annotation types, or an empty set if there are none
+ * @throws IllegalArgumentException if the any elements of the
+ * argument set do not represent an annotation type
+ * @since 9
+ */
+ default Set<? extends Element>
getElementsAnnotatedWithAny(TypeElement... annotations){
+ HashSet<Element> result = new HashSet<>();
+ for (TypeElement annotation : annotations) {
+ result.addAll(getElementsAnnotatedWith(annotation));
+ }
+ return Collections.unmodifiableSet(result);
+ }
+ /**
+ * Returns the elements annotated with one or more of the given
+ * annotation types.
+ *
+ * @apiNote This method may be useful when processing repeating
+ * annotations by looking for an annotation type and its
+ * containing annotation type at the same time.
+ *
+ * @implSpec The default implementation of this method creates an
+ * empty result set, iterates over the annotations in the argument
+ * set calling {@link #getElementsAnnotatedWith(Class)} on
+ * each annotation and adding those results to the result
+ * set. Finally, the contents of the result set are returned as an
+ * unmodifiable set.
+ *
+ * @param annotations annotation types being requested
+ * @return the elements annotated with one or more of the given
+ * annotation types, or an empty set if there are none
+ * @throws IllegalArgumentException if the any elements of the
+ * argument set do not represent an annotation type
+ * @since 9
+ */
+ default Set<? extends Element>
getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> annotations){
+ HashSet<Element> result = new HashSet<>();
+ for (Class<? extends Annotation> annotation : annotations) {
+ result.addAll(getElementsAnnotatedWith(annotation));
+ }
+ return Collections.unmodifiableSet(result);
+ }
On 5/18/2016 1:55 PM, Jonathan Gibbons wrote:
> Jan,
>
> You're getting very close to suggesting a method that takes a
> predicate, and we could provide a variety of predicates for (anyOf,
> allOf) x (Annotation, AnnotationMirror) x (varags, collection)
>
> -- Jon
>
> On 05/18/2016 01:48 PM, Jan Lahoda wrote:
>> On 18.5.2016 22:26, joe darcy wrote:
>>> Hi Jon,
>>>
>>> On 5/18/2016 1:05 PM, Jonathan Gibbons wrote:
>>>> It's sad to see the preference given to the more intellectually
>>>> suspect of the two possibilities.
>>>
>>> Agreed, sad but pragmatic.
>>
>> Would it make sense to use varargs instead of a Set? If we assume the
>> typical use will be something like:
>> round.getElementsAnnotatedWithAny(annotation, containerAnnotation)
>>
>> it might be more convenient to have the method take a vararg than a
>> Set (and would avoid the problem with the erasure clash as another
>> benefit).
>>
>> Jan
>>
>>>
>>>>
>>>> It would be nice to see the nice name given to the intellectually
>>>> superior of the possibilities (i.e AnnotationMirror) and then figure
>>>> out how to deal with the other case.
>>>
>>> How about the name "getElementsAnnotatedWithAny" for both variations?
>>> That potentially avoids confusion over whether or not the elements have
>>> to be modified with any of the annotations or all of them.
>>>
>>>>
>>>> As well as the possibility of another method name, have you ever
>>>> considered the possibility of conversion functions of
>>>> Elements/Types/<something-new> that can convert between (collection
>>>> of) Annotation and (collection of) AnnotationMirror?
>>>
>>> Internally, for the existing methods javac does convert the Class-based
>>> version to the TypeElement based version, but I don't think we want the
>>> specification to require that.
>>>
>>> Thanks,
>>>
>>> -Joe
>>>
>>>>
>>>> -- Jon
>>>>
>>>> On 05/18/2016 12:55 PM, joe darcy wrote:
>>>>> Hello,
>>>>>
>>>>> Please review the patch below which proposes a new method to address
>>>>>
>>>>> JDK-8032230: Enhance javax.a.p.RoundEnvironment after repeating
>>>>> annotations
>>>>>
>>>>> At present, this is just a review of the specification of the default
>>>>> method in the interface and *not* a more optimized implementation in
>>>>> the javac RoundEnvironemnt implementation (and not any tests that
>>>>> would be needed for the new functionality).
>>>>>
>>>>> Note that the bug proposes adding two methods
>>>>>
>>>>> RoundEnvironment.getElementsAnnotatedWith(Set<Class<? extends
>>>>> Annotation>> s)
>>>>> RoundEnvironment.getElementsAnnotatedWith(Set<AnnotationMirror> s)
>>>>>
>>>>> but these methods would clash since their erasure is the same. *sad
>>>>> tromphone*
>>>>>
>>>>> Therefore, I'm only proposing to add the Class-based variant since
>>>>> that one is the more commonly used of the two.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> -Joe
>>>>>
>>>>>
>>>>> + /**
>>>>> + * Returns the elements annotated with any of the given
>>>>> annotation
>>>>> + * types.
>>>>> + *
>>>>> + * @apiNote This method may be useful when processing repeating
>>>>> + * annotations by looking for an annotation type and its
>>>>> + * containing annotation type at the same time.
>>>>> + *
>>>>> + * @implSpec The default implementation of this method
>>>>> creates an
>>>>> + * empty result set, iterates over the annotations in the
>>>>> argument
>>>>> + * set calling {@link #getElementsAnnotatedWith(TypeElement)} on
>>>>> + * each annotation and adding those results to the result
>>>>> + * set. Finally, the contents of the result set are returned
>>>>> as an
>>>>> + * unmodifiable set.
>>>>> + *
>>>>> + * @param annotations annotation type being requested
>>>>> + * @return the elements annotated with the given annotation
>>>>> types,
>>>>> + * or an empty set if there are none
>>>>> + * @throws IllegalArgumentException if the any elements of the
>>>>> + * argument set do not represent an annotation type
>>>>> + * @since 9
>>>>> + */
>>>>> + default Set<? extends Element>
>>>>> getElementsAnnotatedWith(Set<Class<? extends Annotation>>
>>>>> annotations){
>>>>> + HashSet<Element> result = new HashSet<>();
>>>>> + for (Class<? extends Annotation> annotation : annotations) {
>>>>> + result.addAll(getElementsAnnotatedWith(annotation));
>>>>> + }
>>>>> + return Collections.unmodifiableSet(result);
>>>>> + }
>>>>>
>>>>
>>>
>
More information about the compiler-dev
mailing list