LANG-1348 - StackOverflowError on TypeUtils.toString(...) for a generic return type of Enum.valueOf (closes #292)
This commit is contained in:
parent
36217ee164
commit
cc6beb2d05
|
@ -1788,7 +1788,7 @@ public class TypeUtils {
|
|||
|
||||
final Type useOwner = p.getOwnerType();
|
||||
final Class<?> raw = (Class<?>) p.getRawType();
|
||||
final Type[] typeArguments = p.getActualTypeArguments();
|
||||
|
||||
if (useOwner == null) {
|
||||
buf.append(raw.getName());
|
||||
} else {
|
||||
|
@ -1800,10 +1800,46 @@ public class TypeUtils {
|
|||
buf.append('.').append(raw.getSimpleName());
|
||||
}
|
||||
|
||||
appendAllTo(buf.append('<'), ", ", typeArguments).append('>');
|
||||
final int[] recursiveTypeIndexes = findRecursiveTypes(p);
|
||||
|
||||
if (recursiveTypeIndexes.length > 0) {
|
||||
appendRecursiveTypes(buf, recursiveTypeIndexes, p.getActualTypeArguments());
|
||||
} else {
|
||||
appendAllTo(buf.append('<'), ", ", p.getActualTypeArguments()).append('>');
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private static void appendRecursiveTypes(StringBuilder buf, int[] recursiveTypeIndexes, Type[] argumentTypes) {
|
||||
for (int i = 0; i < recursiveTypeIndexes.length; i++) {
|
||||
appendAllTo(buf.append('<'), ", ", argumentTypes[i].toString()).append('>');
|
||||
}
|
||||
|
||||
final Type[] argumentsFiltered = ArrayUtils.removeAll(argumentTypes, recursiveTypeIndexes);
|
||||
|
||||
if (argumentsFiltered.length > 0) {
|
||||
appendAllTo(buf.append('<'), ", ", argumentsFiltered).append('>');
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] findRecursiveTypes(ParameterizedType p) {
|
||||
Type[] filteredArgumentTypes = Arrays.copyOf(p.getActualTypeArguments(), p.getActualTypeArguments().length);
|
||||
int[] indexesToRemove = new int[] {};
|
||||
for (int i = 0; i < filteredArgumentTypes.length; i++) {
|
||||
if (filteredArgumentTypes[i] instanceof TypeVariable<?>) {
|
||||
if (containsVariableTypeSameParametrizedTypeBound(((TypeVariable<?>) filteredArgumentTypes[i]), p)) {
|
||||
indexesToRemove = ArrayUtils.add(indexesToRemove, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return indexesToRemove;
|
||||
}
|
||||
|
||||
private static boolean containsVariableTypeSameParametrizedTypeBound(TypeVariable<?> typeVariable, ParameterizedType p) {
|
||||
return ArrayUtils.contains(typeVariable.getBounds(), p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a {@link WildcardType} as a {@link String}.
|
||||
* @param w {@code WildcardType} to format
|
||||
|
@ -1840,7 +1876,7 @@ public class TypeUtils {
|
|||
* @return {@code buf}
|
||||
* @since 3.2
|
||||
*/
|
||||
private static StringBuilder appendAllTo(final StringBuilder buf, final String sep, final Type... types) {
|
||||
private static <T> StringBuilder appendAllTo(final StringBuilder buf, final String sep, final T... types) {
|
||||
Validate.notEmpty(Validate.noNullElements(types));
|
||||
if (types.length > 0) {
|
||||
buf.append(toString(types[0]));
|
||||
|
@ -1851,4 +1887,8 @@ public class TypeUtils {
|
|||
return buf;
|
||||
}
|
||||
|
||||
private static <T> String toString(T object) {
|
||||
return object instanceof Type ? toString((Type) object) : object.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -781,6 +781,12 @@ public class TypeUtilsTest<B> {
|
|||
Assert.assertTrue(TypeUtils.isAssignable(fromType, failingToType));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLANG1348() throws Exception {
|
||||
final Method method = Enum.class.getMethod("valueOf", Class.class, String.class);
|
||||
Assert.assertEquals("T extends java.lang.Enum<T>", TypeUtils.toString(method.getGenericReturnType()));
|
||||
}
|
||||
|
||||
public Iterable<? extends Map<Integer, ? extends Collection<?>>> iterable;
|
||||
|
||||
public static <G extends Comparable<G>> G stub() {
|
||||
|
|
Loading…
Reference in New Issue