Skip to content

Commit 5d02748

Browse files
authored
Merge pull request quarkusio#47932 from VoglSebastian/methodParameterTypeHandling
Handle method parameter type annotations in ClassComparisonUtil
2 parents 60acc7c + 45d9565 commit 5d02748

File tree

2 files changed

+135
-13
lines changed

2 files changed

+135
-13
lines changed

core/deployment/src/main/java/io/quarkus/deployment/dev/ClassComparisonUtil.java

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
import java.util.stream.Collectors;
1212

1313
import org.jboss.jandex.AnnotationInstance;
14-
import org.jboss.jandex.AnnotationTarget;
1514
import org.jboss.jandex.AnnotationValue;
1615
import org.jboss.jandex.ClassInfo;
1716
import org.jboss.jandex.DotName;
1817
import org.jboss.jandex.FieldInfo;
1918
import org.jboss.jandex.MethodInfo;
2019
import org.jboss.jandex.Type;
20+
import org.jboss.jandex.TypeTarget;
2121

2222
public class ClassComparisonUtil {
2323
private static final Set<DotName> IGNORED_ANNOTATIONS = Set.of(
@@ -130,10 +130,12 @@ static boolean compareMethodAnnotations(Collection<AnnotationInstance> a, Collec
130130
}
131131
List<AnnotationInstance> method1 = new ArrayList<>();
132132
Map<Integer, List<AnnotationInstance>> params1 = new HashMap<>();
133-
methodMap(a, method1, params1);
133+
Map<Integer, List<AnnotationInstance>> paramTypes1 = new HashMap<>();
134+
methodMap(a, method1, params1, paramTypes1);
134135
List<AnnotationInstance> method2 = new ArrayList<>();
135136
Map<Integer, List<AnnotationInstance>> params2 = new HashMap<>();
136-
methodMap(b, method2, params2);
137+
Map<Integer, List<AnnotationInstance>> paramTypes2 = new HashMap<>();
138+
methodMap(b, method2, params2, paramTypes2);
137139
if (!compareAnnotations(method1, method2)) {
138140
return false;
139141
}
@@ -146,21 +148,38 @@ static boolean compareMethodAnnotations(Collection<AnnotationInstance> a, Collec
146148
return false;
147149
}
148150
}
151+
for (Map.Entry<Integer, List<AnnotationInstance>> entry : paramTypes1.entrySet()) {
152+
List<AnnotationInstance> other = paramTypes2.get(entry.getKey());
153+
if (!compareAnnotations(other, entry.getValue())) {
154+
return false;
155+
}
156+
}
149157
return true;
150158
}
151159

