use of org.gradle.internal.reflect.validation.ReplayingTypeValidationContext 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);
}
use of org.gradle.internal.reflect.validation.ReplayingTypeValidationContext in project gradle by gradle.
the class DefaultTaskProperties method resolve.
public static TaskProperties resolve(PropertyWalker propertyWalker, FileCollectionFactory fileCollectionFactory, TaskInternal task) {
String beanName = task.toString();
GetInputPropertiesVisitor inputPropertiesVisitor = new GetInputPropertiesVisitor();
GetInputFilesVisitor inputFilesVisitor = new GetInputFilesVisitor(beanName, fileCollectionFactory);
ValidationVisitor validationVisitor = new ValidationVisitor();
OutputFilesCollector outputFilesCollector = new OutputFilesCollector();
OutputUnpacker outputUnpacker = new OutputUnpacker(beanName, fileCollectionFactory, true, true, OutputUnpacker.UnpackedOutputConsumer.composite(outputFilesCollector, validationVisitor));
GetLocalStateVisitor localStateVisitor = new GetLocalStateVisitor(beanName, fileCollectionFactory);
GetDestroyablesVisitor destroyablesVisitor = new GetDestroyablesVisitor(beanName, fileCollectionFactory);
ReplayingTypeValidationContext validationContext = new ReplayingTypeValidationContext();
try {
TaskPropertyUtils.visitProperties(propertyWalker, task, validationContext, new CompositePropertyVisitor(inputPropertiesVisitor, inputFilesVisitor, outputUnpacker, validationVisitor, destroyablesVisitor, localStateVisitor));
} catch (Exception e) {
throw new TaskExecutionException(task, e);
}
return new DefaultTaskProperties(inputPropertiesVisitor.getProperties(), inputFilesVisitor.getFileProperties(), outputFilesCollector.getFileProperties(), outputUnpacker.hasDeclaredOutputs(), localStateVisitor.getFiles(), destroyablesVisitor.getFiles(), validationVisitor.getTaskPropertySpecs(), validationContext);
}
use of org.gradle.internal.reflect.validation.ReplayingTypeValidationContext in project gradle by gradle.
the class DefaultTypeAnnotationMetadataStore method createTypeAnnotationMetadata.
private TypeAnnotationMetadata createTypeAnnotationMetadata(Class<?> type) {
if (type.isPrimitive() || type.isArray() || type.isAnnotation()) {
return EMPTY_TYPE_ANNOTATION_METADATA;
}
Package typePackage = type.getPackage();
if (typePackage != null) {
String typePackageName = typePackage.getName();
if (ignoredPackagePrefixes.stream().anyMatch(typePackageName::startsWith)) {
return EMPTY_TYPE_ANNOTATION_METADATA;
}
}
ImmutableSet.Builder<Annotation> typeAnnotations = ImmutableSet.builder();
for (Annotation typeAnnotation : type.getDeclaredAnnotations()) {
if (recordedTypeAnnotations.contains(typeAnnotation.annotationType())) {
typeAnnotations.add(typeAnnotation);
}
}
Map<String, PropertyAnnotationMetadataBuilder> methodBuilders = new HashMap<>();
ReplayingTypeValidationContext validationContext = new ReplayingTypeValidationContext();
inheritMethods(type, validationContext, methodBuilders);
ImmutableSortedSet<PropertyAnnotationMetadata> propertiesMetadata;
if (!type.isSynthetic()) {
propertiesMetadata = extractPropertiesFrom(type, methodBuilders, validationContext);
} else {
ImmutableSortedSet.Builder<PropertyAnnotationMetadata> propertiesMetadataBuilder = ImmutableSortedSet.naturalOrder();
for (PropertyAnnotationMetadataBuilder propertyMetadataBuilder : methodBuilders.values()) {
propertiesMetadataBuilder.add(propertyMetadataBuilder.build());
}
propertiesMetadata = propertiesMetadataBuilder.build();
}
return new DefaultTypeAnnotationMetadata(typeAnnotations.build(), propertiesMetadata, validationContext);
}
Aggregations