Search in sources :

Example 1 with ReplayingTypeValidationContext

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);
}
Also used : TypeAnnotationMetadata(org.gradle.internal.reflect.annotations.TypeAnnotationMetadata) AbstractOutputPropertyAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.AbstractOutputPropertyAnnotationHandler) TypeAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.TypeAnnotationHandler) InputFiles(org.gradle.api.tasks.InputFiles) Function(java.util.function.Function) NORMALIZATION(org.gradle.api.internal.tasks.properties.ModifierAnnotationCategory.NORMALIZATION) PropertyAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.PropertyAnnotationHandler) Map(java.util.Map) TYPE(org.gradle.internal.reflect.AnnotationCategory.TYPE) Collector(java.util.stream.Collector) Method(java.lang.reflect.Method) Nullable(javax.annotation.Nullable) GeneratedSubclasses(org.gradle.api.internal.GeneratedSubclasses) Classpath(org.gradle.api.tasks.Classpath) ImmutableSet(com.google.common.collect.ImmutableSet) CompileClasspath(org.gradle.api.tasks.CompileClasspath) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) ReplayingTypeValidationContext(org.gradle.internal.reflect.validation.ReplayingTypeValidationContext) Set(java.util.Set) AnnotationCategory(org.gradle.internal.reflect.AnnotationCategory) TypeValidationContext(org.gradle.internal.reflect.validation.TypeValidationContext) CrossBuildInMemoryCache(org.gradle.cache.internal.CrossBuildInMemoryCache) Maps(com.google.common.collect.Maps) Collectors(java.util.stream.Collectors) TypeAnnotationMetadataStore(org.gradle.internal.reflect.annotations.TypeAnnotationMetadataStore) PropertyMetadata(org.gradle.internal.reflect.PropertyMetadata) PropertyAnnotationMetadata(org.gradle.internal.reflect.annotations.PropertyAnnotationMetadata) ERROR(org.gradle.internal.reflect.validation.Severity.ERROR) Annotation(java.lang.annotation.Annotation) CrossBuildInMemoryCacheFactory(org.gradle.cache.internal.CrossBuildInMemoryCacheFactory) ValidationProblemId(org.gradle.internal.reflect.problems.ValidationProblemId) AbstractOutputPropertyAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.AbstractOutputPropertyAnnotationHandler) PropertyAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.PropertyAnnotationHandler) TypeAnnotationHandler(org.gradle.api.internal.tasks.properties.annotations.TypeAnnotationHandler) PropertyAnnotationMetadata(org.gradle.internal.reflect.annotations.PropertyAnnotationMetadata) ReplayingTypeValidationContext(org.gradle.internal.reflect.validation.ReplayingTypeValidationContext) AnnotationCategory(org.gradle.internal.reflect.AnnotationCategory) Annotation(java.lang.annotation.Annotation) ImmutableSet(com.google.common.collect.ImmutableSet) PropertyMetadata(org.gradle.internal.reflect.PropertyMetadata) TypeAnnotationMetadata(org.gradle.internal.reflect.annotations.TypeAnnotationMetadata) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 2 with ReplayingTypeValidationContext

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);
}
Also used : ReplayingTypeValidationContext(org.gradle.internal.reflect.validation.ReplayingTypeValidationContext) TaskExecutionException(org.gradle.api.tasks.TaskExecutionException) TaskExecutionException(org.gradle.api.tasks.TaskExecutionException)

Example 3 with ReplayingTypeValidationContext

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);
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) PropertyAnnotationMetadata(org.gradle.internal.reflect.annotations.PropertyAnnotationMetadata) ReplayingTypeValidationContext(org.gradle.internal.reflect.validation.ReplayingTypeValidationContext) Annotation(java.lang.annotation.Annotation) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet)

Aggregations

ReplayingTypeValidationContext (org.gradle.internal.reflect.validation.ReplayingTypeValidationContext)3 ImmutableSet (com.google.common.collect.ImmutableSet)2 Annotation (java.lang.annotation.Annotation)2 PropertyAnnotationMetadata (org.gradle.internal.reflect.annotations.PropertyAnnotationMetadata)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableSortedSet (com.google.common.collect.ImmutableSortedSet)1 Maps (com.google.common.collect.Maps)1 Method (java.lang.reflect.Method)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 Set (java.util.Set)1 Function (java.util.function.Function)1 Collector (java.util.stream.Collector)1 Collectors (java.util.stream.Collectors)1 Nullable (javax.annotation.Nullable)1 GeneratedSubclasses (org.gradle.api.internal.GeneratedSubclasses)1 NORMALIZATION (org.gradle.api.internal.tasks.properties.ModifierAnnotationCategory.NORMALIZATION)1 AbstractOutputPropertyAnnotationHandler (org.gradle.api.internal.tasks.properties.annotations.AbstractOutputPropertyAnnotationHandler)1