/** * Returns the annotation handlers of the given type which are found with the given meta-annotation type on the annotations of the given element. */ @Pure @SuppressWarnings("unchecked") public static @Capturable <H extends AnnotationHandler> @Modifiable @Nonnull Map<@Nonnull AnnotationMirror, @Nonnull H> getAnnotationHandlers(@Nonnull Element element, @Nonnull Class<? extends Annotation> metaAnnotationType, @Nonnull Class<H> annotationHandlerType) { final @Nonnull Map<@Nonnull AnnotationMirror, @Nonnull H> result = new LinkedHashMap<>(); for (@Nonnull AnnotationMirror annotationMirror : ProcessingUtility.getAnnotationMirrors(element)) { final @Nullable H annotationHandler; final @Nonnull String cacheKey = ProcessingUtility.getQualifiedName(annotationMirror) + "$" + metaAnnotationType.getCanonicalName(); if (cachedAnnotationHandlers.containsKey(cacheKey)) { final @Nullable AnnotationHandler cachedAnnotationHandler = cachedAnnotationHandlers.get(cacheKey); annotationHandler = annotationHandlerType.isInstance(cachedAnnotationHandler) ? (H) cachedAnnotationHandler : null; } else { final @Nonnull TypeElement annotationElement = (TypeElement) annotationMirror.getAnnotationType().asElement(); final @Nullable AnnotationValue metaAnnotationValue = ProcessingUtility.getAnnotationValue(annotationElement, metaAnnotationType); annotationHandler = ProcessingUtility.getInstance(metaAnnotationValue, annotationHandlerType); cachedAnnotationHandlers.put(cacheKey, annotationHandler); } if (annotationHandler != null) { ProcessingLog.debugging("Found the annotation handler $ for", SourcePosition.of(element, annotationMirror), annotationHandler.getClass().getCanonicalName()); annotationHandler.checkUsage(element, annotationMirror, ErrorLogger.INSTANCE); result.put(annotationMirror, annotationHandler); } } return result; }
@Pure @Override public void checkUsage(@Nonnull Element element, @Nonnull AnnotationMirror annotationMirror, @NonCaptured @Modified @Nonnull ErrorLogger errorLogger) { final @Nullable AnnotationHandler annotationHandler = ProcessingUtility.getInstance(ProcessingUtility.getAnnotationValue(annotationMirror), AnnotationHandler.class); if (annotationHandler != null) { final @Nonnull Logger logger = new Logger(); annotationHandler.checkUsage(element, annotationMirror, logger); if (logger.isCorrectlyUsed()) { errorLogger.log("The annotation $ is used correctly:", SourcePosition.of(element, annotationMirror), annotationHandler.getAnnotationNameWithLeadingAt()); } } }