Provide 'with implementationType' overloads
Provided overloaded versions of `forField` and `forMethodParameter` that accept a `ResolvableType` implementation type (as opposed to a Class). Primarily added to allow resolution against implementation types that have been created programmatically using `forTypeWithGenerics`. Issue: SPR-11218
This commit is contained in:
parent
7e6dbc24f6
commit
9076c70d47
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -835,6 +835,23 @@ public final class ResolvableType implements Serializable {
|
||||||
return forType(null, new FieldTypeProvider(field), owner.asVariableResolver());
|
return forType(null, new FieldTypeProvider(field), owner.asVariableResolver());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a {@link ResolvableType} for the specified {@link Field} with a given
|
||||||
|
* implementation.
|
||||||
|
* <p>Use this variant when the class that declares the field includes generic
|
||||||
|
* parameter variables that are satisfied by the implementation type.
|
||||||
|
* @param field the source field
|
||||||
|
* @param implementationType the implementation type
|
||||||
|
* @return a {@link ResolvableType} for the specified field
|
||||||
|
* @see #forField(Field)
|
||||||
|
*/
|
||||||
|
public static ResolvableType forField(Field field, ResolvableType implementationType) {
|
||||||
|
Assert.notNull(field, "Field must not be null");
|
||||||
|
implementationType = (implementationType == null ? NONE : implementationType);
|
||||||
|
ResolvableType owner = implementationType.as(field.getDeclaringClass());
|
||||||
|
return forType(null, new FieldTypeProvider(field), owner.asVariableResolver());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a {@link ResolvableType} for the specified {@link Field} with the
|
* Return a {@link ResolvableType} for the specified {@link Field} with the
|
||||||
* given nesting level.
|
* given nesting level.
|
||||||
|
|
@ -963,7 +980,25 @@ public final class ResolvableType implements Serializable {
|
||||||
* @see #forMethodParameter(Method, int)
|
* @see #forMethodParameter(Method, int)
|
||||||
*/
|
*/
|
||||||
public static ResolvableType forMethodParameter(MethodParameter methodParameter) {
|
public static ResolvableType forMethodParameter(MethodParameter methodParameter) {
|
||||||
return forMethodParameter(methodParameter, null);
|
return forMethodParameter(methodParameter, (Type) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a {@link ResolvableType} for the specified {@link MethodParameter} with a
|
||||||
|
* given implementation type. Use this variant when the class that declares the method
|
||||||
|
* includes generic parameter variables that are satisfied by the implementation type.
|
||||||
|
* @param methodParameter the source method parameter (must not be {@code null})
|
||||||
|
* @param implementationType the implementation type
|
||||||
|
* @return a {@link ResolvableType} for the specified method parameter
|
||||||
|
* @see #forMethodParameter(MethodParameter)
|
||||||
|
*/
|
||||||
|
public static ResolvableType forMethodParameter(MethodParameter methodParameter, ResolvableType implementationType) {
|
||||||
|
Assert.notNull(methodParameter, "MethodParameter must not be null");
|
||||||
|
implementationType = (implementationType == null ? forType(methodParameter.getContainingClass()) : implementationType);
|
||||||
|
ResolvableType owner = implementationType.as(methodParameter.getDeclaringClass());
|
||||||
|
return forType(null, new MethodParameterTypeProvider(methodParameter),
|
||||||
|
owner.asVariableResolver()).getNested(methodParameter.getNestingLevel(),
|
||||||
|
methodParameter.typeIndexesPerLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -659,6 +659,16 @@ public class ResolvableTypeTests {
|
||||||
assertThat(type.getGeneric().resolve(), equalTo((Class) String.class));
|
assertThat(type.getGeneric().resolve(), equalTo((Class) String.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveTypeVariableFromFieldTypeWithImplementsType() throws Exception {
|
||||||
|
ResolvableType implementationType = ResolvableType.forClassWithGenerics(
|
||||||
|
Fields.class, Integer.class);
|
||||||
|
ResolvableType type = ResolvableType.forField(
|
||||||
|
Fields.class.getField("parameterizedType"), implementationType);
|
||||||
|
assertThat(type.resolve(), equalTo((Class) List.class));
|
||||||
|
assertThat(type.getGeneric().resolve(), equalTo((Class) Integer.class));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resolveTypeVariableFromSuperType() throws Exception {
|
public void resolveTypeVariableFromSuperType() throws Exception {
|
||||||
ResolvableType type = ResolvableType.forClass(ExtendsList.class);
|
ResolvableType type = ResolvableType.forClass(ExtendsList.class);
|
||||||
|
|
@ -735,6 +745,16 @@ public class ResolvableTypeTests {
|
||||||
assertThat(type.getType().toString(), equalTo("T"));
|
assertThat(type.getType().toString(), equalTo("T"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resolveTypeVariableFromMethodParameterTypeWithImplementsType() throws Exception {
|
||||||
|
Method method = Methods.class.getMethod("typedParameter", Object.class);
|
||||||
|
MethodParameter methodParameter = MethodParameter.forMethodOrConstructor(method, 0);
|
||||||
|
ResolvableType implementationType = ResolvableType.forClassWithGenerics(Methods.class, Integer.class);
|
||||||
|
ResolvableType type = ResolvableType.forMethodParameter(methodParameter, implementationType);
|
||||||
|
assertThat(type.resolve(), equalTo((Class) Integer.class));
|
||||||
|
assertThat(type.getType().toString(), equalTo("T"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resolveTypeVariableFromMethodReturn() throws Exception {
|
public void resolveTypeVariableFromMethodReturn() throws Exception {
|
||||||
Method method = Methods.class.getMethod("typedReturn");
|
Method method = Methods.class.getMethod("typedReturn");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue