From c30a82fa0ef8883a5fdc88a0d6dbe563c545839a Mon Sep 17 00:00:00 2001 From: Stephan Pauxberger Date: Fri, 20 Oct 2023 17:46:41 +0200 Subject: [PATCH] Javadoc --- .../blackbuild/klum/cast/checks/NotOn.java | 8 +++++ .../klum/cast/checks/NotTogetherWith.java | 4 +++ .../klum/cast/checks/NumberOfParameters.java | 7 +++++ .../blackbuild/klum/cast/checks/OnlyOn.java | 7 +++++ .../klum/cast/checks/ParameterTypes.java | 5 ++++ .../klum/cast/checks/impl/KlumCastCheck.java | 30 +++++++++++++++---- .../cast/checks/impl/ValidationException.java | 10 +++++-- .../cast/checks/impl/ParameterTypesCheck.java | 2 ++ .../cast/validation/ValidationHandler.java | 8 ++--- 9 files changed, 68 insertions(+), 13 deletions(-) diff --git a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NotOn.java b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NotOn.java index ec6cd06..dd59c94 100644 --- a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NotOn.java +++ b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NotOn.java @@ -30,9 +30,17 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * Designates the annotated member of an annotation is not allowed when the annotation is placed on the given + * element types. + */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @KlumCastValidator("com.blackbuild.klum.cast.checks.impl.MemberTargetFilter") public @interface NotOn { + /** + * The element types on which the annotated member is not allowed. + * @return the element types on which the annotated member is not allowed. + */ ElementType[] value(); } diff --git a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NotTogetherWith.java b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NotTogetherWith.java index a72993c..41bdf44 100644 --- a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NotTogetherWith.java +++ b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NotTogetherWith.java @@ -52,5 +52,9 @@ @Retention(RetentionPolicy.RUNTIME) @KlumCastValidator("com.blackbuild.klum.cast.checks.impl.NotTogetherWithCheck") public @interface NotTogetherWith { + /** + * The annotations that should not be used together with the annotated annotation. + * @return the annotations that should not be used together with the annotated annotation. + */ Class[] value(); } diff --git a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NumberOfParameters.java b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NumberOfParameters.java index 4592a25..0e4014e 100644 --- a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NumberOfParameters.java +++ b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/NumberOfParameters.java @@ -34,10 +34,17 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * Checks that the annotated methods has exactly the given number of parameters. Note that if the annotated element is no method, the validation is ignored. + */ @Target(ElementType.ANNOTATION_TYPE) @Retention(RetentionPolicy.RUNTIME) @KlumCastValidator(type = NumberOfParameters.Check.class) public @interface NumberOfParameters { + /** + * The number of parameters the annotated method must have. + * @return the number of parameters the annotated method must have. + */ int value(); class Check extends KlumCastCheck { diff --git a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/OnlyOn.java b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/OnlyOn.java index 325dd12..67283bb 100644 --- a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/OnlyOn.java +++ b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/OnlyOn.java @@ -30,9 +30,16 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * Designates the annotated member of an annotation is only allowed when the annotation is placed on the given element types. + */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @KlumCastValidator("com.blackbuild.klum.cast.checks.impl.MemberTargetFilter") public @interface OnlyOn { + /** + * The element types on which the annotated member is allowed. + * @return the element types on which the annotated member is allowed. + */ ElementType[] value(); } diff --git a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/ParameterTypes.java b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/ParameterTypes.java index 885a7f2..cb57b97 100644 --- a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/ParameterTypes.java +++ b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/ParameterTypes.java @@ -30,6 +30,11 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * If the target annotation is placed on a method, the method must have the specified parameter types. Single value + * elements can be null to indicate that the parameter type is not checked. If the annotated method has fewer parameters + * that the number of specified parameter types, the extra parameter types are ignored unless strict is set to true. + */ @Target(ElementType.ANNOTATION_TYPE) @Retention(RetentionPolicy.RUNTIME) @KlumCastValidator("com.blackbuild.klum.cast.checks.impl.ParameterTypesCheck") diff --git a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/impl/KlumCastCheck.java b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/impl/KlumCastCheck.java index f807ca3..862a6b3 100644 --- a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/impl/KlumCastCheck.java +++ b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/impl/KlumCastCheck.java @@ -64,12 +64,15 @@ public void setMemberName(@Nullable String memberName) { /** * Performs the actual check. Checks if the check is applicable for the given target and if so, - * delegates to the doCheck method, wrapping any exceptions thrown in an Error object. + * delegates to the doCheck method, wrapping any exceptions thrown in an ErrorMessage object. + *

+ * Usually it is more convenient to override doCheck instead of this method. + * * @param annotationToCheck The annotation whose placement is validated * @param target the target where the annotation to check is placed - * @return an Optional Error object if the check failed, empty if the check succeeded + * @return an Optional ErrorMessage object if the check failed, empty if the check succeeded */ - public Optional check(AnnotationNode annotationToCheck, AnnotatedNode target) { + public Optional check(AnnotationNode annotationToCheck, AnnotatedNode target) { try { if (isValidFor(target)) doCheck(annotationToCheck, target); @@ -77,21 +80,36 @@ public Optional check(AnnotationNode annotationToCheck, AnnotatedNode tar } catch (ValidationException e) { return Optional.of(e.toError(annotationToCheck)); } catch (RuntimeException e) { - return Optional.of(new Error(e.getMessage(), annotationToCheck)); + return Optional.of(new ErrorMessage(e.getMessage(), annotationToCheck)); } } + /** + * Checks if the check is applicable for the given target. By default, this is always true, but can be overidden for + * quick testing. + * @param target The target where the annotation to validate is placed. + * @return true if the check is applicable for the given target. + */ protected boolean isValidFor(AnnotatedNode target) { return true; } + /** + * Performs the actual check. If the check fails, a {@link ValidationException} or any Runtime exception should be thrown. + * @param annotationToCheck The annotation whose placement is validated + * @param target the target where the annotation to check is placed + * @throws ValidationException if the check fails + */ protected abstract void doCheck(AnnotationNode annotationToCheck, AnnotatedNode target) throws ValidationException; - public static class Error { + /** + * Encapsulates an error message and the node where the error occurred. Usually needs not to be used directly + */ + public static class ErrorMessage { public final String message; public final ASTNode node; - public Error(String message, ASTNode node) { + public ErrorMessage(String message, ASTNode node) { this.message = message; this.node = node; } diff --git a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/impl/ValidationException.java b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/impl/ValidationException.java index c337905..2bb1028 100644 --- a/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/impl/ValidationException.java +++ b/klum-cast-annotations/src/main/java/com/blackbuild/klum/cast/checks/impl/ValidationException.java @@ -25,7 +25,11 @@ import org.codehaus.groovy.ast.ASTNode; -public class ValidationException extends RuntimeException { +/** + * Exception that can be thrown to signal a validation error. Currently the only difference to a normal exception is + * the option to provide an ASTNode that is used as the position of the error (which defaults to the validated annotation). + */ +public class ValidationException extends Exception { private final ASTNode position; public ValidationException(String message) { @@ -49,7 +53,7 @@ public ValidationException(Throwable cause) { this(cause.getMessage(), cause, null); } - public KlumCastCheck.Error toError(ASTNode position) { - return new KlumCastCheck.Error(getMessage(), this.position != null ? this.position : position); + public KlumCastCheck.ErrorMessage toError(ASTNode position) { + return new KlumCastCheck.ErrorMessage(getMessage(), this.position != null ? this.position : position); } } diff --git a/klum-cast-compile/src/main/java/com/blackbuild/klum/cast/checks/impl/ParameterTypesCheck.java b/klum-cast-compile/src/main/java/com/blackbuild/klum/cast/checks/impl/ParameterTypesCheck.java index d78363b..432fa8a 100644 --- a/klum-cast-compile/src/main/java/com/blackbuild/klum/cast/checks/impl/ParameterTypesCheck.java +++ b/klum-cast-compile/src/main/java/com/blackbuild/klum/cast/checks/impl/ParameterTypesCheck.java @@ -47,6 +47,8 @@ protected void doCheck(AnnotationNode annotationToCheck, AnnotatedNode target) { for (int i = 0; i < method.getParameters().length; i++) { if (i >= requiredTypes.length) break; + if (requiredTypes[i] == null) + continue; if (!AstSupport.isAssignable(method.getParameters()[i], requiredTypes[i])) throw new IllegalStateException(String.format( "Parameter %d of method %s is not assignable to %s", diff --git a/klum-cast-compile/src/main/java/com/blackbuild/klum/cast/validation/ValidationHandler.java b/klum-cast-compile/src/main/java/com/blackbuild/klum/cast/validation/ValidationHandler.java index 4e95eb7..8aa7381 100644 --- a/klum-cast-compile/src/main/java/com/blackbuild/klum/cast/validation/ValidationHandler.java +++ b/klum-cast-compile/src/main/java/com/blackbuild/klum/cast/validation/ValidationHandler.java @@ -39,7 +39,7 @@ public class ValidationHandler { private final AnnotationNode annotationToValidate; private final AnnotatedNode target; - private final List errors = new ArrayList<>(); + private final List errors = new ArrayList<>(); private String currentMember; private Annotation currentAnnotation; @@ -61,16 +61,16 @@ public static void setStatus(AnnotationNode annotationNode, ValidationHandler.St annotationNode.setNodeMetaData(METADATA_KEY, status); } - public static List validateAnnotation(AnnotationNode annotationToValidate, AnnotatedNode target) { + public static List validateAnnotation(AnnotationNode annotationToValidate, AnnotatedNode target) { if (alreadyValidated(annotationToValidate)) return Collections.emptyList(); if (!annotationToValidate.getClassNode().isResolved()) - return Collections.singletonList(new KlumCastCheck.Error("Validated annotation must have already been compiled", annotationToValidate)); + return Collections.singletonList(new KlumCastCheck.ErrorMessage("Validated annotation must have already been compiled", annotationToValidate)); return new ValidationHandler(annotationToValidate, target).validate(); } - private List validate() { + private List validate() { doValidate(annotationToValidate.getClassNode().getTypeClass()); validateAnnotationMembers(); setStatus(annotationToValidate, Status.VALIDATED);