Fix merged annotation attributes regression

Commit d6768ccc18 introduced a regression in the support for merging
annotation attributes in a multi-level annotation hierarchy.

This commit addresses that issue by ensuring that a merged annotation
is once again synthesized if a meta-annotation in the annotation
hierarchy declares attributes that override attributes in the target
annotation.

Closes gh-28716
This commit is contained in:
Sam Brannen
2022-06-28 14:22:53 +02:00
parent 9868c28c73
commit 622fc3edf7
2 changed files with 75 additions and 8 deletions

View File

@@ -24,6 +24,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
@@ -1420,7 +1421,28 @@ class MergedAnnotationsTests {
assertThat(generatedValue).isSameAs(synthesizedGeneratedValue);
}
@Test
@Test // gh-28716
void synthesizeWhenUsingMergedAnnotationsFromApi() {
Field directlyAnnotatedField = ReflectionUtils.findField(DomainType.class, "directlyAnnotated");
MergedAnnotations mergedAnnotations = MergedAnnotations.from(directlyAnnotatedField);
RootAnnotation rootAnnotation = mergedAnnotations.get(RootAnnotation.class).synthesize();
assertThat(rootAnnotation.flag()).isFalse();
assertThat(rootAnnotation).isNotInstanceOf(SynthesizedAnnotation.class);
Field metaAnnotatedField = ReflectionUtils.findField(DomainType.class, "metaAnnotated");
mergedAnnotations = MergedAnnotations.from(metaAnnotatedField);
rootAnnotation = mergedAnnotations.get(RootAnnotation.class).synthesize();
assertThat(rootAnnotation.flag()).isTrue();
assertThat(rootAnnotation).isInstanceOf(SynthesizedAnnotation.class);
Field metaMetaAnnotatedField = ReflectionUtils.findField(DomainType.class, "metaMetaAnnotated");
mergedAnnotations = MergedAnnotations.from(metaMetaAnnotatedField);
rootAnnotation = mergedAnnotations.get(RootAnnotation.class).synthesize();
assertThat(rootAnnotation.flag()).isTrue();
assertThat(rootAnnotation).isInstanceOf(SynthesizedAnnotation.class);
}
@Test // gh-28704
void synthesizeShouldNotSynthesizeNonsynthesizableAnnotationsWhenUsingMergedAnnotationsFromApi() {
MergedAnnotations mergedAnnotations = MergedAnnotations.from(SecurityConfig.class);
@@ -3127,6 +3149,40 @@ class MergedAnnotationsTests {
static class SecurityConfig {
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@interface RootAnnotation {
String value() default "";
boolean flag() default false;
}
@RootAnnotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@interface ComposedRootAnnotation {
@AliasFor(annotation = RootAnnotation.class, attribute = "flag")
boolean enabled() default true;
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@ComposedRootAnnotation
@interface DoublyComposedRootAnnotation {
}
class DomainType {
@RootAnnotation
Object directlyAnnotated;
@ComposedRootAnnotation
Object metaAnnotated;
@DoublyComposedRootAnnotation
Object metaMetaAnnotated;
}
@Retention(RetentionPolicy.RUNTIME)
@interface TestConfiguration {