Skip to content

Commit

Permalink
Support variable resolution of wildcard types
Browse files Browse the repository at this point in the history
Includes cleanup of "varaible" typos in ResolvableTypeTests.

Closes gh-24150
  • Loading branch information
jhoeller committed Dec 9, 2019
1 parent 5341e77 commit 197dbff
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 21 deletions.
Expand Up @@ -872,6 +872,12 @@ private ResolvableType resolveVariable(TypeVariable<?> variable) {
return forType(ownerType, this.variableResolver).resolveVariable(variable);
}
}
if (this.type instanceof WildcardType) {
ResolvableType resolved = resolveType().resolveVariable(variable);
if (resolved != null) {
return resolved;
}
}
if (this.variableResolver != null) {
return this.variableResolver.resolveVariable(variable);
}
Expand Down Expand Up @@ -997,7 +1003,7 @@ public static ResolvableType forClass(@Nullable Class<?> clazz) {
* {@link Class#isAssignableFrom}, which this serves as a wrapper for.
* For example: {@code ResolvableType.forRawClass(List.class)}.
* @param clazz the class to introspect ({@code null} is semantically
* equivalent to {@code Object.class} for typical use cases here}
* equivalent to {@code Object.class} for typical use cases here)
* @return a {@link ResolvableType} for the specified class
* @since 4.2
* @see #forClass(Class)
Expand Down Expand Up @@ -1485,10 +1491,10 @@ public TypeVariablesVariableResolver(TypeVariable<?>[] variables, ResolvableType
@Override
@Nullable
public ResolvableType resolveVariable(TypeVariable<?> variable) {
TypeVariable<?> variableToCompare = SerializableTypeWrapper.unwrap(variable);
for (int i = 0; i < this.variables.length; i++) {
TypeVariable<?> v1 = SerializableTypeWrapper.unwrap(this.variables[i]);
TypeVariable<?> v2 = SerializableTypeWrapper.unwrap(variable);
if (ObjectUtils.nullSafeEquals(v1, v2)) {
TypeVariable<?> resolvedVariable = SerializableTypeWrapper.unwrap(this.variables[i]);
if (ObjectUtils.nullSafeEquals(resolvedVariable, variableToCompare)) {
return this.generics[i];
}
}
Expand Down
Expand Up @@ -684,53 +684,46 @@ public void doesResolveFromOuterOwner() throws Exception {

@Test
public void resolveBoundedTypeVariableResult() throws Exception {
ResolvableType type = ResolvableType.forMethodReturnType(Methods.class.getMethod("boundedTypeVaraibleResult"));
ResolvableType type = ResolvableType.forMethodReturnType(Methods.class.getMethod("boundedTypeVariableResult"));
assertThat(type.resolve(), equalTo((Class) CharSequence.class));
}

@Test
public void resolveVariableNotFound() throws Exception {
ResolvableType type = ResolvableType.forMethodReturnType(Methods.class.getMethod("typedReturn"));
assertThat(type.resolve(), nullValue());
public void resolveBoundedTypeVariableWildcardResult() throws Exception {
ResolvableType type = ResolvableType.forMethodReturnType(Methods.class.getMethod("boundedTypeVariableWildcardResult"));
assertThat(type.getGeneric(1).asCollection().resolveGeneric(), equalTo((Class) CharSequence.class));
}

@Test
public void resolveTypeVaraibleFromMethodReturn() throws Exception {
public void resolveVariableNotFound() throws Exception {
ResolvableType type = ResolvableType.forMethodReturnType(Methods.class.getMethod("typedReturn"));
assertThat(type.resolve(), nullValue());
}

@Test
public void resolveTypeVaraibleFromMethodReturnWithInstanceClass() throws Exception {
ResolvableType type = ResolvableType.forMethodReturnType(
Methods.class.getMethod("typedReturn"), TypedMethods.class);
assertThat(type.resolve(), equalTo((Class) String.class));
}

@Test
public void resolveTypeVaraibleFromSimpleInterfaceType() {
public void resolveTypeVariableFromSimpleInterfaceType() {
ResolvableType type = ResolvableType.forClass(
MySimpleInterfaceType.class).as(MyInterfaceType.class);
assertThat(type.resolveGeneric(), equalTo((Class) String.class));
}

@Test
public void resolveTypeVaraibleFromSimpleCollectionInterfaceType() {
public void resolveTypeVariableFromSimpleCollectionInterfaceType() {
ResolvableType type = ResolvableType.forClass(
MyCollectionInterfaceType.class).as(MyInterfaceType.class);
assertThat(type.resolveGeneric(), equalTo((Class) Collection.class));
assertThat(type.resolveGeneric(0, 0), equalTo((Class) String.class));
}

@Test
public void resolveTypeVaraibleFromSimpleSuperclassType() {
public void resolveTypeVariableFromSimpleSuperclassType() {
ResolvableType type = ResolvableType.forClass(
MySimpleSuperclassType.class).as(MySuperclassType.class);
assertThat(type.resolveGeneric(), equalTo((Class) String.class));
}

@Test
public void resolveTypeVaraibleFromSimpleCollectionSuperclassType() {
public void resolveTypeVariableFromSimpleCollectionSuperclassType() {
ResolvableType type = ResolvableType.forClass(
MyCollectionSuperclassType.class).as(MySuperclassType.class);
assertThat(type.resolveGeneric(), equalTo((Class) Collection.class));
Expand Down Expand Up @@ -1459,7 +1452,9 @@ interface Methods<T> {

void charSequenceParameter(List<CharSequence> cs);

<R extends CharSequence & Serializable> R boundedTypeVaraibleResult();
<R extends CharSequence & Serializable> R boundedTypeVariableResult();

Map<String, ? extends List<? extends CharSequence>> boundedTypeVariableWildcardResult();

void nested(Map<Map<String, Integer>, Map<Byte, Long>> p);

Expand Down

0 comments on commit 197dbff

Please sign in to comment.