-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uniform API for accessing annotations from AnnotationTarget #131
Comments
+10 for unification.
I wonder if it would make sense to replace the "direct" variants of the method with composition, i.e. something like Also I'm not 100% sure it makes sense to define both |
I think I didn't think of adding And agree that |
I just want to mention that |
|
I need to figure out a better name for the At the moment, I'm thinking (For completeness, I'll add that yet another option would be to make |
I started looking into this for good and there's a couple places in the Jandex API where the behavior is not exactly deterministic, Obviously, the prime example is the existing @MyAnnotation("f1")
List<@MyAnnotation("f2") String> field;
@MyAnnotation("m1")
void method(@MyAnnotation("m2") List<@MyAnnotation("m3") String> param) {
} In this case, Obtaining a This would obviously call for removing this method, but I'm afraid it is used a lot. And works just fine when only one annotation of given name is present, which is the most common case. So instead of removing, I'm thinking I'll do this:
[1] Another example is |
I also just noticed that My original goal here is to break as little as possible, and if there's a breakage, it should be caught during compilation. This behavioral difference between |
Regarding your first example agree it should be documented although this was intentional it’s a short-hand “findFirst” to cut down boiler plate when the results are unambiguous. WRT to the second example, JLS semantics do not allow multiple different return values for the same argument signature (yet JVM semantics do allow it), (exploited by bridge methods). Jandex originally was focused on just plain Java so in some cases precision was sacrificed to cut boilerplate. I |
Hm, I personally think that deterministic or not the |
I actually found yesterday that In case anyone is curious, here are my current additions to /**
* Returns whether an annotation instance with given name is declared on this annotation target or any of its
* nested annotation targets.
*
* @param name name of the annotation type to look for, must not be {@code null}
* @return {@code true} if the annotation is present, {@code false} otherwise
* @since 3.0
* @see #annotation(DotName)
* @see #annotations()
*/
boolean hasAnnotation(DotName name);
/**
* Returns the annotation instance with given name declared on this annotation target or any of its nested
* annotation targets. The {@code target()} method of the returned annotation instance may be used to determine
* the exact location of the annotation instance.
* <p>
* In case an annotation with given name occurs more than once, the result of this method is not deterministic.
* For such situations, {@link #annotations(DotName)} is preferable.
*
* @param name name of the annotation type to look for, must not be {@code null}
* @return the annotation instance, or {@code null} if not found
* @since 3.0
* @see #annotations(DotName)
*/
AnnotationInstance annotation(DotName name);
/**
* Returns the annotation instances with given name declared on this annotation target and nested annotation targets.
* The {@code target()} method of the returned annotation instances may be used to determine the exact location
* of the respective annotation instance.
*
* @param name name of the annotation type, must not be {@code null}
* @return collection of annotation instances, never {@code null}
* @see #annotationsWithRepeatable(DotName, IndexView)
* @see #annotations()
* @since 3.0
*/
Collection<AnnotationInstance> annotations(DotName name);
/**
* Returns the annotation instances with given name declared on this annotation target and nested annotation targets.
* The {@code target()} method of the returned annotation instances may be used to determine the exact location
* of the respective annotation instance.
* <p>
* If the specified annotation is repeatable, the result also contains all values from the container annotation
* instance. In this case, the {@link AnnotationInstance#target()} returns the target of the container annotation
* instance.
*
* @param name name of the annotation type, must not be {@code null}
* @param index index used to obtain the annotation type, must not be {@code null}
* @return collection of annotation instances, never {@code null}
* @throws IllegalArgumentException if the index does not contain the annotation type or if {@code name} does not
* identify an annotation type
* @see #annotations()
* @since 3.0
*/
Collection<AnnotationInstance> annotationsWithRepeatable(DotName name, IndexView index);
/**
* Returns the annotation instances declared on this annotation target and nested annotation targets.
* The {@code target()} method of the returned annotation instances may be used to determine the exact location
* of the respective annotation instance.
*
* @return collection of annotation instances, never {@code null}
* @since 3.0
*/
Collection<AnnotationInstance> annotations(); The implementations of A second set of methods to only access annotations declared directly on the target and not on nested targets is yet to be added. I'm still not sure what would be the best naming :-) |
One thing about the I identified 2 differences:
My current plan is to unify all implementations of
|
+1
That's an interesting edge case. And I agree that we should always look for the container annotation as well. TBH I know about a few places in quarkus where this corner case is not handled "correctly" ;-). |
Done in #182. |
Two PRs (#64, #75) already attempt to make the annotation access API more regular. I think this should be addressed holistically. In my opinion, all the annotation access methods should be present on
AnnotationTarget
, so that all annotation targets expose uniform API. It would look roughly like this:The
direct*
methods would return annotations that are present directly on the annotation target, while the generic methods would -- just like now -- return annotations present on the annotation target as well as nested annotation targets.This would unfortunately be a breaking change, because
ClassInfo
currently exposes a very different API than other annotation targets and there's a name collision.The text was updated successfully, but these errors were encountered: