Support WildcardType resolution in GenericTypeResolver
This commit adds support for WildcardType bounds resolution, commonly seen in Kotlin due to declaration-site variance, but also possible in Java even if less common. Closes gh-22313
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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.
|
||||
@@ -37,6 +37,7 @@ import static org.springframework.util.ReflectionUtils.findMethod;
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
class GenericTypeResolverTests {
|
||||
@@ -185,6 +186,51 @@ class GenericTypeResolverTests {
|
||||
assertThat(resolved).isEqualTo(E.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveWildcardTypeWithUpperBound() {
|
||||
Method method = findMethod(MySimpleSuperclassType.class, "upperBound", List.class);
|
||||
Type resolved = resolveType(method.getGenericParameterTypes()[0], MySimpleSuperclassType.class);
|
||||
ResolvableType resolvableType = ResolvableType.forType(resolved);
|
||||
assertThat(resolvableType.hasUnresolvableGenerics()).isFalse();
|
||||
assertThat(resolvableType.resolveGenerics()).containsExactly(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveWildcardTypeWithUpperBoundWithResolvedType() {
|
||||
Method method = findMethod(MySimpleSuperclassType.class, "upperBoundWithResolvedType", List.class);
|
||||
Type resolved = resolveType(method.getGenericParameterTypes()[0], MySimpleSuperclassType.class);
|
||||
ResolvableType resolvableType = ResolvableType.forType(resolved);
|
||||
assertThat(resolvableType.hasUnresolvableGenerics()).isFalse();
|
||||
assertThat(resolvableType.resolveGenerics()).containsExactly(Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveWildcardTypeWithLowerBound() {
|
||||
Method method = findMethod(MySimpleSuperclassType.class, "lowerBound", List.class);
|
||||
Type resolved = resolveType(method.getGenericParameterTypes()[0], MySimpleSuperclassType.class);
|
||||
ResolvableType resolvableType = ResolvableType.forType(resolved);
|
||||
assertThat(resolvableType.hasUnresolvableGenerics()).isFalse();
|
||||
assertThat(resolvableType.resolveGenerics()).containsExactly(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveWildcardTypeWithLowerBoundWithResolvedType() {
|
||||
Method method = findMethod(MySimpleSuperclassType.class, "lowerBoundWithResolvedType", List.class);
|
||||
Type resolved = resolveType(method.getGenericParameterTypes()[0], MySimpleSuperclassType.class);
|
||||
ResolvableType resolvableType = ResolvableType.forType(resolved);
|
||||
assertThat(resolvableType.hasUnresolvableGenerics()).isFalse();
|
||||
assertThat(resolvableType.resolveGenerics()).containsExactly(Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveWildcardTypeWithUnbounded() {
|
||||
Method method = findMethod(MySimpleSuperclassType.class, "unbounded", List.class);
|
||||
Type resolved = resolveType(method.getGenericParameterTypes()[0], MySimpleSuperclassType.class);
|
||||
ResolvableType resolvableType = ResolvableType.forType(resolved);
|
||||
assertThat(resolvableType.hasUnresolvableGenerics()).isFalse();
|
||||
assertThat(resolvableType.resolveGenerics()).containsExactly(Object.class);
|
||||
}
|
||||
|
||||
public interface MyInterfaceType<T> {
|
||||
}
|
||||
|
||||
@@ -195,6 +241,21 @@ class GenericTypeResolverTests {
|
||||
}
|
||||
|
||||
public abstract class MySuperclassType<T> {
|
||||
|
||||
public void upperBound(List<? extends T> list) {
|
||||
}
|
||||
|
||||
public void upperBoundWithResolvedType(List<? extends Integer> list) {
|
||||
}
|
||||
|
||||
public void lowerBound(List<? extends T> list) {
|
||||
}
|
||||
|
||||
public void lowerBoundWithResolvedType(List<? super Integer> list) {
|
||||
}
|
||||
|
||||
public void unbounded(List<?> list) {
|
||||
}
|
||||
}
|
||||
|
||||
public class MySimpleSuperclassType extends MySuperclassType<String> {
|
||||
|
||||
Reference in New Issue
Block a user