152160
private static void methodMap(Collection<AnnotationInstance> b, List<AnnotationInstance> method2,
153-
Map<Integer, List<AnnotationInstance>> params2) {
161+
Map<Integer, List<AnnotationInstance>> params2, Map<Integer, List<AnnotationInstance>> paramTypes2) {
154162
for (AnnotationInstance i : b) {
155-
if (i.target().kind() == AnnotationTarget.Kind.METHOD) {
156-
method2.add(i);
157-
} else {
158-
int index = i.target().asMethodParameter().position();
159-
List<AnnotationInstance> instances = params2.get(index);
160-
if (instances == null) {
161-
params2.put(index, instances = new ArrayList<>());
162-
}
163-
instances.add(i);
163+
int index;
164+
switch (i.target().kind()) {
165+
case METHOD:
166+
method2.add(i);
167+
break;
168+
case METHOD_PARAMETER:
169+
index = i.target().asMethodParameter().position();
170+
params2.computeIfAbsent(index, k -> new ArrayList<>()).add(i);
171+
break;
172+
case TYPE:
173+
TypeTarget.Usage usage = i.target().asType().usage();
174+
if (usage == TypeTarget.Usage.METHOD_PARAMETER) {
175+
index = i.target().asType().asMethodParameterType().position();
176+
paramTypes2.computeIfAbsent(index, k -> new ArrayList<>()).add(i);
177+
} else {
178+
throw new IllegalArgumentException("Unsupported type annotation usage: " + usage);
179+
}
180+
break;
181+
default:
182+
throw new IllegalArgumentException("Unsupported annotation target kind: " + i.target().kind());
164183
}
165184
}
166185
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package io.quarkus.deployment.dev;
2+
3+
import java.lang.annotation.Annotation;
4+
import java.lang.annotation.Documented;
5+
import java.lang.annotation.ElementType;
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.RetentionPolicy;
8+
import java.lang.annotation.Target;
9+
import java.util.List;
10+
11+
import org.jboss.jandex.AnnotationInstance;
12+
import org.jboss.jandex.MethodParameterInfo;
13+
import org.junit.jupiter.api.Assertions;
14+
import org.junit.jupiter.api.Nested;
15+
import org.junit.jupiter.api.Test;
16+
17+
class ClassComparisonUtilTest {
18+
19+
@Nested
20+
class CompareMethodAnnotations {
21+
22+
@Test
23+
public void annotationsEqual() {
24+
AnnotationInstance instance1 = methodParameterAnnotation(AnnotationForTest1.class);
25+
AnnotationInstance instance2 = methodParameterAnnotation(AnnotationForTest1.class);
26+
27+
List<AnnotationInstance> instances1 = List.of(instance1);
28+
List<AnnotationInstance> instances2 = List.of(instance2);
29+
30+
Assertions.assertTrue(ClassComparisonUtil.compareMethodAnnotations(instances1, instances2));
31+
}
32+
33+
@Test
34+
public void annotationsNotEqual() {
35+
AnnotationInstance instance1 = methodParameterAnnotation(AnnotationForTest1.class);
36+
AnnotationInstance instance2 = methodParameterAnnotation(AnnotationForTest2.class);
37+
38+
List<AnnotationInstance> instances1 = List.of(instance1);
39+
List<AnnotationInstance> instances2 = List.of(instance2);
40+
41+
Assertions.assertFalse(ClassComparisonUtil.compareMethodAnnotations(instances1, instances2));
42+
}
43+
44+
@Test
45+
public void compareMethodAnnotationsSizeDiffer() {
46+
AnnotationInstance instance = methodParameterAnnotation(AnnotationForTest1.class);
47+
48+
List<AnnotationInstance> instances = List.of(instance);
49+
50+
Assertions.assertFalse(ClassComparisonUtil.compareMethodAnnotations(instances, List.of()));
51+
Assertions.assertFalse(ClassComparisonUtil.compareMethodAnnotations(List.of(), instances));
52+
}
53+
54+
@Test
55+
public void multipleAnnotationsAtSamePosition() {
56+
List<AnnotationInstance> instances1 = List.of(
57+
methodParameterAnnotation(AnnotationForTest1.class),
58+
methodParameterAnnotation(AnnotationForTest2.class));
59+
List<AnnotationInstance> instances2 = List.of(
60+
methodParameterAnnotation(AnnotationForTest2.class),
61+
methodParameterAnnotation(AnnotationForTest1.class));
62+
63+
Assertions.assertTrue(ClassComparisonUtil.compareMethodAnnotations(instances1, instances2));
64+
}
65+
66+
@Test
67+
public void multipleAnnotations() {
68+
List<AnnotationInstance> instances1 = List.of(
69+
methodParameterAnnotation(AnnotationForTest1.class, 1),
70+
methodParameterAnnotation(AnnotationForTest2.class, 2));
71+
72+
List<AnnotationInstance> instances2 = List.of(
73+
methodParameterAnnotation(AnnotationForTest1.class, 2),
74+
methodParameterAnnotation(AnnotationForTest2.class, 1));
75+
76+
Assertions.assertFalse(ClassComparisonUtil.compareMethodAnnotations(instances1, instances2));
77+
}
78+
79+
private static AnnotationInstance methodParameterAnnotation(
80+
Class<? extends Annotation> annotation) {
81+
return methodParameterAnnotation(annotation, 1);
82+
}
83+
84+
private static AnnotationInstance methodParameterAnnotation(
85+
Class<? extends Annotation> annotation, int position) {
86+
MethodParameterInfo target = MethodParameterInfo.create(null, (short) position);
87+
return AnnotationInstance.builder(annotation).buildWithTarget(target);
88+
}
89+
90+
@Target({ ElementType.PARAMETER, ElementType.TYPE_USE })
91+
@Retention(RetentionPolicy.RUNTIME)
92+
@Documented
93+
private @interface AnnotationForTest1 {
94+
}
95+
96+
@Target({ ElementType.PARAMETER, ElementType.TYPE_USE })
97+
@Retention(RetentionPolicy.RUNTIME)
98+
@Documented
99+
private @interface AnnotationForTest2 {
100+
}
101+
}
102+
103+
}

0 commit comments

Comments
 (0)