From d5642c56c72c402b23b95abea5499287d4e78f2a Mon Sep 17 00:00:00 2001 From: graemerocher Date: Tue, 27 Jul 2021 17:24:13 +0200 Subject: [PATCH 1/3] Start cleanup of AnnotationTarget --- .../build/compatible/spi/Annotations.java | 40 ++++----- .../build/compatible/spi/Enhancement.java | 2 +- .../lang/model/AnnotationAttribute.java | 2 +- .../enterprise/lang/model/AnnotationInfo.java | 61 +++++++++----- ...ributeValue.java => AnnotationMember.java} | 6 +- .../lang/model/AnnotationTarget.java | 81 ++++++++++++++++--- 6 files changed, 139 insertions(+), 53 deletions(-) rename api/src/main/java/jakarta/enterprise/lang/model/{AnnotationAttributeValue.java => AnnotationMember.java} (93%) diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Annotations.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Annotations.java index 0d5af2f0..fc4e4d28 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Annotations.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Annotations.java @@ -1,7 +1,7 @@ package jakarta.enterprise.inject.build.compatible.spi; import jakarta.enterprise.lang.model.AnnotationAttribute; -import jakarta.enterprise.lang.model.AnnotationAttributeValue; +import jakarta.enterprise.lang.model.AnnotationMember; import jakarta.enterprise.lang.model.AnnotationInfo; import jakarta.enterprise.lang.model.declarations.ClassInfo; import java.lang.annotation.Annotation; @@ -9,39 +9,39 @@ // TODO devise a builder-style API instead (see also AnnotationConfig) public interface Annotations { - AnnotationAttributeValue value(boolean value); + AnnotationMember value(boolean value); - AnnotationAttributeValue value(byte value); + AnnotationMember value(byte value); - AnnotationAttributeValue value(short value); + AnnotationMember value(short value); - AnnotationAttributeValue value(int value); + AnnotationMember value(int value); - AnnotationAttributeValue value(long value); + AnnotationMember value(long value); - AnnotationAttributeValue value(float value); + AnnotationMember value(float value); - AnnotationAttributeValue value(double value); + AnnotationMember value(double value); - AnnotationAttributeValue value(char value); + AnnotationMember value(char value); - AnnotationAttributeValue value(String value); + AnnotationMember value(String value); - AnnotationAttributeValue value(Enum enumValue); + AnnotationMember value(Enum enumValue); - AnnotationAttributeValue value(Class> enumType, String enumValue); + AnnotationMember value(Class> enumType, String enumValue); - AnnotationAttributeValue value(ClassInfo enumType, String enumValue); + AnnotationMember value(ClassInfo enumType, String enumValue); - AnnotationAttributeValue value(Class value); + AnnotationMember value(Class value); - AnnotationAttributeValue annotationValue(Class annotationType, AnnotationAttribute... attributes); + AnnotationMember annotationValue(Class annotationType, AnnotationAttribute... attributes); - AnnotationAttributeValue annotationValue(ClassInfo annotationType, AnnotationAttribute... attributes); + AnnotationMember annotationValue(ClassInfo annotationType, AnnotationAttribute... attributes); - AnnotationAttributeValue annotationValue(AnnotationInfo annotation); + AnnotationMember annotationValue(AnnotationInfo annotation); - AnnotationAttributeValue annotationValue(Annotation annotation); + AnnotationMember annotationValue(Annotation annotation); AnnotationAttribute attribute(String name, boolean value); @@ -69,9 +69,9 @@ public interface Annotations { AnnotationAttribute attribute(String name, Class value); - AnnotationAttribute arrayAttribute(String name, AnnotationAttributeValue... values); + AnnotationAttribute arrayAttribute(String name, AnnotationMember... values); - AnnotationAttribute arrayAttribute(String name, List values); + AnnotationAttribute arrayAttribute(String name, List values); AnnotationAttribute annotationAttribute(String name, Class annotationType, AnnotationAttribute... attributes); diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Enhancement.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Enhancement.java index 8d494bee..c8a1c012 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Enhancement.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Enhancement.java @@ -26,7 +26,7 @@ * class types, array types, parameterized types and wildcard types. *

