From 8a40e2e94423f2f0f5ee5ae5c1131c0657057b75 Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Wed, 4 Aug 2021 14:38:36 +0200 Subject: [PATCH] extension API improvements That is specifically: - change the `*Config` types to no longer inherit from the corresponding `*Info` types; instead, they provide an `info()` method - rename `AnnotationConfig` to `DeclarationConfig` for symmetry between `*Info` and `*Config` types - change the annotation transformation methods on `DeclarationConfig` to return `this` to allow fluent usage - allow additional parameter types for `@Enhancement` methods: `DeclarationConfig`, `DeclarationInfo`, `ClassInfo`, `MethodInfo`, and `FieldInfo` (`*Info` types are useful when only collecting information during `@Enhancement`, not modifying anything) - remove useless type parameters from `AnnotationInfo`, `ClassInfo`, `MethodInfo`, `FieldInfo`, `ClassConfig`, `MethodConfig`, `FieldConfig`, `BeanInfo`, and `ObserverInfo`; the `SyntheticBeanBuilder` type still has a type parameter, which remains an open question - add a lot of documentation --- .../compatible/spi/AnnotationBuilder.java | 28 ++-- .../spi/AnnotationBuilderFactory.java | 2 +- .../compatible/spi/AnnotationConfig.java | 19 --- .../inject/build/compatible/spi/BeanInfo.java | 108 ++++++++++++-- .../build/compatible/spi/ClassConfig.java | 49 +++++-- .../compatible/spi/DeclarationConfig.java | 65 +++++++++ .../build/compatible/spi/DisposerInfo.java | 15 +- .../build/compatible/spi/Enhancement.java | 7 +- .../build/compatible/spi/FieldConfig.java | 17 ++- .../compatible/spi/InjectionPointInfo.java | 18 ++- .../inject/build/compatible/spi/Messages.java | 12 +- .../build/compatible/spi/MetaAnnotations.java | 6 +- .../build/compatible/spi/MethodConfig.java | 18 ++- .../build/compatible/spi/ObserverInfo.java | 82 ++++++++++- .../build/compatible/spi/ScopeInfo.java | 21 +-- .../compatible/spi/SyntheticBeanBuilder.java | 6 +- .../spi/SyntheticObserverBuilder.java | 6 +- .../inject/build/compatible/spi/Types.java | 2 +- .../enterprise/lang/model/AnnotationInfo.java | 8 +- .../lang/model/AnnotationMember.java | 8 +- .../lang/model/AnnotationTarget.java | 10 +- .../lang/model/declarations/ClassInfo.java | 137 +++++++++++++++--- .../model/declarations/DeclarationInfo.java | 66 ++++++++- .../lang/model/declarations/FieldInfo.java | 10 +- .../lang/model/declarations/MethodInfo.java | 9 +- .../lang/model/declarations/PackageInfo.java | 9 ++ .../model/declarations/ParameterInfo.java | 24 ++- .../lang/model/types/ClassType.java | 2 +- .../lang/model/types/ParameterizedType.java | 2 +- .../enterprise/lang/model/types/Type.java | 90 +++++++++++- 30 files changed, 691 insertions(+), 165 deletions(-) delete mode 100644 api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationConfig.java create mode 100644 api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/DeclarationConfig.java diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationBuilder.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationBuilder.java index cdd19154..ba0af8eb 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationBuilder.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationBuilder.java @@ -35,7 +35,7 @@ static AnnotationBuilder of(Class annotationType) { * @param annotationType the annotation type, must not be {@code null} * @return a new {@code AnnotationBuilder} */ - static AnnotationBuilder of(ClassInfo annotationType) { + static AnnotationBuilder of(ClassInfo annotationType) { return AnnotationBuilderFactoryResolver.get().create(annotationType); } @@ -278,7 +278,7 @@ default AnnotationBuilder value(Class> enumType, String... enu * @param enumValue name of the enum constant, must not be {@code null} * @return this {@code AnnotationBuilder} */ - default AnnotationBuilder value(ClassInfo enumType, String enumValue) { + default AnnotationBuilder value(ClassInfo enumType, String enumValue) { return member(AnnotationInfo.MEMBER_VALUE, enumType, enumValue); } @@ -289,7 +289,7 @@ default AnnotationBuilder value(ClassInfo enumType, String enumValue) { * @param enumValues names of the enum constants, must not be {@code null} or contain {@code null} * @return this {@code AnnotationBuilder} */ - default AnnotationBuilder value(ClassInfo enumType, String... enumValues) { + default AnnotationBuilder value(ClassInfo enumType, String... enumValues) { return member(AnnotationInfo.MEMBER_VALUE, enumType, enumValues); } @@ -319,7 +319,7 @@ default AnnotationBuilder value(Class... values) { * @param value the class value, must not be {@code null} * @return this {@code AnnotationBuilder} */ - default AnnotationBuilder value(ClassInfo value) { + default AnnotationBuilder value(ClassInfo value) { return member(AnnotationInfo.MEMBER_VALUE, value); } @@ -329,7 +329,7 @@ default AnnotationBuilder value(ClassInfo value) { * @param values the class array, must not be {@code null} or contain {@code null} * @return this {@code AnnotationBuilder} */ - default AnnotationBuilder value(ClassInfo... values) { + default AnnotationBuilder value(ClassInfo... values) { return member(AnnotationInfo.MEMBER_VALUE, values); } @@ -379,7 +379,7 @@ default AnnotationBuilder value(Type... values) { * @param value the annotation value, must not be {@code null} * @return this {@code AnnotationBuilder} */ - default AnnotationBuilder value(AnnotationInfo value) { + default AnnotationBuilder value(AnnotationInfo value) { return member(AnnotationInfo.MEMBER_VALUE, value); } @@ -389,7 +389,7 @@ default AnnotationBuilder value(AnnotationInfo value) { * @param values the annotation array, must not be {@code null} or contain {@code null} * @return this {@code AnnotationBuilder} */ - default AnnotationBuilder value(AnnotationInfo... values) { + default AnnotationBuilder value(AnnotationInfo... values) { return member(AnnotationInfo.MEMBER_VALUE, values); } @@ -630,7 +630,7 @@ default AnnotationBuilder value(Annotation... values) { * @param enumValue name of the enum constant, must not be {@code null} * @return this {@code AnnotationBuilder} */ - AnnotationBuilder member(String name, ClassInfo enumType, String enumValue); + AnnotationBuilder member(String name, ClassInfo enumType, String enumValue); /** * Adds an enum array-valued annotation member with given {@code name}. @@ -640,7 +640,7 @@ default AnnotationBuilder value(Annotation... values) { * @param enumValues names of the enum constants, must not be {@code null} or contain {@code null} * @return this {@code AnnotationBuilder} */ - AnnotationBuilder member(String name, ClassInfo enumType, String... enumValues); + AnnotationBuilder member(String name, ClassInfo enumType, String... enumValues); /** * Adds a class-valued annotation member with given {@code name}. @@ -667,7 +667,7 @@ default AnnotationBuilder value(Annotation... values) { * @param value the class value, must not be {@code null} * @return this {@code AnnotationBuilder} */ - AnnotationBuilder member(String name, ClassInfo value); + AnnotationBuilder member(String name, ClassInfo value); /** * Adds a class array-valued annotation member with given {@code name}. @@ -676,7 +676,7 @@ default AnnotationBuilder value(Annotation... values) { * @param values the class array, must not be {@code null} or contain {@code null} * @return this {@code AnnotationBuilder} */ - AnnotationBuilder member(String name, ClassInfo... values); + AnnotationBuilder member(String name, ClassInfo... values); /** * Adds a class-valued annotation member with given {@code name}. @@ -724,7 +724,7 @@ default AnnotationBuilder value(Annotation... values) { * @param value the annotation value, must not be {@code null} * @return this {@code AnnotationBuilder} */ - AnnotationBuilder member(String name, AnnotationInfo value); + AnnotationBuilder member(String name, AnnotationInfo value); /** * Adds an annotation array-valued annotation member with given {@code name}. @@ -733,7 +733,7 @@ default AnnotationBuilder value(Annotation... values) { * @param values the annotation array, must not be {@code null} or contain {@code null} * @return this {@code AnnotationBuilder} */ - AnnotationBuilder member(String name, AnnotationInfo... values); + AnnotationBuilder member(String name, AnnotationInfo... values); /** * Adds an annotation-valued annotation member with given {@code name}. @@ -759,5 +759,5 @@ default AnnotationBuilder value(Annotation... values) { * * @return the built {@link AnnotationInfo}, never {@code null} */ - AnnotationInfo build(); + AnnotationInfo build(); } diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationBuilderFactory.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationBuilderFactory.java index 6dc7fdf2..251dad7f 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationBuilderFactory.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationBuilderFactory.java @@ -24,5 +24,5 @@ public interface AnnotationBuilderFactory extends Prioritized { * @param annotationType the annotation type * @return a new {@link AnnotationBuilder} */ - AnnotationBuilder create(ClassInfo annotationType); + AnnotationBuilder create(ClassInfo annotationType); } 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 deleted file mode 100644 index da78fb9e..00000000 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationConfig.java +++ /dev/null @@ -1,19 +0,0 @@ -package jakarta.enterprise.inject.build.compatible.spi; - -import jakarta.enterprise.lang.model.AnnotationInfo; - -import java.lang.annotation.Annotation; -import java.util.function.Predicate; - -// TODO better name? -public interface AnnotationConfig { - void addAnnotation(Class annotationType); // for marker annotations - - void addAnnotation(AnnotationInfo annotation); - - void addAnnotation(Annotation annotation); - - void removeAnnotation(Predicate predicate); - - void removeAllAnnotations(); -} diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/BeanInfo.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/BeanInfo.java index f0412839..b16a46fa 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/BeanInfo.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/BeanInfo.java @@ -8,52 +8,134 @@ import java.util.Collection; /** - * @param type of the inspected bean (that is, not the declaring class, but one of the types the bean has) + * Provides read-only information about a bean. */ -public interface BeanInfo { - // TODO remove the type parameter? - +public interface BeanInfo { + /** + * Returns the {@link ScopeInfo scope} of this bean. + * + * @return the {@link ScopeInfo scope} of this bean, never {@code null} + */ ScopeInfo scope(); + /** + * Returns a collection of all {@link Type type}s of this bean. + * + * @return immutable collection of bean types, never {@code null} + */ Collection types(); + /** + * Returns a collection of this bean's qualifiers, represented as {@link AnnotationInfo}. + * + * @return immutable collection of qualifiers, never {@code null} + */ // TODO method(s) for getting AnnotationInfo for given qualifier class? Collection qualifiers(); /** - * Returns the class that declares the bean. - * In case of a bean defined by a class, that is the bean class directly. + * Returns the class that declares this bean. + * In case of a managed bean, also known as class-based bean, that is the bean class directly. * In case of a producer method or field, that is the class that declares the producer method or field. - * TODO null for synthetic beans, or return Optional? + * Returns {@code null} if this bean is synthetic. * - * @return {@link ClassInfo} for the class that declares the bean + * @return {@link ClassInfo} for the class that declares this bean, or {@code null} if this bean is synthetic */ - ClassInfo declaringClass(); + ClassInfo declaringClass(); + /** + * Returns whether this bean is a managed bean, sometimes also called class-based bean. + * + * @return whether this bean is a managed bean + */ boolean isClassBean(); + /** + * Returns whether this bean is defined by a producer method. + * + * @return whether this bean is defined by a producer method + */ boolean isProducerMethod(); + /** + * Returns whether this bean is defined by a producer field. + * + * @return whether this bean is defined by a producer field + */ boolean isProducerField(); + /** + * Returns whether this bean is synthetic. In other words, whether this bean + * doesn't correspond to a declaration in some source code and was created + * through other means (e.g. using an extension). + * + * @return whether this bean is synthetic + */ boolean isSynthetic(); - MethodInfo producerMethod(); // TODO null if not producer method, or return Optional? + /** + * Returns the producer {@link MethodInfo method} that defines this bean. + * Returns {@code null} if this bean isn't defined by a producer method. + * + * @return producer method that defines this bean, or {@code null} if this bean isn't defined by a producer method + */ + MethodInfo producerMethod(); - FieldInfo producerField(); // TODO null if not producer field, or return Optional? + /** + * Returns the producer {@link FieldInfo field} that defines this bean. + * Returns {@code null} if this bean isn't defined by a producer field. + * + * @return producer field that defines this bean, or {@code null} if this bean isn't defined by a producer field + */ + FieldInfo producerField(); + /** + * Returns whether this bean is an {@link jakarta.enterprise.inject.Alternative alternative}. + * + * @return whether this bean is an {@link jakarta.enterprise.inject.Alternative alternative} + */ boolean isAlternative(); + /** + * Returns the {@link jakarta.annotation.Priority priority} of this alternative bean. + * If this bean is not an alternative, the return value is undefined. + * + * @return the priority of this alternative bean + * @see #isAlternative() + */ int priority(); - // EL name (from @Named), IIUC + /** + * Returns the bean name of this bean. A bean name is usually defined + * using the {@link jakarta.inject.Named @Named} annotation. + * Returns {@code null} if the bean doesn't have a name. + * + * @return the bean name, or {@code null} if the bean doesn't have a name + */ String getName(); - DisposerInfo disposer(); // TODO null if not producer method/field, or return Optional? + /** + * Returns the {@link DisposerInfo disposer method} of this producer-based bean. + * Returns {@code null} if this bean is not a defined by a producer method or a producer field, + * or if this producer-based bean doesn't have a corresponding disposer method. + * + * @return the {@link DisposerInfo disposer}, or {@code null} if this bean doesn't have a disposer + */ + DisposerInfo disposer(); + /** + * Returns a collection of this bean's {@link StereotypeInfo stereotype}s. + * + * @return immutable collection of stereotypes, never {@code null} + */ Collection stereotypes(); // TODO interceptors? + /** + * Returns a collection of this bean's {@link InjectionPointInfo injection point}s. + * + * @return immutable collection of injection points, never {@code null} + */ Collection injectionPoints(); } diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ClassConfig.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ClassConfig.java index 8c35dfaa..8af23e28 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ClassConfig.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ClassConfig.java @@ -5,23 +5,42 @@ import java.util.Collection; /** - * @param the configured class + * Allows adding annotations to and removing annotations from a class. + * Note that the class is not physically altered, the modifications + * are only seen by the CDI container. + * + * @see Enhancement */ -public interface ClassConfig extends ClassInfo, AnnotationConfig { - // TODO remove the type parameter? - // TODO even if ClassInfo has equals/hashCode, ClassConfig probably shouldn't - - // only constructors declared by this class, not inherited ones - // no [static] initializers +public interface ClassConfig extends DeclarationConfig { + /** + * Returns the {@link ClassInfo read-only information} about this transformed class. + * + * @return the {@link ClassInfo} corresponding to this transformed class, never {@code null} + */ @Override - Collection> constructors(); + ClassInfo info(); - // only methods declared by this class, not inherited ones - // no constructors nor [static] initializers - @Override - Collection> methods(); + /** + * Returns a collection of {@link MethodConfig} objects for each constructor of this class. + * + * @return immutable collection of {@link MethodConfig} objects, never {@code null} + */ + // TODO specify whether inherited constructors are also included + Collection constructors(); - // only fields declared by this class, not inherited ones - @Override - Collection> fields(); + /** + * Returns a collection of {@link MethodConfig} objects for each method of this class. + * + * @return immutable collection of {@link MethodConfig} objects, never {@code null} + */ + // TODO specify whether inherited methods are also included + Collection methods(); + + /** + * Returns a collection of {@link FieldConfig} objects for each field of this class. + * + * @return immutable collection of {@link FieldConfig} objects, never {@code null} + */ + // TODO specify whether inherited fields are also included + Collection fields(); } diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/DeclarationConfig.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/DeclarationConfig.java new file mode 100644 index 00000000..4d0e3864 --- /dev/null +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/DeclarationConfig.java @@ -0,0 +1,65 @@ +package jakarta.enterprise.inject.build.compatible.spi; + +import jakarta.enterprise.lang.model.AnnotationInfo; +import jakarta.enterprise.lang.model.declarations.DeclarationInfo; + +import java.lang.annotation.Annotation; +import java.util.function.Predicate; + +/** + * Allows adding annotations to and removing annotations from a declaration. + * Note that the declaration is not physically altered, the modifications + * are only seen by the CDI container. + * + * @see Enhancement + */ +public interface DeclarationConfig> { + /** + * Returns the {@link DeclarationInfo read-only information} about this transformed declaration. + * + * @return the {@link DeclarationInfo} corresponding to this transformed declaration, never {@code null} + */ + DeclarationInfo info(); + + /** + * Adds a marker annotation of given type to this declaration. + * Doesn't allow configuring annotation members. + * + * @param annotationType the annotation type, must not be {@code null} + * @return this configurator object, to allow fluent usage + */ + THIS addAnnotation(Class annotationType); + + /** + * Adds given annotation to this declaration. The {@link AnnotationInfo} can be obtained + * from an annotation target, or constructed from scratch using {@link AnnotationBuilder}. + * + * @param annotation the annotation to add to this declaration, must not be {@code null} + * @return this configurator object, to allow fluent usage + */ + THIS addAnnotation(AnnotationInfo annotation); + + /** + * Adds given annotation to this declaration. The annotation instance is typically + * a subclass of {@link jakarta.enterprise.util.AnnotationLiteral AnnotationLiteral}. + * + * @param annotation the annotation to add to this declaration, must not be {@code null} + * @return this configurator object, to allow fluent usage + */ + THIS addAnnotation(Annotation annotation); + + /** + * Removes all annotations matching given predicate from this declaration. + * + * @param predicate an annotation predicate, must not be {@code null} + * @return this configurator object, to allow fluent usage + */ + THIS removeAnnotation(Predicate predicate); + + /** + * Removes all annotations from this declaration. + * + * @return this configurator object, to allow fluent usage + */ + THIS removeAllAnnotations(); +} diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/DisposerInfo.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/DisposerInfo.java index a4aeaaed..e0997ce2 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/DisposerInfo.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/DisposerInfo.java @@ -3,8 +3,21 @@ import jakarta.enterprise.lang.model.declarations.MethodInfo; import jakarta.enterprise.lang.model.declarations.ParameterInfo; +/** + * Provides read-only information about a disposer method. + */ public interface DisposerInfo { - MethodInfo disposerMethod(); + /** + * Returns this disposer method represented as {@link MethodInfo}. + * + * @return the {@link MethodInfo}, never {@code null} + */ + MethodInfo disposerMethod(); + /** + * Returns the disposed parameter of this disposer method. + * + * @return the disposed parameter, never {@code null} + */ ParameterInfo disposedParameter(); } 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 787eff0b..e868258f 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 @@ -11,9 +11,10 @@ *

* Methods annotated {@code @Enhancement} must define exactly one parameter of one of these types: *

    - *
  • {@link ClassConfig ClassConfig}
  • - *
  • {@link MethodConfig MethodConfig}
  • - *
  • {@link FieldConfig FieldConfig}
  • + *
  • {@link DeclarationConfig} or {@link jakarta.enterprise.lang.model.declarations.DeclarationInfo DeclarationInfo}
  • + *
  • {@link ClassConfig} or {@link jakarta.enterprise.lang.model.declarations.ClassInfo ClassInfo}
  • + *
  • {@link MethodConfig} or {@link jakarta.enterprise.lang.model.declarations.MethodInfo MethodInfo}
  • + *
  • {@link FieldConfig} or {@link jakarta.enterprise.lang.model.declarations.FieldInfo FieldInfo}
  • *
* The method must also have at least one annotation {@link ExactType @ExactType} or {@link SubtypesOf @SubtypesOf}. *

diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/FieldConfig.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/FieldConfig.java index ff53e178..3113e0f8 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/FieldConfig.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/FieldConfig.java @@ -3,9 +3,18 @@ import jakarta.enterprise.lang.model.declarations.FieldInfo; /** - * @param type of whomever declares the configured field + * Allows adding annotations to and removing annotations from a field. + * Note that the field is not physically altered, the modifications + * are only seen by the CDI container. + * + * @see Enhancement */ -public interface FieldConfig extends FieldInfo, AnnotationConfig { - // TODO remove the type parameter? - // TODO even if FieldInfo has equals/hashCode, FieldConfig probably shouldn't +public interface FieldConfig extends DeclarationConfig { + /** + * Returns the {@link FieldInfo read-only information} about this transformed field. + * + * @return the {@link FieldInfo} corresponding to this transformed field, never {@code null} + */ + @Override + FieldInfo info(); } diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InjectionPointInfo.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InjectionPointInfo.java index af4e9d0f..e61b07ee 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InjectionPointInfo.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/InjectionPointInfo.java @@ -5,14 +5,28 @@ import jakarta.enterprise.lang.model.types.Type; import java.util.Collection; +/** + * Provides read-only information about an injection point. + */ public interface InjectionPointInfo { + /** + * Returns the {@link Type type} of this injection point. + * + * @return the type of this injection point, never {@code null} + */ Type type(); + /** + * Returns a collection of qualifiers declared on this injection point, represented as {@link AnnotationInfo}. + * + * @return collection of qualifiers, never {@code null} + */ // TODO method(s) for getting AnnotationInfo for given qualifier class? Collection qualifiers(); /** - * Returns a {@code FieldInfo} for field injection, or {@code ParameterInfo} for: + * Returns the declaration of this injection point. That is a {@link jakarta.enterprise.lang.model.declarations.FieldInfo FieldInfo} + * for field injection, or {@link jakarta.enterprise.lang.model.declarations.ParameterInfo ParameterInfo} for: *

    *
  • constructor injection,
  • *
  • initializer method,
  • @@ -21,7 +35,7 @@ public interface InjectionPointInfo { *
  • observer method.
  • *
* - * @return declaration of this injection point + * @return the declaration of this injection point, never {@code null} */ DeclarationInfo declaration(); } diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Messages.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Messages.java index b2695f67..edbe1d4a 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Messages.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Messages.java @@ -29,7 +29,7 @@ public interface Messages { * @param message information message * @param relatedTo bean to which the message is related */ - void info(String message, BeanInfo relatedTo); + void info(String message, BeanInfo relatedTo); /** * Add an information message which is related to given {@link ObserverInfo}. @@ -37,7 +37,7 @@ public interface Messages { * @param message information message * @param relatedTo observer to which the message is related */ - void info(String message, ObserverInfo relatedTo); + void info(String message, ObserverInfo relatedTo); /** * Add a generic warning that is not related to any particular element, or that information is not known. @@ -61,7 +61,7 @@ public interface Messages { * @param message warning message * @param relatedTo bean to which the message is related */ - void warn(String message, BeanInfo relatedTo); + void warn(String message, BeanInfo relatedTo); /** * Add a warning which is related to given {@link ObserverInfo}. @@ -69,7 +69,7 @@ public interface Messages { * @param message warning message * @param relatedTo observer to which the message is related */ - void warn(String message, ObserverInfo relatedTo); + void warn(String message, ObserverInfo relatedTo); /** * Add a generic error that is not related to any particular element, or that information is not known. @@ -93,7 +93,7 @@ public interface Messages { * @param message error message * @param relatedTo bean to which the message is related */ - void error(String message, BeanInfo relatedTo); + void error(String message, BeanInfo relatedTo); /** * Add an error which is related to given {@link ObserverInfo}. @@ -101,7 +101,7 @@ public interface Messages { * @param message error message * @param relatedTo observer to which the message is related */ - void error(String message, ObserverInfo relatedTo); + void error(String message, ObserverInfo relatedTo); /** * Add a generic error that is represented by an exception. diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MetaAnnotations.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MetaAnnotations.java index 2f677156..77ea27e7 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MetaAnnotations.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MetaAnnotations.java @@ -23,7 +23,7 @@ public interface MetaAnnotations { * @param annotation annotation type * @param config allows transforming annotations on the {@code annotation} */ - void addQualifier(Class annotation, Consumer> config); + void addQualifier(Class annotation, Consumer config); /** * Registers {@code annotation} as an interceptor binding annotation. Only makes sense if the annotation @@ -32,7 +32,7 @@ public interface MetaAnnotations { * @param annotation annotation type * @param config allows transforming annotations on the {@code annotation} */ - void addInterceptorBinding(Class annotation, Consumer> config); + void addInterceptorBinding(Class annotation, Consumer config); /** * Registers {@code annotation} as a stereotype annotation. Only makes sense if the annotation @@ -41,7 +41,7 @@ public interface MetaAnnotations { * @param annotation annotation type * @param config allows transforming annotations on the {@code annotation} */ - void addStereotype(Class annotation, Consumer> config); + void addStereotype(Class annotation, Consumer config); /** * Registers custom context as configured by the returned {@link ContextConfig}. diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MethodConfig.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MethodConfig.java index 7c5ee0f2..babf24d9 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MethodConfig.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MethodConfig.java @@ -3,10 +3,20 @@ import jakarta.enterprise.lang.model.declarations.MethodInfo; /** - * @param type of whomever declares the configured method or constructor + * Allows adding annotations to and removing annotations from a method. + * Note that the method is not physically altered, the modifications + * are only seen by the CDI container. + * + * @see Enhancement */ -public interface MethodConfig extends MethodInfo, AnnotationConfig { - // TODO remove the type parameter? +public interface MethodConfig extends DeclarationConfig { // TODO split MethodConfig into MethodConfig/ConstructorConfig? - // TODO even if MethodInfo has equals/hashCode, MethodConfig probably shouldn't + + /** + * Returns the {@link MethodInfo read-only information} about this transformed method. + * + * @return the {@link MethodInfo} corresponding to this transformed method, never {@code null} + */ + @Override + MethodInfo info(); } diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ObserverInfo.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ObserverInfo.java index 114fdb10..20a6f232 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ObserverInfo.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ObserverInfo.java @@ -10,35 +10,101 @@ import jakarta.enterprise.event.TransactionPhase; /** - * @param type observed by the inspected observer + * Provides read-only information about an observer. */ -public interface ObserverInfo { - // TODO remove the type parameter? - +public interface ObserverInfo { String id(); // TODO remove entirely? + /** + * Returns the type of events observed by this observer. + * + * @return the type of events observed by this observer, never {@code null} + */ Type observedType(); + /** + * Returns a collection of this observer's qualifiers, represented as {@link AnnotationInfo}. + * + * @return immutable collection of qualifiers, never {@code null} + */ // TODO method(s) for getting AnnotationInfo for given qualifier class? Collection qualifiers(); - ClassInfo declaringClass(); // never null, even if synthetic + /** + * Returns the {@link ClassInfo class} that declares this observer. + * In case of synthetic observers, returns the class that was designated + * as a declaring class during synthetic observer registration. + * + * @return the class that declares this observer, never {@code null} + */ + ClassInfo declaringClass(); - MethodInfo observerMethod(); // TODO null for synthetic observers, or return Optional? see also isSynthetic below + /** + * Returns the observer method, if this observer corresponds to an observer method. + * Returns {@code null} if this is a synthetic observer. + * + * @return the observer method, or {@code null} if this is a synthetic observer + */ + MethodInfo observerMethod(); - ParameterInfo eventParameter(); // TODO null for synthetic observers, or return Optional? see also isSynthetic below + /** + * Returns the event parameter of the observer method, if this observer corresponds to an observer method. + * Returns {@code null} if this is a synthetic observer. + * + * @return the event parameter of the observer method, or {@code null} if this is a synthetic observer + */ + ParameterInfo eventParameter(); - BeanInfo bean(); // TODO null for synthetic observers, or return Optional? see also isSynthetic below + /** + * Returns the {@link BeanInfo bean} that declares this observer, if it corresponds to an observer method. + * Returns {@code null} if this is a synthetic observer. + * + * @return the bean declaring this observer, or {@code null} if this is a synthetic observer + */ + BeanInfo bean(); + /** + * Returns whether this observer is synthetic. In other words, whether this observer + * doesn't correspond to a declaration in some source code and was created + * through other means (e.g. using an extension). + * + * @return whether this observer is synthetic + */ default boolean isSynthetic() { return bean() == null; } + /** + * Returns the priority of this observer. This is typically defined by adding + * the {@link jakarta.annotation.Priority @Priority} annotation to the event parameter of the observer. + * If the annotation is not used, the default priority, as defined by the CDI specification, is returned, + * + * @return the priority of this observer + */ int priority(); + /** + * Returns whether this observer is asynchronous, that is, whether this observer + * was declared using {@link jakarta.enterprise.event.ObservesAsync @ObservesAsync}. + * + * @return whether this observer is asynchronous + */ boolean isAsync(); + /** + * Returns the {@link Reception reception type} of this observer. Allows distinguishing + * conditional observer methods from always notified observer methods. + * + * @return the reception type of this observer + */ Reception reception(); + /** + * Returns the {@link TransactionPhase transaction phase} of this transactional observer. + * Returns {@link TransactionPhase#IN_PROGRESS} if this is a regular synchronous observer. + * Returns {@code null} if this is an asynchronous observer. + * + * @return the transaction phase of this observer, or {@code null} if this is an asynchronous observer + */ TransactionPhase transactionPhase(); } diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ScopeInfo.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ScopeInfo.java index b0a88c06..3fc964c0 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ScopeInfo.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ScopeInfo.java @@ -2,30 +2,33 @@ import jakarta.enterprise.lang.model.declarations.ClassInfo; +/** + * Provides read-only information about bean's scope. + */ public interface ScopeInfo { /** - * Returns the declaration of this scope annotation's type. + * Returns the declaration of this scope annotation. * - * @return declaration of this scope annotation's type, never {@code null} + * @return declaration of this scope annotation, never {@code null} */ - ClassInfo annotation(); + ClassInfo annotation(); /** - * Binary name of this scope annotation's type, as defined by The Java™ Language Specification; - * in other words, the scope annotation type name as returned by {@link Class#getName()}. + * Binary name of this scope annotation, as defined by The Java™ Language Specification; + * in other words, the scope annotation name as returned by {@link Class#getName()}. * Equivalent to {@code annotation().name()}. * - * @return binary name of this scope annotation's type, never {@code null} + * @return binary name of this scope annotation, never {@code null} */ default String name() { return annotation().name(); } /** - * Returns whether the scope is normal. In other words, returns whether - * the scope annotation type is meta-annotated {@code @NormalScope}. + * Returns whether this scope is normal. In other words, returns whether + * this scope annotation is meta-annotated {@code @NormalScope}. * - * @return whether the scope is normal + * @return whether this scope is normal */ boolean isNormal(); } 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 148b27c6..a2352679 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 @@ -19,7 +19,7 @@ public interface SyntheticBeanBuilder { // TODO methods to add multiple types at once? SyntheticBeanBuilder type(Class type); - SyntheticBeanBuilder type(ClassInfo type); + SyntheticBeanBuilder type(ClassInfo type); SyntheticBeanBuilder type(Type type); @@ -27,7 +27,7 @@ public interface SyntheticBeanBuilder { // TODO methods to add multiple qualifiers at once? SyntheticBeanBuilder qualifier(Class annotationType); // for marker annotations - SyntheticBeanBuilder qualifier(AnnotationInfo qualifierAnnotation); + SyntheticBeanBuilder qualifier(AnnotationInfo qualifierAnnotation); SyntheticBeanBuilder qualifier(Annotation qualifierAnnotation); @@ -50,7 +50,7 @@ public interface SyntheticBeanBuilder { // can be called multiple times and is additive SyntheticBeanBuilder stereotype(Class stereotypeAnnotation); - SyntheticBeanBuilder stereotype(ClassInfo stereotypeAnnotation); + SyntheticBeanBuilder stereotype(ClassInfo stereotypeAnnotation); // params for creation and destruction functions SyntheticBeanBuilder withParam(String key, boolean value); 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 8aeacbad..a90231d9 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 @@ -28,13 +28,13 @@ public interface SyntheticObserverBuilder { // if called multiple times, last call wins SyntheticObserverBuilder declaringClass(Class declaringClass); - SyntheticObserverBuilder declaringClass(ClassInfo declaringClass); + SyntheticObserverBuilder declaringClass(ClassInfo declaringClass); // if called multiple times, last call wins // TODO methods to add multiple types at once? SyntheticObserverBuilder type(Class type); - SyntheticObserverBuilder type(ClassInfo type); + SyntheticObserverBuilder type(ClassInfo type); SyntheticObserverBuilder type(Type type); @@ -42,7 +42,7 @@ public interface SyntheticObserverBuilder { // TODO methods to add multiple qualifiers at once? SyntheticObserverBuilder qualifier(Class annotationType); // for marker annotations - SyntheticObserverBuilder qualifier(AnnotationInfo qualifierAnnotation); + SyntheticObserverBuilder qualifier(AnnotationInfo qualifierAnnotation); SyntheticObserverBuilder qualifier(Annotation qualifierAnnotation); diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Types.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Types.java index 54ca1ca5..c672c653 100644 --- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Types.java +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/Types.java @@ -26,7 +26,7 @@ public interface Types { Type ofPrimitive(PrimitiveType.PrimitiveKind kind); - Type ofClass(ClassInfo clazz); + Type ofClass(ClassInfo clazz); Type ofArray(Type componentType, int dimensions); 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 c42b9078..6338fd22 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationInfo.java @@ -2,18 +2,14 @@ import jakarta.enterprise.lang.model.declarations.ClassInfo; -import java.lang.annotation.Annotation; import java.lang.annotation.Repeatable; import java.util.Map; /** * An annotation instance, typically obtained from an {@link AnnotationTarget}. * Provides access to annotation members and their values. - * - * @param the annotation type */ -// TODO does this have to be parameterized? -public interface AnnotationInfo { +public interface AnnotationInfo { /** * Name of the commonly used {@code value()} annotation member. */ @@ -24,7 +20,7 @@ public interface AnnotationInfo { * * @return declaration of this annotation's type, never {@code null} */ - ClassInfo declaration(); + ClassInfo declaration(); /** * Binary name of this annotation's type, as defined by The Java™ Language Specification; 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 db298bb3..8bdac9ff 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationMember.java @@ -275,12 +275,12 @@ default boolean isArray() { * @return a {@link ClassInfo} representing the enum type * @throws IllegalStateException if this annotation member value is not an enum value */ - ClassInfo asEnumClass(); + ClassInfo asEnumClass(); /** - * Returns the name (also known as enum constant) of this enum value. + * Returns the name of this enum value (also known as enum constant). * - * @return the enum constant + * @return the name of this enum constant * @throws IllegalStateException if this annotation member value is not an enum value */ String asEnumConstant(); @@ -306,7 +306,7 @@ default boolean isArray() { * @return an {@link AnnotationInfo} instance * @throws IllegalStateException if this annotation member value is not a nested annotation */ - AnnotationInfo asNestedAnnotation(); + AnnotationInfo asNestedAnnotation(); /** * Returns this array value as an immutable {@link List} of {@link AnnotationMember}s. 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 f7cabc04..010cd8d6 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/AnnotationTarget.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/AnnotationTarget.java @@ -74,7 +74,7 @@ public interface AnnotationTarget { * @param predicate annotation predicate, must not be {@code null} * @return {@code true} if given predicate matches any annotation present on this annotation target, {@code false} otherwise. */ - boolean hasAnnotation(Predicate> predicate); + boolean hasAnnotation(Predicate predicate); /** * Returns an annotation of given type, if it is present on this annotation target. @@ -83,7 +83,7 @@ public interface AnnotationTarget { * @param the annotation generic type * @return the {@link AnnotationInfo} or {@code null} if no such annotation is present on this annotation target */ - AnnotationInfo annotation(Class annotationType); + AnnotationInfo annotation(Class annotationType); /** * Returns a collection of annotations of given repeatable annotation type @@ -95,7 +95,7 @@ public interface AnnotationTarget { * @param the annotation generic type * @return immutable collection of {@link AnnotationInfo}, never {@code null} */ - Collection> repeatableAnnotation(Class annotationType); + Collection repeatableAnnotation(Class annotationType); /** * Returns a collection of all annotations present on this annotation target that match given predicate. @@ -104,7 +104,7 @@ public interface AnnotationTarget { * @param predicate annotation predicate, must not be {@code null} * @return immutable collection of {@link AnnotationInfo}, never {@code null} */ - Collection> annotations(Predicate> predicate); + Collection annotations(Predicate predicate); /** * Returns a collection of all annotations present on this annotation target. @@ -112,5 +112,5 @@ public interface AnnotationTarget { * * @return immutable collection of {@link AnnotationInfo}, never {@code null} */ - Collection> annotations(); + Collection annotations(); } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/declarations/ClassInfo.java b/api/src/main/java/jakarta/enterprise/lang/model/declarations/ClassInfo.java index 61a36753..29ad4653 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/declarations/ClassInfo.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/declarations/ClassInfo.java @@ -7,10 +7,15 @@ import java.util.List; /** - * @param the inspected class + * Provides read-only information about a class. As of Java™ 11, there are 4 kinds of classes: + *
    + *
  • plain classes,
  • + *
  • interfaces,
  • + *
  • enums (specialized kind of plain classes),
  • + *
  • annotations (specialized kind of interfaces).
  • + *
*/ -public interface ClassInfo extends DeclarationInfo { - // TODO remove the type parameter? +public interface ClassInfo extends DeclarationInfo { // TODO nested classes don't provide access to enclosing class, but that might be OK for our purposes? /** @@ -29,50 +34,138 @@ public interface ClassInfo extends DeclarationInfo { */ String simpleName(); + /** + * Returns the {@link PackageInfo package} this class is part of. + * Returns {@code null} if this class is part of an unnamed package. + * + * @return this class' package, or {@code null} if this class is in an unnamed package + */ PackageInfo packageInfo(); - // empty if class is not parameterized + /** + * Returns a list of {@link TypeVariable type parameters} declared on this class. + * Returns an empty list if this class is not parameterized. + * + * @return immutable list of this class' type parameters, never {@code null} + */ List typeParameters(); - // null if this class doesn't have a superclass (e.g. is Object or an interface) - // TODO or Optional? + /** + * Returns the {@link Type type} of this class' superclass. Returns {@code null} if this class + * doesn't have a superclass; that is, if this class is {@code java.lang.Object} or an interface. + * + * @return the type of this class' superclass, or {@code null} if there's no superclass + */ Type superClass(); - // null if this class doesn't have a superclass (e.g. is Object or an interface) - // TODO or Optional? - ClassInfo superClassDeclaration(); + /** + * Returns the {@link ClassInfo declaration} of this class' superclass. Returns {@code null} if this class + * doesn't have a superclass; that is, if this class is {@code java.lang.Object} or an interface. + * + * @return the declaration of this class' superclass, or {@code null} if there's no superclass + */ + ClassInfo superClassDeclaration(); - // empty if the class has no superinterfaces + /** + * Returns a list of {@link Type type}s of this class' direct superinterfaces. Returns an empty list + * if this class has no direct superinterface. + * + * @return immutable list of types of this class' direct superinterfaces, never {@code null} + */ List superInterfaces(); - // empty if the class has no superinterfaces - List> superInterfacesDeclarations(); + /** + * Returns a list of {@link ClassInfo declaration}s of this class' direct superinterfaces. Returns an empty list + * if this class has no direct superinterface. + * + * @return immutable list of declarations of this class' direct superinterfaces, never {@code null} + */ + List superInterfacesDeclarations(); - // TODO better name? + /** + * Returns whether this class is a plain class. That is, not an interface, + * not an enum, and not an annotation. + * + * @return whether this class is a plain class + */ + // TODO better name? "plain class" is my invention boolean isPlainClass(); + /** + * Returns whether this class is an interface. + * + * @return whether this class is an interface + */ boolean isInterface(); + /** + * Returns whether this class is an enum. + * + * @return whether this class is an enum + */ boolean isEnum(); + /** + * Returns whether this class is an annotation. + * + * @return whether this class is an annotation + */ boolean isAnnotation(); + /** + * Returns whether this class is {@code abstract}. + * + * @return whether this class is {@code abstract} + */ boolean isAbstract(); + /** + * Returns whether this class is {@code final}. + * + * @return whether this class is {@code final} + */ boolean isFinal(); + /** + * Returns the {@link java.lang.reflect.Modifier modifier}s declared on this class. + * + * @return the class modifiers + */ int modifiers(); - // only constructors declared by this class, not inherited ones - // no [static] initializers - Collection> constructors(); + /** + * Returns a collection of {@link MethodInfo constructor}s declared in this class. + * Constructors declared in direct or indirect superclasses are not included. + * + * @return immutable collection of constructors, never {@code null} + */ + Collection constructors(); - // only methods declared by this class, not inherited ones - // no constructors nor [static] initializers - Collection> methods(); + /** + * Returns a collection of {@link MethodInfo method}s declared in this class and all + * its superclasses up to and excluding {@code java.lang.Object}. This includes + * {@code private} methods declared by superclasses. Constructors are not included. + *

+ * Also, {@code default} methods declared in all direct and indirect superinterfaces + * of this class are included. Abstract or {@code private} methods declared in interfaces + * are not included. + * TODO this rule about interface methods comes from current Weld implementation and needs more thinking + * + * @return immutable collection of methods, never {@code null} + */ + Collection methods(); - // only fields declared by this class, not inherited ones - Collection> fields(); + /** + * Returns a collection of {@link FieldInfo field}s declared in this class and all + * its superclasses up to and excluding {@code java.lang.Object}. This includes + * {@code private} fields declared in superclasses. + *

+ * Fields declared in superinterfaces are not included. + * TODO this rule about interface fields comes from current Weld implementation and needs more thinking + * + * @return immutable collection of fields, never {@code null} + */ + Collection fields(); // --- @@ -82,7 +175,7 @@ default Kind kind() { } @Override - default ClassInfo asClass() { + default ClassInfo asClass() { return this; } } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/declarations/DeclarationInfo.java b/api/src/main/java/jakarta/enterprise/lang/model/declarations/DeclarationInfo.java index 7a1b7773..67594737 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/declarations/DeclarationInfo.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/declarations/DeclarationInfo.java @@ -47,45 +47,105 @@ enum Kind { FIELD, } + /** + * Returns the {@link Kind kind} of this declaration. + * + * @return the kind of this declaration + */ Kind kind(); + /** + * Returns whether this declaration is a {@link PackageInfo package}. + * + * @return {@code true} if this is a package, {@code false} otherwise + */ default boolean isPackage() { return kind() == Kind.PACKAGE; } + /** + * Returns whether this declaration is a {@link ClassInfo class}. + * + * @return {@code true} if this is a class, {@code false} otherwise + */ default boolean isClass() { return kind() == Kind.CLASS; } + /** + * Returns whether this declaration is a {@link MethodInfo method}. + * + * @return {@code true} if this is a method, {@code false} otherwise + */ default boolean isMethod() { return kind() == Kind.METHOD; } + /** + * Returns whether this declaration is a {@link ParameterInfo method parameter}. + * + * @return {@code true} if this is a parameter, {@code false} otherwise + */ default boolean isParameter() { return kind() == Kind.PARAMETER; } + /** + * Returns whether this declaration is a {@link FieldInfo field}. + * + * @return {@code true} if this is a field, {@code false} otherwise + */ default boolean isField() { return kind() == Kind.FIELD; } + /** + * Returns this declaration as a {@link PackageInfo package}. + * + * @return this package, never {@code null} + * @throws IllegalStateException if {@link #isPackage()} returns {@code false} + */ default PackageInfo asPackage() { throw new IllegalStateException("Not a package"); } - default ClassInfo asClass() { + /** + * Returns this declaration as a {@link ClassInfo class}. + * + * @return this class, never {@code null} + * @throws IllegalStateException if {@link #isClass()} returns {@code false} + */ + default ClassInfo asClass() { throw new IllegalStateException("Not a class"); } - default MethodInfo asMethod() { + /** + * Returns this declaration as a {@link MethodInfo method}. + * + * @return this method, never {@code null} + * @throws IllegalStateException if {@link #isMethod()} returns {@code false} + */ + default MethodInfo asMethod() { throw new IllegalStateException("Not a method"); } + /** + * Returns this declaration as a {@link ParameterInfo method parameter}. + * + * @return this parameter, never {@code null} + * @throws IllegalStateException if {@link #isParameter()} returns {@code false} + */ default ParameterInfo asParameter() { throw new IllegalStateException("Not a parameter"); } - default FieldInfo asField() { + /** + * Returns this declaration as a {@link FieldInfo field}. + * + * @return this field, never {@code null} + * @throws IllegalStateException if {@link #isField()} returns {@code false} + */ + default FieldInfo asField() { throw new IllegalStateException("Not a field"); } } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/declarations/FieldInfo.java b/api/src/main/java/jakarta/enterprise/lang/model/declarations/FieldInfo.java index afbeaf06..a75f832d 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/declarations/FieldInfo.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/declarations/FieldInfo.java @@ -3,11 +3,9 @@ import jakarta.enterprise.lang.model.types.Type; /** - * @param type of whomever declares the inspected field + * Provides read-only information about a field. */ -public interface FieldInfo extends DeclarationInfo { - // TODO remove the type parameter? - +public interface FieldInfo extends DeclarationInfo { String name(); Type type(); @@ -18,7 +16,7 @@ public interface FieldInfo extends DeclarationInfo { int modifiers(); - ClassInfo declaringClass(); + ClassInfo declaringClass(); // --- @@ -28,7 +26,7 @@ default Kind kind() { } @Override - default FieldInfo asField() { + default FieldInfo asField() { return this; } } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/declarations/MethodInfo.java b/api/src/main/java/jakarta/enterprise/lang/model/declarations/MethodInfo.java index 2f446fe8..0a8866f9 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/declarations/MethodInfo.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/declarations/MethodInfo.java @@ -6,10 +6,9 @@ import java.util.Optional; /** - * @param type of whomever declares the inspected method or constructor + * Provides read-only information about a method. */ -public interface MethodInfo extends DeclarationInfo { - // TODO remove the type parameter? +public interface MethodInfo extends DeclarationInfo { // TODO split MethodInfo into MethodInfo/ConstructorInfo? a lot of methods here don't make sense for constructors, // plus existing APIs (Core Reflection, CDI Portable Extensions) also make this distinction @@ -37,7 +36,7 @@ public interface MethodInfo extends DeclarationInfo { int modifiers(); - ClassInfo declaringClass(); + ClassInfo declaringClass(); // --- @@ -47,7 +46,7 @@ default Kind kind() { } @Override - default MethodInfo asMethod() { + default MethodInfo asMethod() { return this; } } diff --git a/api/src/main/java/jakarta/enterprise/lang/model/declarations/PackageInfo.java b/api/src/main/java/jakarta/enterprise/lang/model/declarations/PackageInfo.java index 0e54f5ed..ac32fd85 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/declarations/PackageInfo.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/declarations/PackageInfo.java @@ -1,7 +1,16 @@ package jakarta.enterprise.lang.model.declarations; +/** + * Provides read-only information about a package. + */ // TODO is this useful? perhaps `ClassInfo.packageName` returning a `String` would be enough? public interface PackageInfo extends DeclarationInfo { + /** + * Returns the fully qualified name of this package, as defined by The Java™ Language Specification; + * in other words, the package name as returned by {@link Package#getName()}. + * + * @return fully qualified name of this package, never {@code null} + */ String name(); // --- diff --git a/api/src/main/java/jakarta/enterprise/lang/model/declarations/ParameterInfo.java b/api/src/main/java/jakarta/enterprise/lang/model/declarations/ParameterInfo.java index c7226083..8dfca718 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/declarations/ParameterInfo.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/declarations/ParameterInfo.java @@ -2,12 +2,32 @@ import jakarta.enterprise.lang.model.types.Type; +/** + * Provides read-only information about a method parameter. + */ public interface ParameterInfo extends DeclarationInfo { - String name(); // TODO doesn't have to be known + /** + * Returns the name of this parameter, if it is known. Method parameter names may not always be known, + * in which case a synthetic name of the form {@code argN}, where {@code N} is zero-based parameter position + * in the method declaration, is returned. + * + * @return the name of this parameter, or a synthetic name, never {@code null} + */ + String name(); + /** + * Returns the {@link Type type} of this parameter. + * + * @return the type of this parameter, never {@code null} + */ Type type(); - MethodInfo declaringMethod(); + /** + * Returns the {@link MethodInfo method} that declares this parameter. + * + * @return the method that declares this parameter, never {@code null} + */ + MethodInfo declaringMethod(); // --- diff --git a/api/src/main/java/jakarta/enterprise/lang/model/types/ClassType.java b/api/src/main/java/jakarta/enterprise/lang/model/types/ClassType.java index 6f208ebb..fdd1cfb7 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/types/ClassType.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/types/ClassType.java @@ -3,7 +3,7 @@ import jakarta.enterprise.lang.model.declarations.ClassInfo; public interface ClassType extends Type { - ClassInfo declaration(); + ClassInfo declaration(); // --- diff --git a/api/src/main/java/jakarta/enterprise/lang/model/types/ParameterizedType.java b/api/src/main/java/jakarta/enterprise/lang/model/types/ParameterizedType.java index 5bab1f45..7d95e4fa 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/types/ParameterizedType.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/types/ParameterizedType.java @@ -4,7 +4,7 @@ import java.util.List; public interface ParameterizedType extends Type { - ClassInfo declaration(); + ClassInfo declaration(); List typeArguments(); diff --git a/api/src/main/java/jakarta/enterprise/lang/model/types/Type.java b/api/src/main/java/jakarta/enterprise/lang/model/types/Type.java index 56c47a85..693b8f9d 100644 --- a/api/src/main/java/jakarta/enterprise/lang/model/types/Type.java +++ b/api/src/main/java/jakarta/enterprise/lang/model/types/Type.java @@ -1,13 +1,15 @@ package jakarta.enterprise.lang.model.types; import jakarta.enterprise.lang.model.AnnotationTarget; +import jakarta.enterprise.lang.model.declarations.ClassInfo; import jakarta.enterprise.lang.model.declarations.DeclarationInfo; +import jakarta.enterprise.lang.model.declarations.PackageInfo; /** * Types are: * *

    - *
  • a void type
  • + *
  • the void type
  • *
  • a primitive type, such as {@code int}
  • *
  • a class type, such as {@code String}
  • *
  • an array type, such as {@code int[]} or {@code String[][]}
  • @@ -57,60 +59,146 @@ enum Kind { WILDCARD_TYPE, } + /** + * Returns the {@link Kind kind} of this type. + * + * @return the kind of this type + */ Kind kind(); + /** + * Returns whether this type is the {@link VoidType void} type. + * + * @return {@code true} if this is void, {@code false} otherwise + */ default boolean isVoid() { return kind() == Kind.VOID; } + /** + * Returns whether this type is a {@link PrimitiveType primitive} type. + * + * @return {@code true} if this is a primitive type, {@code false} otherwise + */ default boolean isPrimitive() { return kind() == Kind.PRIMITIVE; } + /** + * Returns whether this type is a {@link ClassType class} type. + * + * @return {@code true} if this is a class type, {@code false} otherwise + */ default boolean isClass() { return kind() == Kind.CLASS; } + /** + * Returns whether this type is an {@link ArrayType array} type. + * + * @return {@code true} if this is an array type, {@code false} otherwise + */ default boolean isArray() { return kind() == Kind.ARRAY; } + /** + * Returns whether this type is a {@link ParameterizedType parameterized} type. + * + * @return {@code true} if this is a parameterized type, {@code false} otherwise + */ default boolean isParameterizedType() { return kind() == Kind.PARAMETERIZED_TYPE; } + /** + * Returns whether this type is a {@link TypeVariable type variable}. + * Type variables are also used to represent type parameters in declarations + * of parameterized types. + * + * @return {@code true} if this is a primitive type, {@code false} otherwise + */ default boolean isTypeVariable() { return kind() == Kind.TYPE_VARIABLE; } + /** + * Returns whether this type is a {@link WildcardType wildcard} type. + * + * @return {@code true} if this is a wildcard type, {@code false} otherwise + */ default boolean isWildcardType() { return kind() == Kind.WILDCARD_TYPE; } + /** + * Returns this type as the {@link VoidType void} type. + * + * @return this void type, never {@code null} + * @throws IllegalStateException if {@link #isVoid()} returns {@code false} + */ default VoidType asVoid() { throw new IllegalStateException("Not a void"); } + /** + * Returns this type as a {@link PrimitiveType primitive} type. + * + * @return this primitive type, never {@code null} + * @throws IllegalStateException if {@link #isPrimitive()} returns {@code false} + */ default PrimitiveType asPrimitive() { throw new IllegalStateException("Not a primitive"); } + /** + * Returns this type as a {@link ClassType class} type. + * + * @return this class type, never {@code null} + * @throws IllegalStateException if {@link #isClass()} returns {@code false} + */ default ClassType asClass() { throw new IllegalStateException("Not a class"); } + /** + * Returns this type as an {@link ArrayType array} type. + * + * @return this array type, never {@code null} + * @throws IllegalStateException if {@link #isArray()} returns {@code false} + */ default ArrayType asArray() { throw new IllegalStateException("Not an array"); } + /** + * Returns this type as a {@link ParameterizedType parameterized} type. + * + * @return this parameterized type, never {@code null} + * @throws IllegalStateException if {@link #isParameterizedType()} returns {@code false} + */ default ParameterizedType asParameterizedType() { throw new IllegalStateException("Not a parameterized type"); } + /** + * Returns this type as a {@link TypeVariable type variable}. + * Type variables are also used to represent type parameters in declarations + * of parameterized types. + * + * @return this type variable, never {@code null} + * @throws IllegalStateException if {@link #isTypeVariable()} returns {@code false} + */ default TypeVariable asTypeVariable() { throw new IllegalStateException("Not a type variable"); } + /** + * Returns this type as a {@link WildcardType wildcard} type. + * + * @return this wildcard type, never {@code null} + * @throws IllegalStateException if {@link #isWildcardType()} returns {@code false} + */ default WildcardType asWildcardType() { throw new IllegalStateException("Not a wildcard type"); }