use of org.gradle.api.internal.tasks.properties.annotations.TypeAnnotationHandler in project gradle by gradle.
the class DefaultTypeMetadataStore method createTypeMetadata.
private <T> TypeMetadata createTypeMetadata(Class<T> type) {
Class<?> publicType = GeneratedSubclasses.unpack(type);
ReplayingTypeValidationContext validationContext = new ReplayingTypeValidationContext();
TypeAnnotationMetadata annotationMetadata = typeAnnotationMetadataStore.getTypeAnnotationMetadata(publicType);
annotationMetadata.visitValidationFailures(validationContext);
for (TypeAnnotationHandler annotationHandler : typeAnnotationHandlers) {
if (annotationMetadata.isAnnotationPresent(annotationHandler.getAnnotationType())) {
annotationHandler.validateTypeMetadata(publicType, validationContext);
}
}
ImmutableSet.Builder<PropertyMetadata> effectiveProperties = ImmutableSet.builderWithExpectedSize(annotationMetadata.getPropertiesAnnotationMetadata().size());
for (PropertyAnnotationMetadata propertyAnnotationMetadata : annotationMetadata.getPropertiesAnnotationMetadata()) {
Map<AnnotationCategory, Annotation> propertyAnnotations = propertyAnnotationMetadata.getAnnotations();
Annotation typeAnnotation = propertyAnnotations.get(TYPE);
Annotation normalizationAnnotation = propertyAnnotations.get(NORMALIZATION);
Class<? extends Annotation> propertyType = determinePropertyType(typeAnnotation, normalizationAnnotation);
if (propertyType == null) {
validationContext.visitPropertyProblem(problem -> problem.withId(ValidationProblemId.MISSING_ANNOTATION).forProperty(propertyAnnotationMetadata.getPropertyName()).reportAs(ERROR).withDescription(() -> "is missing " + displayName).happensBecause("A property without annotation isn't considered during up-to-date checking").addPossibleSolution(() -> "Add " + displayName).addPossibleSolution("Mark it as @Internal").documentedAt("validation_problems", "missing_annotation"));
continue;
}
PropertyAnnotationHandler annotationHandler = propertyAnnotationHandlers.get(propertyType);
if (annotationHandler == null) {
validationContext.visitPropertyProblem(problem -> problem.withId(ValidationProblemId.ANNOTATION_INVALID_IN_CONTEXT).forProperty(propertyAnnotationMetadata.getPropertyName()).reportAs(ERROR).withDescription(() -> String.format("is annotated with invalid property type @%s", propertyType.getSimpleName())).happensBecause(() -> "The '@" + propertyType.getSimpleName() + "' annotation cannot be used in this context").addPossibleSolution("Remove the property").addPossibleSolution(() -> "Use a different annotation, e.g one of " + toListOfAnnotations(propertyAnnotationHandlers.keySet())).documentedAt("validation_problems", "annotation_invalid_in_context"));
continue;
}
ImmutableSet<? extends AnnotationCategory> allowedModifiersForPropertyType = annotationHandler.getAllowedModifiers();
for (Map.Entry<AnnotationCategory, Annotation> entry : propertyAnnotations.entrySet()) {
AnnotationCategory annotationCategory = entry.getKey();
if (annotationCategory == TYPE) {
continue;
}
Class<? extends Annotation> annotationType = entry.getValue().annotationType();
if (!allowedModifiersForPropertyType.contains(annotationCategory)) {
validationContext.visitPropertyProblem(problem -> problem.withId(ValidationProblemId.INCOMPATIBLE_ANNOTATIONS).forProperty(propertyAnnotationMetadata.getPropertyName()).reportAs(ERROR).withDescription(() -> "is annotated with @" + annotationType.getSimpleName() + " but that is not allowed for '" + propertyType.getSimpleName() + "' properties").happensBecause(() -> "This modifier is used in conjunction with a property of type '" + propertyType.getSimpleName() + "' but this doesn't have semantics").withLongDescription(() -> "The list of allowed modifiers for '" + propertyType.getSimpleName() + "' is " + toListOfAnnotations(allowedPropertyModifiers)).addPossibleSolution(() -> "Remove the '@" + annotationType.getSimpleName() + "' annotation").documentedAt("validation_problems", "incompatible_annotations"));
} else if (!allowedPropertyModifiers.contains(annotationType)) {
validationContext.visitPropertyProblem(problem -> problem.withId(ValidationProblemId.ANNOTATION_INVALID_IN_CONTEXT).forProperty(propertyAnnotationMetadata.getPropertyName()).reportAs(ERROR).withDescription(() -> String.format("is annotated with invalid modifier @%s", annotationType.getSimpleName())).happensBecause(() -> "The '@" + annotationType.getSimpleName() + "' annotation cannot be used in this context").addPossibleSolution("Remove the annotation").addPossibleSolution(() -> "Use a different annotation, e.g one of " + toListOfAnnotations(allowedPropertyModifiers)).documentedAt("validation_problems", "annotation_invalid_in_context"));
}
}
PropertyMetadata property = new DefaultPropertyMetadata(propertyType, propertyAnnotationMetadata);
annotationHandler.validatePropertyMetadata(property, validationContext);
if (annotationHandler.isPropertyRelevant()) {
effectiveProperties.add(property);
}
}
return new DefaultTypeMetadata(effectiveProperties.build(), validationContext, propertyAnnotationHandlers);
}
Aggregations