Skip to content

Commit 3571952

Browse files
committed
Unit test for match against unresolvable wildcard
See gh-33982
1 parent 4fbca99 commit 3571952

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

Diff for: spring-core/src/main/java/org/springframework/core/ResolvableType.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,12 @@ private boolean isAssignableFrom(ResolvableType other, boolean strict, @Nullable
309309

310310
// Deal with wildcard bounds
311311
WildcardBounds ourBounds = WildcardBounds.get(this);
312-
WildcardBounds typeBounds = WildcardBounds.get(other);
312+
WildcardBounds otherBounds = WildcardBounds.get(other);
313313

314314
// In the form X is assignable to <? extends Number>
315-
if (typeBounds != null) {
316-
return (ourBounds != null && ourBounds.isSameKind(typeBounds) &&
317-
ourBounds.isAssignableFrom(typeBounds.getBounds()));
315+
if (otherBounds != null) {
316+
return (ourBounds != null && ourBounds.isSameKind(otherBounds) &&
317+
ourBounds.isAssignableFrom(otherBounds.getBounds()));
318318
}
319319

320320
// In the form <? extends Number> is assignable to X...
@@ -365,8 +365,8 @@ private boolean isAssignableFrom(ResolvableType other, boolean strict, @Nullable
365365
if (checkGenerics) {
366366
// Recursively check each generic
367367
ResolvableType[] ourGenerics = getGenerics();
368-
ResolvableType[] typeGenerics = other.as(ourResolved).getGenerics();
369-
if (ourGenerics.length != typeGenerics.length) {
368+
ResolvableType[] otherGenerics = other.as(ourResolved).getGenerics();
369+
if (ourGenerics.length != otherGenerics.length) {
370370
return false;
371371
}
372372
if (ourGenerics.length > 0) {
@@ -375,7 +375,7 @@ private boolean isAssignableFrom(ResolvableType other, boolean strict, @Nullable
375375
}
376376
matchedBefore.put(this.type, other.type);
377377
for (int i = 0; i < ourGenerics.length; i++) {
378-
if (!ourGenerics[i].isAssignableFrom(typeGenerics[i], true, matchedBefore)) {
378+
if (!ourGenerics[i].isAssignableFrom(otherGenerics[i], true, matchedBefore)) {
379379
return false;
380380
}
381381
}

Diff for: spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java

+18-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -169,7 +169,7 @@ void forInstanceProvider() {
169169

170170
@Test
171171
void forInstanceProviderNull() {
172-
ResolvableType type = ResolvableType.forInstance(new MyGenericInterfaceType<String>(null));
172+
ResolvableType type = ResolvableType.forInstance(new MyGenericInterfaceType<>(null));
173173
assertThat(type.getType()).isEqualTo(MyGenericInterfaceType.class);
174174
assertThat(type.resolve()).isEqualTo(MyGenericInterfaceType.class);
175175
}
@@ -1177,6 +1177,20 @@ void isAssignableFromForComplexWildcards() throws Exception {
11771177
assertThatResolvableType(complex4).isNotAssignableFrom(complex3);
11781178
}
11791179

1180+
@Test
1181+
void isAssignableFromForUnresolvedWildcards() {
1182+
ResolvableType wildcard = ResolvableType.forInstance(new Wildcard<>());
1183+
ResolvableType wildcardFixed = ResolvableType.forInstance(new WildcardFixed());
1184+
ResolvableType wildcardConcrete = ResolvableType.forClassWithGenerics(Wildcard.class, Number.class);
1185+
1186+
assertThat(wildcard.isAssignableFrom(wildcardFixed)).isTrue();
1187+
assertThat(wildcard.isAssignableFrom(wildcardConcrete)).isTrue();
1188+
assertThat(wildcardFixed.isAssignableFrom(wildcard)).isFalse();
1189+
assertThat(wildcardFixed.isAssignableFrom(wildcardConcrete)).isFalse();
1190+
assertThat(wildcardConcrete.isAssignableFrom(wildcard)).isTrue();
1191+
assertThat(wildcardConcrete.isAssignableFrom(wildcardFixed)).isFalse();
1192+
}
1193+
11801194
@Test
11811195
void identifyTypeVariable() throws Exception {
11821196
Method method = ClassArguments.class.getMethod("typedArgumentFirst", Class.class, Class.class, Class.class);
@@ -1574,7 +1588,6 @@ public ResolvableType getResolvableType() {
15741588
}
15751589
}
15761590

1577-
15781591
public class MySimpleInterfaceType implements MyInterfaceType<String> {
15791592
}
15801593

@@ -1584,28 +1597,24 @@ public abstract class MySimpleInterfaceTypeWithImplementsRaw implements MyInterf
15841597
public abstract class ExtendsMySimpleInterfaceTypeWithImplementsRaw extends MySimpleInterfaceTypeWithImplementsRaw {
15851598
}
15861599

1587-
15881600
public class MyCollectionInterfaceType implements MyInterfaceType<Collection<String>> {
15891601
}
15901602

15911603

15921604
public abstract class MySuperclassType<T> {
15931605
}
15941606

1595-
15961607
public class MySimpleSuperclassType extends MySuperclassType<String> {
15971608
}
15981609

1599-
16001610
public class MyCollectionSuperclassType extends MySuperclassType<Collection<String>> {
16011611
}
16021612

16031613

1604-
interface Wildcard<T extends Number> extends List<T> {
1614+
public class Wildcard<T extends Number> {
16051615
}
16061616

1607-
1608-
interface RawExtendsWildcard extends Wildcard {
1617+
public class WildcardFixed extends Wildcard<Integer> {
16091618
}
16101619

16111620

0 commit comments

Comments
 (0)