Fix a bug where TypeParameterMatcher does not detect the case where the type parameter is derived from an outer class

- Fixes #1153
This commit is contained in:
Trustin Lee 2013-03-14 07:22:44 +09:00
parent b86d3d692a
commit 4323fea5fb
2 changed files with 22 additions and 5 deletions

View File

@ -18,7 +18,6 @@ package io.netty.util.internal;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType; import java.lang.reflect.GenericArrayType;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable; import java.lang.reflect.TypeVariable;
@ -40,7 +39,7 @@ public abstract class TypeParameterMatcher {
}; };
public static TypeParameterMatcher find( public static TypeParameterMatcher find(
final Object object, final GenericDeclaration parameterizedSuperclass, final String typeParamName) { final Object object, final Class<?> parameterizedSuperclass, final String typeParamName) {
final Map<Class<?>, Map<String, TypeParameterMatcher>> typeMap = TypeParameterMatcher.typeMap.get(); final Map<Class<?>, Map<String, TypeParameterMatcher>> typeMap = TypeParameterMatcher.typeMap.get();
final Class<?> thisClass = object.getClass(); final Class<?> thisClass = object.getClass();
@ -80,7 +79,7 @@ public abstract class TypeParameterMatcher {
} }
private static Class<?> find0( private static Class<?> find0(
final Object object, GenericDeclaration parameterizedSuperclass, String typeParamName) { final Object object, Class<?> parameterizedSuperclass, String typeParamName) {
final Class<?> thisClass = object.getClass(); final Class<?> thisClass = object.getClass();
Class<?> currentClass = thisClass; Class<?> currentClass = thisClass;
@ -127,9 +126,17 @@ public abstract class TypeParameterMatcher {
// Resolved type parameter points to another type parameter. // Resolved type parameter points to another type parameter.
TypeVariable<?> v = (TypeVariable<?>) actualTypeParam; TypeVariable<?> v = (TypeVariable<?>) actualTypeParam;
currentClass = thisClass; currentClass = thisClass;
parameterizedSuperclass = v.getGenericDeclaration(); if (!(v.getGenericDeclaration() instanceof Class)) {
return Object.class;
}
parameterizedSuperclass = (Class<?>) v.getGenericDeclaration();
typeParamName = v.getName(); typeParamName = v.getName();
continue; if (parameterizedSuperclass.isAssignableFrom(thisClass)) {
continue;
} else {
return Object.class;
}
} }
return fail(thisClass, typeParamName); return fail(thisClass, typeParamName);

View File

@ -118,4 +118,14 @@ public class TypeParameterMatcherTest {
TypeParameterMatcher m = TypeParameterMatcher.find(new U() { }, U.class, "E"); TypeParameterMatcher m = TypeParameterMatcher.find(new U() { }, U.class, "E");
assertTrue(m.match(new Object())); assertTrue(m.match(new Object()));
} }
private static class V<E> {
U<E> u = new U<E>() { };
}
@Test
public void testInnerClass() throws Exception {
TypeParameterMatcher m = TypeParameterMatcher.find(new V<String>().u, U.class, "E");
assertTrue(m.match(new Object()));
}
} }