Restore support for recursive annotations in Kotlin

This commit reinstates support for recursive annotations in Kotlin.

See gh-28012
See gh-28618
See gh-31400
Closes gh-31518
This commit is contained in:
lorenzsimon
2023-10-29 12:36:33 +01:00
committed by Sam Brannen
parent 5c012bbb0c
commit 6a7a0bddb7
6 changed files with 160 additions and 29 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -80,7 +80,7 @@ class AnnotationTypeMappingsTests {
@Test
void forAnnotationTypeWhenRepeatableMetaAnnotationIsFiltered() {
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(WithRepeatedMetaAnnotations.class,
Repeating.class.getName()::equals);
RepeatableContainers.standardRepeatables(), Repeating.class.getName()::equals);
assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType)
.containsExactly(WithRepeatedMetaAnnotations.class);
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.annotation
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class FilterWithAlias(
@get:AliasFor("name")
val value: String = "",
@get:AliasFor("value")
val name: String = "",
val and: FiltersWithoutAlias = FiltersWithoutAlias()
)

View File

@@ -0,0 +1,25 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core.annotation
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class FiltersWithoutAlias(
vararg val value: FilterWithAlias
)

View File

@@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test
*
* @author Sam Brannen
* @author Juergen Hoeller
* @author Lorenz Simon
* @since 5.3.16
*/
class KotlinMergedAnnotationsTests {
@@ -74,6 +75,35 @@ class KotlinMergedAnnotationsTests {
assertThat(synthesizedFriends).hasSize(2)
}
@Test // gh-28012
fun recursiveNestedAnnotationWithAlias() {
val method = javaClass.getMethod("filterWithAliasMethod")
// MergedAnnotations
val mergedAnnotations = MergedAnnotations.from(method)
assertThat(mergedAnnotations.isPresent(FilterWithAlias::class.java)).isTrue();
// MergedAnnotation
val mergedAnnotation = MergedAnnotation.from(method.getAnnotation(FilterWithAlias::class.java))
assertThat(mergedAnnotation).isNotNull();
// Synthesized Annotations
val fooFilter = mergedAnnotation.synthesize()
assertThat(fooFilter.value).isEqualTo("foo")
assertThat(fooFilter.name).isEqualTo("foo")
val filters = fooFilter.and
assertThat(filters.value).hasSize(2)
val barFilter = filters.value[0]
assertThat(barFilter.value).isEqualTo("bar")
assertThat(barFilter.name).isEqualTo("bar")
assertThat(barFilter.and.value).isEmpty()
val bazFilter = filters.value[1]
assertThat(bazFilter.value).isEqualTo("baz")
assertThat(bazFilter.name).isEqualTo("baz")
assertThat(bazFilter.and.value).isEmpty()
}
@PersonWithAlias("jane", friends = [PersonWithAlias("john"), PersonWithAlias("sally")])
fun personWithAliasMethod() {
@@ -83,4 +113,8 @@ class KotlinMergedAnnotationsTests {
fun personWithoutAliasMethod() {
}
@FilterWithAlias("foo", and = FiltersWithoutAlias(FilterWithAlias("bar"), FilterWithAlias("baz")))
fun filterWithAliasMethod() {
}
}