* If you need to create instances of {@link jakarta.enterprise.lang.model.AnnotationAttribute AnnotationAttribute} or - * {@link jakarta.enterprise.lang.model.AnnotationAttributeValue AnnotationAttributeValue}, you can also declare + * {@link jakarta.enterprise.lang.model.AnnotationMember AnnotationAttributeValue}, you can also declare * a parameter of type {@link Annotations Annotations}. It provides factory methods for all kinds of annotation attributes. */ @Target(ElementType.METHOD) diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationAttribute.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationAttribute.java index 99c84f35..615c6842 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationAttribute.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationAttribute.java @@ -4,5 +4,5 @@ public interface AnnotationAttribute { String name(); - AnnotationAttributeValue value(); + AnnotationMember value(); } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java index b65ab9de..b30fd53e 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java @@ -1,15 +1,29 @@ package jakarta.enterprise.lang.model; import jakarta.enterprise.lang.model.declarations.ClassInfo; + +import java.lang.annotation.Annotation; import java.lang.annotation.Repeatable; import java.util.Collection; -public interface AnnotationInfo { +/** + * Models an annotation definition, providing access to the {@link jakarta.enterprise.lang.model.AnnotationMember} + * instances. + * + * @param The annotation type. + */ +public interface AnnotationInfo { + /** + * The commonly used {@code value()} member. + */ + String MEMBER_VALUE = "value"; + /** * Target of this annotation. * That is, the declaration, the type parameter or the type use on which this annotation is present. * TODO what if this annotation is a nested annotation? * TODO what if this annotation doesn't have a known target (e.g. qualifier of a synthetic bean)? + * TODO Do we need this? Retrieving the target from an annotation value is not supported in Micronaut * * @return target of this annotation */ @@ -18,15 +32,15 @@ public interface AnnotationInfo { /** * Declaration of this annotation's type. * - * @return declaration of this annotation + * @return declaration of this annotation, never {@code null} */ - ClassInfo declaration(); + ClassInfo declaration(); /** * Fully qualified name of this annotation. * Equivalent to {@code declaration().name()}. * - * @return fully qualified name of this annotation + * @return fully qualified name of this annotation, never {@code null} */ default String name() { return declaration().name(); @@ -43,34 +57,45 @@ default boolean isRepeatable() { } /** - * Whether this annotation has an attribute with given {@code name}. + * Whether this annotation has a member with given {@code name}. * - * @param name attribute name - * @return whether this annotation has an attribute with given {@code name} + * @param name member name, never {@code null} + * @return whether this annotation has a member with given {@code name} + * @throws java.lang.IllegalArgumentException if the argument is {@code null} */ - boolean hasAttribute(String name); + boolean hasMember(String name); /** * Value of this annotation's attribute with given {@code name}. - * TODO what if it doesn't exist? null, exception, or change return type to Optional * - * @param name attribute name - * @return value of this annotation's attribute with given {@code name} + * @param name attribute name, never {@code null} + * @return value of this annotation's attribute with given {@code name} or {@code null} if it doesn't exist. + * @throws java.lang.IllegalArgumentException if the argument is {@code null} */ - AnnotationAttributeValue attribute(String name); + AnnotationMember member(String name); + /** + * Returns whether this annotation has a value defined using the {@link #MEMBER_VALUE} member. + * + * @return Returns {@code true} if the {@link #MEMBER_VALUE} is set, {@code false} otherwise + */ default boolean hasValue() { - return hasAttribute("value"); + return hasMember(MEMBER_VALUE); } - default AnnotationAttributeValue value() { - return attribute("value"); + /** + * Returns the {@link AnnotationMember} instance that represents + * the value of the {@link #MEMBER_VALUE} member. + * @return An {@link AnnotationMember} instance or {@code null} if none exists. + */ + default AnnotationMember value() { + return member(MEMBER_VALUE); } /** - * All attributes of this annotation. + * All members of this annotation. * - * @return all attributes of this annotation + * @return An immutable collection of all members of this annotation. Never {@code null}. */ - Collection attributes(); + Collection members(); } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationAttributeValue.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java similarity index 93% rename from api/src/main/java/jakarta/enterprise/lang/model/AnnotationAttributeValue.java rename to api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java index d404c29f..f4b22f66 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationAttributeValue.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java @@ -5,7 +5,7 @@ import java.util.List; // TODO "attribute" is a colloquial expression, perhaps use something closer to the JLS? AnnotationMember? -public interface AnnotationAttributeValue { +public interface AnnotationMember { // TODO is there a better API for this than the is*/as* style? enum Kind { @@ -105,7 +105,7 @@ default boolean isNestedAnnotation() { Type asClass(); // can be a VoidType, PrimitiveType or ClassType - List asArray(); + List asArray(); - AnnotationInfo asNestedAnnotation(); + AnnotationInfo asNestedAnnotation(); } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationTarget.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationTarget.java index 74923aec..1e92b99f 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationTarget.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationTarget.java @@ -7,37 +7,98 @@ import java.util.function.Predicate; /** - * Annotation target is anything that can be annotated. + * An Annotation target is anything that can be annotated. * That is: * *

    - *
  • a declaration, such as a class, method, field, etc.
  • - *
  • a type parameter, occuring in class declarations and method declarations
  • - *
  • a type use, such as a type of method parameter, a type of field, a type argument, etc.
  • + *
  • a declaration, such as a class, method, field, etc. See {@link jakarta.enterprise.lang.model.declarations.DeclarationInfo}.
  • + *
  • a type parameter, occurring in class declarations and method declarations.
  • + *
  • a type use, such as a type of method parameter, a type of field, a type argument, etc. See {@link jakarta.enterprise.lang.model.types.Type}.
  • *
+ * + * + * @since 4.0.0 */ public interface AnnotationTarget { // TODO specify equals/hashCode (for the entire .lang.model hierarchy) // TODO settle on using Optional everywhere, or allowing null everywhere; it's a mix right now + // TODO what about declared vs not declared annotations? + // TODO I am wondering why we are deviating from javax.lang.model names here like AnnotatedConstruct, Element etc. + /** + * Returns whether this annotation target a {@link jakarta.enterprise.lang.model.declarations.DeclarationInfo}. + * + * @see jakarta.enterprise.lang.model.declarations.DeclarationInfo + * @return Will return {@code true} if it is a {@link jakarta.enterprise.lang.model.declarations.DeclarationInfo} and {@code false} otherwise + */ boolean isDeclaration(); + /** + * Returns whether this annotation target is a {@link jakarta.enterprise.lang.model.types.Type}. + * @return Will return {@code true} if it is a {@link jakarta.enterprise.lang.model.types.Type} and {@code false} otherwise + */ boolean isType(); + /** + * Coerce this annotation target to a {@link jakarta.enterprise.lang.model.declarations.DeclarationInfo}. + * @return The {@link jakarta.enterprise.lang.model.declarations.DeclarationInfo} instance, never {@code null} + * @throws java.lang.IllegalStateException If {@link #isDeclaration()} returns {@code false} + */ DeclarationInfo asDeclaration(); + /** + * Coerce this annotation target to a {@link jakarta.enterprise.lang.model.types.Type}. + * @return The {@link jakarta.enterprise.lang.model.types.Type} instance, never {@code null} + * @throws java.lang.IllegalStateException If {@link #isType()} returns {@code false} + */ Type asType(); + /** + * Return with the given annotation type is present on this annotation target. + * + * @param annotationType The annotation type, never {@code null} + * @return Returns {@code true} if the given annotation type is present on this annotation info, {@code false} otherwise. + * @throws java.lang.IllegalArgumentException If {@code null} is passed as an argument + */ boolean hasAnnotation(Class annotationType); - boolean hasAnnotation(Predicate predicate); + /** + * Evaluate the given predicate, returning {@code true} if the predicate matches any {@link jakarta.enterprise.lang.model.AnnotationInfo} present on this annotation target. + * @param predicate The predicate, never {@code null} + * @return Returns {@code true} if the given predicate matches any {@link jakarta.enterprise.lang.model.AnnotationInfo} instance, {@code false} otherwise. + * @throws java.lang.IllegalArgumentException If {@code null} is passed as an argument + */ + boolean hasAnnotation(Predicate> predicate); - // TODO what if missing? - AnnotationInfo annotation(Class annotationType); + /** + * Obtains an {@link jakarta.enterprise.lang.model.AnnotationInfo} for the given annotation type if it is present on this annotation target. + * @param annotationType The annotation type, never {@code null} + * @param The annotation generic type + * @return The {@link jakarta.enterprise.lang.model.AnnotationInfo} or {@code null} if it doesn't exist. + * @throws java.lang.IllegalArgumentException If {@code null} is passed as an argument + */ + AnnotationInfo annotation(Class annotationType); - Collection repeatableAnnotation(Class annotationType); + /** + * Obtains a collection of the repeatable {@link jakarta.enterprise.lang.model.AnnotationInfo} instances for the given repeatable annotation type (An annotation type that is annotated with {@link java.lang.annotation.Repeatable}). + * + * @param annotationType The annotation type + * @return An immutable collection of {@link jakarta.enterprise.lang.model.AnnotationInfo}, never {@code null} + */ + Collection> repeatableAnnotation(Class annotationType); - Collection annotations(Predicate predicate); + /** + * Obtains a collection of the {@link jakarta.enterprise.lang.model.AnnotationInfo} instances that match the given predicate. + * + * @param predicate The predicate used to evaluate matching {@link jakarta.enterprise.lang.model.AnnotationInfo} instances. + * @return An immutable collection of {@link jakarta.enterprise.lang.model.AnnotationInfo}, never {@code null} + * @throws java.lang.IllegalArgumentException If {@code null} is passed as an argument + */ + Collection> annotations(Predicate> predicate); - Collection annotations(); + /** + * Obtains all of the {@link jakarta.enterprise.lang.model.AnnotationInfo} instances for the given annotation target. + * @return An immutable collection of {@link jakarta.enterprise.lang.model.AnnotationInfo}, never {@code null} + */ + Collection> annotations(); } From 9d8b916d3f3c1f534403332e8a363519bcdb0fdd Mon Sep 17 00:00:00 2001 From: graemerocher Date: Tue, 27 Jul 2021 17:27:40 +0200 Subject: [PATCH 2/3] rename --- .../compatible/spi/AnnotationConfig.java | 6 +- .../build/compatible/spi/Annotations.java | 76 ++++++------ .../build/compatible/spi/Enhancement.java | 4 +- .../compatible/spi/SyntheticBeanBuilder.java | 6 +- .../spi/SyntheticObserverBuilder.java | 6 +- .../lang/model/AnnotationAttribute.java | 8 -- .../enterprise/lang/model/AnnotationInfo.java | 12 +- .../lang/model/AnnotationMember.java | 107 +---------------- .../lang/model/AnnotationMemberValue.java | 111 ++++++++++++++++++ 9 files changed, 168 insertions(+), 168 deletions(-) delete mode 100644 api/src/main/java/jakarta/enterprise/lang/model/AnnotationAttribute.java create mode 100644 api/src/main/java/jakarta/enterprise/lang/model/AnnotationMemberValue.java diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationConfig.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationConfig.java index 97201ddd..92fa33c2 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationConfig.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationConfig.java @@ -1,6 +1,6 @@ package jakarta.enterprise.inject.build.compatible.spi; -import jakarta.enterprise.lang.model.AnnotationAttribute; +import jakarta.enterprise.lang.model.AnnotationMember; import jakarta.enterprise.lang.model.AnnotationInfo; import jakarta.enterprise.lang.model.declarations.ClassInfo; import java.lang.annotation.Annotation; @@ -9,9 +9,9 @@ // TODO better name? // TODO devise a builder-style API instead (see also Annotations) public interface AnnotationConfig { - void addAnnotation(Class annotationType, AnnotationAttribute... attributes); + void addAnnotation(Class annotationType, AnnotationMember... attributes); - void addAnnotation(ClassInfo annotationType, AnnotationAttribute... attributes); + void addAnnotation(ClassInfo annotationType, AnnotationMember... attributes); void addAnnotation(AnnotationInfo annotation); diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Annotations.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Annotations.java index fc4e4d28..261aef18 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Annotations.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Annotations.java @@ -1,7 +1,7 @@ package jakarta.enterprise.inject.build.compatible.spi; -import jakarta.enterprise.lang.model.AnnotationAttribute; import jakarta.enterprise.lang.model.AnnotationMember; +import jakarta.enterprise.lang.model.AnnotationMemberValue; import jakarta.enterprise.lang.model.AnnotationInfo; import jakarta.enterprise.lang.model.declarations.ClassInfo; import java.lang.annotation.Annotation; @@ -9,76 +9,76 @@ // TODO devise a builder-style API instead (see also AnnotationConfig) public interface Annotations { - AnnotationMember value(boolean value); + AnnotationMemberValue value(boolean value); - AnnotationMember value(byte value); + AnnotationMemberValue value(byte value); - AnnotationMember value(short value); + AnnotationMemberValue value(short value); - AnnotationMember value(int value); + AnnotationMemberValue value(int value); - AnnotationMember value(long value); + AnnotationMemberValue value(long value); - AnnotationMember value(float value); + AnnotationMemberValue value(float value); - AnnotationMember value(double value); + AnnotationMemberValue value(double value); - AnnotationMember value(char value); + AnnotationMemberValue value(char value); - AnnotationMember value(String value); + AnnotationMemberValue value(String value); - AnnotationMember value(Enum enumValue); + AnnotationMemberValue value(Enum enumValue); - AnnotationMember value(Class> enumType, String enumValue); + AnnotationMemberValue value(Class> enumType, String enumValue); - AnnotationMember value(ClassInfo enumType, String enumValue); + AnnotationMemberValue value(ClassInfo enumType, String enumValue); - AnnotationMember value(Class value); + AnnotationMemberValue value(Class value); - AnnotationMember annotationValue(Class annotationType, AnnotationAttribute... attributes); + AnnotationMemberValue annotationValue(Class annotationType, AnnotationMember... attributes); - AnnotationMember annotationValue(ClassInfo annotationType, AnnotationAttribute... attributes); + AnnotationMemberValue annotationValue(ClassInfo annotationType, AnnotationMember... attributes); - AnnotationMember annotationValue(AnnotationInfo annotation); + AnnotationMemberValue annotationValue(AnnotationInfo annotation); - AnnotationMember annotationValue(Annotation annotation); + AnnotationMemberValue annotationValue(Annotation annotation); - AnnotationAttribute attribute(String name, boolean value); + AnnotationMember attribute(String name, boolean value); - AnnotationAttribute attribute(String name, byte value); + AnnotationMember attribute(String name, byte value); - AnnotationAttribute attribute(String name, short value); + AnnotationMember attribute(String name, short value); - AnnotationAttribute attribute(String name, int value); + AnnotationMember attribute(String name, int value); - AnnotationAttribute attribute(String name, long value); + AnnotationMember attribute(String name, long value); - AnnotationAttribute attribute(String name, float value); + AnnotationMember attribute(String name, float value); - AnnotationAttribute attribute(String name, double value); + AnnotationMember attribute(String name, double value); - AnnotationAttribute attribute(String name, char value); + AnnotationMember attribute(String name, char value); - AnnotationAttribute attribute(String name, String value); + AnnotationMember attribute(String name, String value); - AnnotationAttribute attribute(String name, Enum enumValue); + AnnotationMember attribute(String name, Enum enumValue); - AnnotationAttribute attribute(String name, Class> enumType, String enumValue); + AnnotationMember attribute(String name, Class> enumType, String enumValue); - AnnotationAttribute attribute(String name, ClassInfo enumType, String enumValue); + AnnotationMember attribute(String name, ClassInfo enumType, String enumValue); - AnnotationAttribute attribute(String name, Class value); + AnnotationMember attribute(String name, Class value); - AnnotationAttribute arrayAttribute(String name, AnnotationMember... values); + AnnotationMember arrayAttribute(String name, AnnotationMemberValue... values); - AnnotationAttribute arrayAttribute(String name, List values); + AnnotationMember arrayAttribute(String name, List values); - AnnotationAttribute annotationAttribute(String name, Class annotationType, - AnnotationAttribute... attributes); + AnnotationMember annotationAttribute(String name, Class annotationType, + AnnotationMember... attributes); - AnnotationAttribute annotationAttribute(String name, ClassInfo annotationType, AnnotationAttribute... attributes); + AnnotationMember annotationAttribute(String name, ClassInfo annotationType, AnnotationMember... attributes); - AnnotationAttribute annotationAttribute(String name, AnnotationInfo annotation); + AnnotationMember annotationAttribute(String name, AnnotationInfo annotation); - AnnotationAttribute annotationAttribute(String name, Annotation annotation); + AnnotationMember annotationAttribute(String name, Annotation annotation); } diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Enhancement.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Enhancement.java index c8a1c012..30c2a48a 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Enhancement.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Enhancement.java @@ -25,8 +25,8 @@ * a parameter of type {@link Types Types}. It provides factory methods for the void type, primitive types, * class types, array types, parameterized types and wildcard types. *

- * If you need to create instances of {@link jakarta.enterprise.lang.model.AnnotationAttribute AnnotationAttribute} or - * {@link jakarta.enterprise.lang.model.AnnotationMember AnnotationAttributeValue}, you can also declare + * If you need to create instances of {@link jakarta.enterprise.lang.model.AnnotationMember AnnotationAttribute} or + * {@link jakarta.enterprise.lang.model.AnnotationMemberValue AnnotationAttributeValue}, you can also declare * a parameter of type {@link Annotations Annotations}. It provides factory methods for all kinds of annotation attributes. */ @Target(ElementType.METHOD) diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticBeanBuilder.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticBeanBuilder.java index 537aaaab..43e49e02 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticBeanBuilder.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticBeanBuilder.java @@ -1,6 +1,6 @@ package jakarta.enterprise.inject.build.compatible.spi; -import jakarta.enterprise.lang.model.AnnotationAttribute; +import jakarta.enterprise.lang.model.AnnotationMember; import jakarta.enterprise.lang.model.AnnotationInfo; import jakarta.enterprise.lang.model.declarations.ClassInfo; import jakarta.enterprise.lang.model.types.Type; @@ -25,9 +25,9 @@ public interface SyntheticBeanBuilder { // can be called multiple times and is additive // TODO methods to add multiple qualifiers at once? - SyntheticBeanBuilder qualifier(Class qualifierAnnotation, AnnotationAttribute... attributes); + SyntheticBeanBuilder qualifier(Class qualifierAnnotation, AnnotationMember... attributes); - SyntheticBeanBuilder qualifier(ClassInfo qualifierAnnotation, AnnotationAttribute... attributes); + SyntheticBeanBuilder qualifier(ClassInfo qualifierAnnotation, AnnotationMember... attributes); SyntheticBeanBuilder qualifier(AnnotationInfo qualifierAnnotation); diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticObserverBuilder.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticObserverBuilder.java index 14141fc9..3f94c152 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticObserverBuilder.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SyntheticObserverBuilder.java @@ -1,6 +1,6 @@ package jakarta.enterprise.inject.build.compatible.spi; -import jakarta.enterprise.lang.model.AnnotationAttribute; +import jakarta.enterprise.lang.model.AnnotationMember; import jakarta.enterprise.lang.model.AnnotationInfo; import jakarta.enterprise.lang.model.declarations.ClassInfo; import jakarta.enterprise.lang.model.types.Type; @@ -40,9 +40,9 @@ public interface SyntheticObserverBuilder { // can be called multiple times and is additive // TODO methods to add multiple qualifiers at once? - SyntheticObserverBuilder qualifier(Class qualifierAnnotation, AnnotationAttribute... attributes); + SyntheticObserverBuilder qualifier(Class qualifierAnnotation, AnnotationMember... attributes); - SyntheticObserverBuilder qualifier(ClassInfo qualifierAnnotation, AnnotationAttribute... attributes); + SyntheticObserverBuilder qualifier(ClassInfo qualifierAnnotation, AnnotationMember... attributes); SyntheticObserverBuilder qualifier(AnnotationInfo qualifierAnnotation); diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationAttribute.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationAttribute.java deleted file mode 100644 index 615c6842..00000000 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationAttribute.java +++ /dev/null @@ -1,8 +0,0 @@ -package jakarta.enterprise.lang.model; - -// TODO "attribute" is a colloquial expression, perhaps use something closer to the JLS? AnnotationMember? -public interface AnnotationAttribute { - String name(); - - AnnotationMember value(); -} diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java index b30fd53e..96f472ae 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java @@ -7,7 +7,7 @@ import java.util.Collection; /** - * Models an annotation definition, providing access to the {@link jakarta.enterprise.lang.model.AnnotationMember} + * Models an annotation definition, providing access to the {@link AnnotationMemberValue} * instances. * * @param The annotation type. @@ -72,7 +72,7 @@ default boolean isRepeatable() { * @return value of this annotation's attribute with given {@code name} or {@code null} if it doesn't exist. * @throws java.lang.IllegalArgumentException if the argument is {@code null} */ - AnnotationMember member(String name); + AnnotationMemberValue member(String name); /** * Returns whether this annotation has a value defined using the {@link #MEMBER_VALUE} member. @@ -84,11 +84,11 @@ default boolean hasValue() { } /** - * Returns the {@link AnnotationMember} instance that represents + * Returns the {@link AnnotationMemberValue} instance that represents * the value of the {@link #MEMBER_VALUE} member. - * @return An {@link AnnotationMember} instance or {@code null} if none exists. + * @return An {@link AnnotationMemberValue} instance or {@code null} if none exists. */ - default AnnotationMember value() { + default AnnotationMemberValue value() { return member(MEMBER_VALUE); } @@ -97,5 +97,5 @@ default AnnotationMember value() { * * @return An immutable collection of all members of this annotation. Never {@code null}. */ - Collection members(); + Collection members(); } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java index f4b22f66..17b33e25 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java @@ -1,111 +1,8 @@ package jakarta.enterprise.lang.model; -import jakarta.enterprise.lang.model.declarations.ClassInfo; -import jakarta.enterprise.lang.model.types.Type; -import java.util.List; - // TODO "attribute" is a colloquial expression, perhaps use something closer to the JLS? AnnotationMember? public interface AnnotationMember { - // TODO is there a better API for this than the is*/as* style? - - enum Kind { - BOOLEAN, - BYTE, - SHORT, - INT, - LONG, - FLOAT, - DOUBLE, - CHAR, - STRING, - ENUM, - CLASS, - ARRAY, - NESTED_ANNOTATION, - } - - Kind kind(); - - default boolean isBoolean() { - return kind() == Kind.BOOLEAN; - } - - default boolean isByte() { - return kind() == Kind.BYTE; - } - - default boolean isShort() { - return kind() == Kind.SHORT; - } - - default boolean isInt() { - return kind() == Kind.INT; - } - - default boolean isLong() { - return kind() == Kind.LONG; - } - - default boolean isFloat() { - return kind() == Kind.FLOAT; - } - - default boolean isDouble() { - return kind() == Kind.DOUBLE; - } - - default boolean isChar() { - return kind() == Kind.CHAR; - } - - default boolean isString() { - return kind() == Kind.STRING; - } - - default boolean isEnum() { - return kind() == Kind.ENUM; - } - - default boolean isClass() { - return kind() == Kind.CLASS; - } - - default boolean isArray() { - return kind() == Kind.ARRAY; - } - - default boolean isNestedAnnotation() { - return kind() == Kind.NESTED_ANNOTATION; - } - - boolean asBoolean(); - - byte asByte(); - - short asShort(); - - int asInt(); - - long asLong(); - - float asFloat(); - - double asDouble(); - - char asChar(); - - String asString(); - - // TODO should this be present? - > E asEnum(); - - ClassInfo asEnumClass(); - - String asEnumValue(); - - Type asClass(); // can be a VoidType, PrimitiveType or ClassType - - List asArray(); + String name(); - AnnotationInfo asNestedAnnotation(); + AnnotationMemberValue value(); } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMemberValue.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMemberValue.java new file mode 100644 index 00000000..31d2a1f0 --- /dev/null +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMemberValue.java @@ -0,0 +1,111 @@ +package jakarta.enterprise.lang.model; + +import jakarta.enterprise.lang.model.declarations.ClassInfo; +import jakarta.enterprise.lang.model.types.Type; +import java.util.List; + +// TODO "attribute" is a colloquial expression, perhaps use something closer to the JLS? AnnotationMember? +public interface AnnotationMemberValue { + // TODO is there a better API for this than the is*/as* style? + + enum Kind { + BOOLEAN, + BYTE, + SHORT, + INT, + LONG, + FLOAT, + DOUBLE, + CHAR, + STRING, + ENUM, + CLASS, + ARRAY, + NESTED_ANNOTATION, + } + + Kind kind(); + + default boolean isBoolean() { + return kind() == Kind.BOOLEAN; + } + + default boolean isByte() { + return kind() == Kind.BYTE; + } + + default boolean isShort() { + return kind() == Kind.SHORT; + } + + default boolean isInt() { + return kind() == Kind.INT; + } + + default boolean isLong() { + return kind() == Kind.LONG; + } + + default boolean isFloat() { + return kind() == Kind.FLOAT; + } + + default boolean isDouble() { + return kind() == Kind.DOUBLE; + } + + default boolean isChar() { + return kind() == Kind.CHAR; + } + + default boolean isString() { + return kind() == Kind.STRING; + } + + default boolean isEnum() { + return kind() == Kind.ENUM; + } + + default boolean isClass() { + return kind() == Kind.CLASS; + } + + default boolean isArray() { + return kind() == Kind.ARRAY; + } + + default boolean isNestedAnnotation() { + return kind() == Kind.NESTED_ANNOTATION; + } + + boolean asBoolean(); + + byte asByte(); + + short asShort(); + + int asInt(); + + long asLong(); + + float asFloat(); + + double asDouble(); + + char asChar(); + + String asString(); + + // TODO should this be present? + > E asEnum(); + + ClassInfo asEnumClass(); + + String asEnumValue(); + + Type asClass(); // can be a VoidType, PrimitiveType or ClassType + + List asArray(); + + AnnotationInfo asNestedAnnotation(); +} From 0e921f78c2832660b37c1adc5951c90b64d674d6 Mon Sep 17 00:00:00 2001 From: graemerocher Date: Wed, 28 Jul 2021 17:25:25 +0200 Subject: [PATCH 3/3] more cleanup --- .../enterprise/lang/model/AnnotationInfo.java | 17 +- .../lang/model/AnnotationMember.java | 12 +- .../lang/model/AnnotationMemberValue.java | 171 +++++++++++++++++- .../lang/model/AnnotationTarget.java | 1 - 4 files changed, 175 insertions(+), 26 deletions(-) diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java index 96f472ae..e0a5d565 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java @@ -18,17 +18,6 @@ public interface AnnotationInfo { */ String MEMBER_VALUE = "value"; - /** - * Target of this annotation. - * That is, the declaration, the type parameter or the type use on which this annotation is present. - * TODO what if this annotation is a nested annotation? - * TODO what if this annotation doesn't have a known target (e.g. qualifier of a synthetic bean)? - * TODO Do we need this? Retrieving the target from an annotation value is not supported in Micronaut - * - * @return target of this annotation - */ - AnnotationTarget target(); - /** * Declaration of this annotation's type. * @@ -61,7 +50,7 @@ default boolean isRepeatable() { * * @param name member name, never {@code null} * @return whether this annotation has a member with given {@code name} - * @throws java.lang.IllegalArgumentException if the argument is {@code null} + * @throws java.lang.NullPointerException if the argument is {@code null} */ boolean hasMember(String name); @@ -70,12 +59,12 @@ default boolean isRepeatable() { * * @param name attribute name, never {@code null} * @return value of this annotation's attribute with given {@code name} or {@code null} if it doesn't exist. - * @throws java.lang.IllegalArgumentException if the argument is {@code null} + * @throws java.lang.NullPointerException if the argument is {@code null} */ AnnotationMemberValue member(String name); /** - * Returns whether this annotation has a value defined using the {@link #MEMBER_VALUE} member. + * Returns whether this annotation has the {@link #MEMBER_VALUE} member. * * @return Returns {@code true} if the {@link #MEMBER_VALUE} is set, {@code false} otherwise */ diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java index 17b33e25..41693820 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java @@ -1,8 +1,18 @@ package jakarta.enterprise.lang.model; -// TODO "attribute" is a colloquial expression, perhaps use something closer to the JLS? AnnotationMember? +/** + * Represents an annotation member and associated {@link jakarta.enterprise.lang.model.AnnotationMemberValue}. + */ public interface AnnotationMember { + /** + * @return The name of the annotation member. Never {@code null}. + */ String name(); + /** + * Supplies the {@link jakarta.enterprise.lang.model.AnnotationMemberValue} associated with the annotation member. + * + * @return The value of the annotation member. Never {@code null}. + */ AnnotationMemberValue value(); } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMemberValue.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMemberValue.java index 31d2a1f0..4cabe36c 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMemberValue.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMemberValue.java @@ -4,108 +4,259 @@ import jakarta.enterprise.lang.model.types.Type; import java.util.List; -// TODO "attribute" is a colloquial expression, perhaps use something closer to the JLS? AnnotationMember? +/** + * Models the value of an {@link jakarta.enterprise.lang.model.AnnotationMember}. + */ public interface AnnotationMemberValue { - // TODO is there a better API for this than the is*/as* style? - + /** + * The kind of the member. + */ enum Kind { + /** + * A primitive {@link java.lang.Boolean}. + */ BOOLEAN, + /** + * A primitive {@link java.lang.Byte}. + */ BYTE, + /** + * A primitive {@link java.lang.Short}. + */ SHORT, + /** + * A primitive {@link java.lang.Integer}. + */ INT, + /** + * A primitive {@link java.lang.Long}. + */ LONG, + /** + * A primitive {@link java.lang.Float}. + */ FLOAT, + /** + * A primitive {@link java.lang.Double}. + */ DOUBLE, + /** + * A primitive {@link java.lang.Character}. + */ CHAR, + /** + * A {@link java.lang.String} value. + */ STRING, + /** + * An {@link java.lang.Enum} value. + */ ENUM, + /** + * A {@link java.lang.Class} value modelled as {@link jakarta.enterprise.lang.model.types.Type}. + */ CLASS, + /** + * An array value. + */ ARRAY, + /** + * A nested annotation definition. + */ NESTED_ANNOTATION, } + /** + * @return The kind of the annotation member. Never {@code null}. + */ Kind kind(); + /** + * @return Returns {@code true} if the kind is a {@code boolean}, {@code false} otherwise. + */ default boolean isBoolean() { return kind() == Kind.BOOLEAN; } + /** + * @return Returns {@code true} if the kind is a {@code byte}, {@code false} otherwise. + */ default boolean isByte() { return kind() == Kind.BYTE; } + /** + * @return Returns {@code true} if the kind is a {@code short}, {@code false} otherwise. + */ default boolean isShort() { return kind() == Kind.SHORT; } + /** + * @return Returns {@code true} if the kind is a {@code int}, {@code false} otherwise. + */ default boolean isInt() { return kind() == Kind.INT; } + /** + * @return Returns {@code true} if the kind is a {@code long}, {@code false} otherwise. + */ default boolean isLong() { return kind() == Kind.LONG; } + /** + * @return Returns {@code true} if the kind is a {@code float}, {@code false} otherwise. + */ default boolean isFloat() { return kind() == Kind.FLOAT; } + /** + * @return Returns {@code true} if the kind is a {@code double}, {@code false} otherwise. + */ default boolean isDouble() { return kind() == Kind.DOUBLE; } + /** + * @return Returns {@code true} if the kind is a {@code char}, {@code false} otherwise. + */ default boolean isChar() { return kind() == Kind.CHAR; } + /** + * @return Returns {@code true} if the kind is a {@link String}, {@code false} otherwise. + */ default boolean isString() { return kind() == Kind.STRING; } + /** + * @return Returns {@code true} if the kind is a {@link Enum}, {@code false} otherwise. + */ default boolean isEnum() { return kind() == Kind.ENUM; } + /** + * @return Returns {@code true} if the kind is a {@link Class}, {@code false} otherwise. + */ default boolean isClass() { return kind() == Kind.CLASS; } + /** + * @return Returns {@code true} if the kind is an array, {@code false} otherwise. + */ default boolean isArray() { return kind() == Kind.ARRAY; } + /** + * @return Returns {@code true} if the kind is an {@link java.lang.annotation.Annotation}, {@code false} otherwise. + */ default boolean isNestedAnnotation() { return kind() == Kind.NESTED_ANNOTATION; } + /** + * Return the value as a boolean. + * @return The boolean value + */ boolean asBoolean(); + /** + * Return the value as a byte. + * @return The byte value + * @throws NumberFormatException if the value cannot be represented as a byte. + */ byte asByte(); + /** + * Return the value as a short. + * @return The short value + * @throws NumberFormatException if the value cannot be represented as a short. + */ short asShort(); + /** + * Return the value as an int. + * @return The int value + * @throws java.lang.IllegalStateException if the value cannot be represented as an int. + */ int asInt(); + /** + * Return the value as a long. + * @return The long value + * @throws java.lang.IllegalStateException if the value cannot be represented as a long. + */ long asLong(); + /** + * Return the value as a float. + * @return The float value + * @throws java.lang.IllegalStateException if the value cannot be represented as a float. + */ float asFloat(); + /** + * Return the value as a double. + * @return The double value + * @throws java.lang.IllegalStateException if the value cannot be represented as a double. + */ double asDouble(); + /** + * Return the value as a char. + * @return The char value + * @throws java.lang.IllegalStateException if the value cannot be represented as a double. + */ char asChar(); + /** + * Return the value as a string. + * @return A string representing the value. Never {@code null}. + */ String asString(); - // TODO should this be present? - > E asEnum(); - + /** + * Return the value to an enum instance. + * @param enumType The enum type + * @param The enum generic type + * @return The enum instance + * @throws java.lang.IllegalStateException if the enum value cannot be established from the given argument + */ + > E asEnum(Class enumType); + + /** + * Return the enum type that an enum value represents. + * + * @return A {@link jakarta.enterprise.lang.model.declarations.ClassInfo} representing the type of an enum value. + */ ClassInfo asEnumClass(); - String asEnumValue(); - - Type asClass(); // can be a VoidType, PrimitiveType or ClassType - + /** + * Return the type of the value. Valid types include {@link jakarta.enterprise.lang.model.types.PrimitiveType}, {@link jakarta.enterprise.lang.model.types.VoidType} and {@link jakarta.enterprise.lang.model.types.ClassType}. + * + * @return The {@link jakarta.enterprise.lang.model.types.Type} of the value. + */ + Type asType(); // can be a VoidType, PrimitiveType or ClassType + + /** + * Allows retrieving the values of an array when {@link #isArray()} returns {@code true}. + * + * @return An immutable list of {@link jakarta.enterprise.lang.model.AnnotationMemberValue} representing the array values. + */ List asArray(); + /** + * Allows retrieving the a nested annotation value as an an instance of {@link jakarta.enterprise.lang.model.AnnotationInfo} when {@link #isNestedAnnotation()} returns {@code true}. + * @return The {@link jakarta.enterprise.lang.model.AnnotationInfo} instance. + * @throws java.lang.IllegalStateException If the value is not an annotation. + */ AnnotationInfo asNestedAnnotation(); } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationTarget.java b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationTarget.java index 1e92b99f..1904527b 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationTarget.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationTarget.java @@ -23,7 +23,6 @@ public interface AnnotationTarget { // TODO specify equals/hashCode (for the entire .lang.model hierarchy) // TODO settle on using Optional everywhere, or allowing null everywhere; it's a mix right now // TODO what about declared vs not declared annotations? - // TODO I am wondering why we are deviating from javax.lang.model names here like AnnotatedConstruct, Element etc. /** * Returns whether this annotation target a {@link jakarta.enterprise.lang.model.declarations.DeclarationInfo}.