@@ -194,31 +194,42 @@ public static TypeDetails resolveTypeVariableFromParameterizedType(
194194 ParameterizedTypeDetails parameterizedType ,
195195 TypeVariableDetails typeVariable ) {
196196 final ClassDetails classDetails = parameterizedType .getRawClassDetails ();
197- final List <TypeVariableDetails > typeParameters = classDetails .getTypeParameters ();
198- final List <TypeDetails > typeArguments = parameterizedType .getArguments ();
199- assert typeParameters .size () == typeArguments .size ();
197+ final TypeDetails typeArgument = findMatchingTypeArgument (
198+ classDetails .getTypeParameters (),
199+ parameterizedType .getArguments (),
200+ typeVariable .getIdentifier ()
201+ );
202+
203+ // If no type argument is found, or the type variable is defined by another
204+ // class, try resolving it in the generic super type if present
205+ if ( typeArgument == null || classDetails != typeVariable .getDeclaringType () ) {
206+ final TypeDetails genericSuper = classDetails .getGenericSuperType ();
207+ final TypeDetails resolvedType = genericSuper != null ?
208+ genericSuper .resolveTypeVariable ( typeVariable ) :
209+ null ;
210+ if ( typeArgument == null || resolvedType != null
211+ && resolvedType .getTypeKind () != TypeDetails .Kind .TYPE_VARIABLE ) {
212+ return resolvedType ;
213+ }
214+ }
215+
216+ // Either we found the exact type variable's argument, or the parameterized class redefines
217+ // a type variable with the same identifier as a supertype, and it should be ignored.
218+ // Return the matching generic type argument
219+ return typeArgument ;
220+ }
200221
222+ private static TypeDetails findMatchingTypeArgument (
223+ List <TypeVariableDetails > typeParameters ,
224+ List <TypeDetails > typeArguments ,
225+ String identifier ) {
226+ assert typeParameters .size () == typeArguments .size ();
201227 for ( int i = 0 ; i < typeParameters .size (); i ++ ) {
202228 final TypeVariableDetails typeParameter = typeParameters .get ( i );
203- if ( typeParameter .getIdentifier ().equals ( typeVariable .getIdentifier () ) ) {
204- if ( classDetails != typeVariable .getDeclaringType () ) {
205- final TypeDetails genericSuper = classDetails .getGenericSuperType ();
206- if ( genericSuper != null && genericSuper .getTypeKind () == TypeDetails .Kind .PARAMETERIZED_TYPE ) {
207- // Recursively check if the type variable is resolved in supertypes
208- final TypeDetails superResolvedType = classDetails .resolveTypeVariable ( typeVariable );
209- if ( superResolvedType .getTypeKind () != TypeDetails .Kind .TYPE_VARIABLE
210- && superResolvedType != OBJECT_TYPE_DETAILS ) {
211- return superResolvedType ;
212- }
213- }
214- }
215- // Either we found the exact parameter definition, or the local generic supertype
216- // redefines a type variable with the same identifier, and we should ignore it.
217- // Return the matching generic type argument
229+ if ( typeParameter .getIdentifier ().equals ( identifier ) ) {
218230 return typeArguments .get ( i );
219231 }
220232 }
221-
222233 return null ;
223234 }
224235
0 commit comments