Skip to content

Commit bf9f261

Browse files
committed
Revert "Support recursive annotations in merged annotations"
This reverts commit 3ec612a.
1 parent df37e33 commit bf9f261

File tree

7 files changed

+31
-279
lines changed

7 files changed

+31
-279
lines changed

spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMapping.java

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -82,8 +82,8 @@ final class AnnotationTypeMapping {
8282
private final Set<Method> claimedAliases = new HashSet<>();
8383

8484

85-
AnnotationTypeMapping(@Nullable AnnotationTypeMapping source, Class<? extends Annotation> annotationType,
86-
@Nullable Annotation annotation, Set<Class<? extends Annotation>> visitedAnnotationTypes) {
85+
AnnotationTypeMapping(@Nullable AnnotationTypeMapping source,
86+
Class<? extends Annotation> annotationType, @Nullable Annotation annotation) {
8787

8888
this.source = source;
8989
this.root = (source != null ? source.getRoot() : this);
@@ -103,7 +103,7 @@ final class AnnotationTypeMapping {
103103
processAliases();
104104
addConventionMappings();
105105
addConventionAnnotationValues();
106-
this.synthesizable = computeSynthesizableFlag(visitedAnnotationTypes);
106+
this.synthesizable = computeSynthesizableFlag();
107107
}
108108

109109

@@ -311,10 +311,7 @@ private boolean isBetterConventionAnnotationValue(int index, boolean isValueAttr
311311
}
312312

313313
@SuppressWarnings("unchecked")
314-
private boolean computeSynthesizableFlag(Set<Class<? extends Annotation>> visitedAnnotationTypes) {
315-
// Track that we have visited the current annotation type.
316-
visitedAnnotationTypes.add(this.annotationType);
317-
314+
private boolean computeSynthesizableFlag() {
318315
// Uses @AliasFor for local aliases?
319316
for (int index : this.aliasMappings) {
320317
if (index != -1) {
@@ -343,15 +340,9 @@ private boolean computeSynthesizableFlag(Set<Class<? extends Annotation>> visite
343340
if (type.isAnnotation() || (type.isArray() && type.getComponentType().isAnnotation())) {
344341
Class<? extends Annotation> annotationType =
345342
(Class<? extends Annotation>) (type.isAnnotation() ? type : type.getComponentType());
346-
// Ensure we have not yet visited the current nested annotation type, in order
347-
// to avoid infinite recursion for JVM languages other than Java that support
348-
// recursive annotation definitions.
349-
if (visitedAnnotationTypes.add(annotationType)) {
350-
AnnotationTypeMapping mapping =
351-
AnnotationTypeMappings.forAnnotationType(annotationType, visitedAnnotationTypes).get(0);
352-
if (mapping.isSynthesizable()) {
353-
return true;
354-
}
343+
AnnotationTypeMapping mapping = AnnotationTypeMappings.forAnnotationType(annotationType).get(0);
344+
if (mapping.isSynthesizable()) {
345+
return true;
355346
}
356347
}
357348
}

spring-core/src/main/java/org/springframework/core/annotation/AnnotationTypeMappings.java

Lines changed: 21 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,10 +20,8 @@
2020
import java.util.ArrayDeque;
2121
import java.util.ArrayList;
2222
import java.util.Deque;
23-
import java.util.HashSet;
2423
import java.util.List;
2524
import java.util.Map;
26-
import java.util.Set;
2725

2826
import org.springframework.lang.Nullable;
2927
import org.springframework.util.ConcurrentReferenceHashMap;
@@ -42,7 +40,6 @@
4240
* be searched once, regardless of how many times they are actually used.
4341
*
4442
* @author Phillip Webb
45-
* @author Sam Brannen
4643
* @since 5.2
4744
* @see AnnotationTypeMapping
4845
*/
@@ -63,22 +60,19 @@ final class AnnotationTypeMappings {
6360

6461

6562
private AnnotationTypeMappings(RepeatableContainers repeatableContainers,
66-
AnnotationFilter filter, Class<? extends Annotation> annotationType,
67-
Set<Class<? extends Annotation>> visitedAnnotationTypes) {
63+
AnnotationFilter filter, Class<? extends Annotation> annotationType) {
6864

6965
this.repeatableContainers = repeatableContainers;
7066
this.filter = filter;
7167
this.mappings = new ArrayList<>();
72-
addAllMappings(annotationType, visitedAnnotationTypes);
68+
addAllMappings(annotationType);
7369
this.mappings.forEach(AnnotationTypeMapping::afterAllMappingsSet);
7470
}
7571

7672

77-
private void addAllMappings(Class<? extends Annotation> annotationType,
78-
Set<Class<? extends Annotation>> visitedAnnotationTypes) {
79-
73+
private void addAllMappings(Class<? extends Annotation> annotationType) {
8074
Deque<AnnotationTypeMapping> queue = new ArrayDeque<>();
81-
addIfPossible(queue, null, annotationType, null, visitedAnnotationTypes);
75+
addIfPossible(queue, null, annotationType, null);
8276
while (!queue.isEmpty()) {
8377
AnnotationTypeMapping mapping = queue.removeFirst();
8478
this.mappings.add(mapping);
@@ -108,15 +102,14 @@ private void addMetaAnnotationsToQueue(Deque<AnnotationTypeMapping> queue, Annot
108102
}
109103

110104
private void addIfPossible(Deque<AnnotationTypeMapping> queue, AnnotationTypeMapping source, Annotation ann) {
111-
addIfPossible(queue, source, ann.annotationType(), ann, new HashSet<>());
105+
addIfPossible(queue, source, ann.annotationType(), ann);
112106
}
113107

114108
private void addIfPossible(Deque<AnnotationTypeMapping> queue, @Nullable AnnotationTypeMapping source,
115-
Class<? extends Annotation> annotationType, @Nullable Annotation ann,
116-
Set<Class<? extends Annotation>> visitedAnnotationTypes) {
109+
Class<? extends Annotation> annotationType, @Nullable Annotation ann) {
117110

118111
try {
119-
queue.addLast(new AnnotationTypeMapping(source, annotationType, ann, visitedAnnotationTypes));
112+
queue.addLast(new AnnotationTypeMapping(source, annotationType, ann));
120113
}
121114
catch (Exception ex) {
122115
AnnotationUtils.rethrowAnnotationConfigurationException(ex);
@@ -173,37 +166,20 @@ AnnotationTypeMapping get(int index) {
173166
* @return type mappings for the annotation type
174167
*/
175168
static AnnotationTypeMappings forAnnotationType(Class<? extends Annotation> annotationType) {
176-
return forAnnotationType(annotationType, new HashSet<>());
177-
}
178-
179-
/**
180-
* Create {@link AnnotationTypeMappings} for the specified annotation type.
181-
* @param annotationType the source annotation type
182-
* @param visitedAnnotationTypes the set of annotations that we have already
183-
* visited; used to avoid infinite recursion for recursive annotations which
184-
* some JVM languages support (such as Kotlin)
185-
* @return type mappings for the annotation type
186-
*/
187-
static AnnotationTypeMappings forAnnotationType(Class<? extends Annotation> annotationType,
188-
Set<Class<? extends Annotation>> visitedAnnotationTypes) {
189-
190-
return forAnnotationType(annotationType, RepeatableContainers.standardRepeatables(),
191-
AnnotationFilter.PLAIN, visitedAnnotationTypes);
169+
return forAnnotationType(annotationType, AnnotationFilter.PLAIN);
192170
}
193171

194172
/**
195173
* Create {@link AnnotationTypeMappings} for the specified annotation type.
196174
* @param annotationType the source annotation type
197-
* @param repeatableContainers the repeatable containers that may be used by
198-
* the meta-annotations
199175
* @param annotationFilter the annotation filter used to limit which
200176
* annotations are considered
201177
* @return type mappings for the annotation type
202178
*/
203-
static AnnotationTypeMappings forAnnotationType(Class<? extends Annotation> annotationType,
204-
RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter) {
179+
static AnnotationTypeMappings forAnnotationType(
180+
Class<? extends Annotation> annotationType, AnnotationFilter annotationFilter) {
205181

206-
return forAnnotationType(annotationType, repeatableContainers, annotationFilter, new HashSet<>());
182+
return forAnnotationType(annotationType, RepeatableContainers.standardRepeatables(), annotationFilter);
207183
}
208184

209185
/**
@@ -213,24 +189,20 @@ static AnnotationTypeMappings forAnnotationType(Class<? extends Annotation> anno
213189
* the meta-annotations
214190
* @param annotationFilter the annotation filter used to limit which
215191
* annotations are considered
216-
* @param visitedAnnotationTypes the set of annotations that we have already
217-
* visited; used to avoid infinite recursion for recursive annotations which
218-
* some JVM languages support (such as Kotlin)
219192
* @return type mappings for the annotation type
220193
*/
221-
private static AnnotationTypeMappings forAnnotationType(Class<? extends Annotation> annotationType,
222-
RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter,
223-
Set<Class<? extends Annotation>> visitedAnnotationTypes) {
194+
static AnnotationTypeMappings forAnnotationType(Class<? extends Annotation> annotationType,
195+
RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter) {
224196

225197
if (repeatableContainers == RepeatableContainers.standardRepeatables()) {
226198
return standardRepeatablesCache.computeIfAbsent(annotationFilter,
227-
key -> new Cache(repeatableContainers, key)).get(annotationType, visitedAnnotationTypes);
199+
key -> new Cache(repeatableContainers, key)).get(annotationType);
228200
}
229201
if (repeatableContainers == RepeatableContainers.none()) {
230202
return noRepeatablesCache.computeIfAbsent(annotationFilter,
231-
key -> new Cache(repeatableContainers, key)).get(annotationType, visitedAnnotationTypes);
203+
key -> new Cache(repeatableContainers, key)).get(annotationType);
232204
}
233-
return new AnnotationTypeMappings(repeatableContainers, annotationFilter, annotationType, visitedAnnotationTypes);
205+
return new AnnotationTypeMappings(repeatableContainers, annotationFilter, annotationType);
234206
}
235207

236208
static void clearCache() {
@@ -263,21 +235,14 @@ private static class Cache {
263235
/**
264236
* Get or create {@link AnnotationTypeMappings} for the specified annotation type.
265237
* @param annotationType the annotation type
266-
* @param visitedAnnotationTypes the set of annotations that we have already
267-
* visited; used to avoid infinite recursion for recursive annotations which
268-
* some JVM languages support (such as Kotlin)
269238
* @return a new or existing {@link AnnotationTypeMappings} instance
270239
*/
271-
AnnotationTypeMappings get(Class<? extends Annotation> annotationType,
272-
Set<Class<? extends Annotation>> visitedAnnotationTypes) {
273-
274-
return this.mappings.computeIfAbsent(annotationType, key -> createMappings(key, visitedAnnotationTypes));
240+
AnnotationTypeMappings get(Class<? extends Annotation> annotationType) {
241+
return this.mappings.computeIfAbsent(annotationType, this::createMappings);
275242
}
276243

277-
private AnnotationTypeMappings createMappings(Class<? extends Annotation> annotationType,
278-
Set<Class<? extends Annotation>> visitedAnnotationTypes) {
279-
280-
return new AnnotationTypeMappings(this.repeatableContainers, this.filter, annotationType, visitedAnnotationTypes);
244+
AnnotationTypeMappings createMappings(Class<? extends Annotation> annotationType) {
245+
return new AnnotationTypeMappings(this.repeatableContainers, this.filter, annotationType);
281246
}
282247
}
283248

spring-core/src/test/java/org/springframework/core/annotation/AnnotationTypeMappingsTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -80,7 +80,7 @@ void forAnnotationTypeWhenHasRepeatingMetaAnnotationReturnsMapping() {
8080
@Test
8181
void forAnnotationTypeWhenRepeatableMetaAnnotationIsFiltered() {
8282
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(WithRepeatedMetaAnnotations.class,
83-
RepeatableContainers.standardRepeatables(), Repeating.class.getName()::equals);
83+
Repeating.class.getName()::equals);
8484
assertThat(getAll(mappings)).flatExtracting(AnnotationTypeMapping::getAnnotationType)
8585
.containsExactly(WithRepeatedMetaAnnotations.class);
8686
}

spring-core/src/test/kotlin/org/springframework/core/annotation/Filter.kt

Lines changed: 0 additions & 35 deletions
This file was deleted.

spring-core/src/test/kotlin/org/springframework/core/annotation/Filters.kt

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)