Type resolveTypeVariables ( final Type type ) { if ( type instanceof Class < ? > ) { // Arrays and non-generic classes have no type variables return type ; } else if ( type instanceof ParameterizedType ) { // Recursively resolve parameterized types final ParameterizedType parameterizedType = ( ParameterizedType ) type ; final Type [ ] typeArgs = parameterizedType . getActualTypeArguments ( ) ; Type [ ] typeArgsResolved = null ; for ( int i = 0 ; i < typeArgs . length ; i ++ ) { // Recursively revolve each parameter of the type final Type typeArgResolved = resolveTypeVariables ( typeArgs [ i ] ) ; // Only compare typeArgs to typeArgResolved until the first difference is found if ( typeArgsResolved == null ) { if ( ! typeArgResolved . equals ( typeArgs [ i ] ) ) { // After the first difference is found, lazily allocate typeArgsResolved typeArgsResolved = new Type [ typeArgs . length ] ; // Go back and copy all the previous args System . arraycopy ( typeArgs , 0 , typeArgsResolved , 0 , i ) ; // Insert the first different arg typeArgsResolved [ i ] = typeArgResolved ; } } else { // After the first difference is found, keep copying the resolved args into the array typeArgsResolved [ i ] = typeArgResolved ; } } if ( typeArgsResolved == null ) { // There were no type parameters to resolve return type ; } else { // Return new ParameterizedType that wraps the resolved type args return new ParameterizedTypeImpl ( ( Class < ? > ) parameterizedType . getRawType ( ) , typeArgsResolved , parameterizedType . getOwnerType ( ) ) ; } } else if ( type instanceof TypeVariable < ? > ) { // Look up concrete type for type variable final TypeVariable < ? > typeVariable = ( TypeVariable < ? > ) type ; for ( int i = 0 ; i < typeVariables . length ; i ++ ) { if ( typeVariables [ i ] . getName ( ) . equals ( typeVariable . getName ( ) ) ) { return resolvedTypeArguments [ i ] ; } } // Could not resolve type variable return type ; } else if ( type instanceof GenericArrayType ) { // Count the array dimensions, and resolve the innermost type of the array int numArrayDims = 0 ; Type t = type ; while ( t instanceof GenericArrayType ) { numArrayDims ++ ; t = ( ( GenericArrayType ) t ) . getGenericComponentType ( ) ; } final Type innermostType = t ; final Type innermostTypeResolved = resolveTypeVariables ( innermostType ) ; if ( ! ( innermostTypeResolved instanceof Class < ? > ) ) { throw new IllegalArgumentException ( "Could not resolve generic array type " + type ) ; } final Class < ? > innermostTypeResolvedClass = ( Class < ? > ) innermostTypeResolved ; // Build an array to hold the size of each dimension, filled with zeroes final int [ ] dims = ( int [ ] ) Array . newInstance ( int . class , numArrayDims ) ; // Build a zero-sized array of the required number of dimensions, using the resolved innermost class final Object arrayInstance = Array . newInstance ( innermostTypeResolvedClass , dims ) ; // Get the class of this array instance -- this is the resolved array type return arrayInstance . getClass ( ) ; } else if ( type instanceof WildcardType ) { // TODO: Support WildcardType throw ClassGraphException . newClassGraphException ( "WildcardType not yet supported: " + type ) ; } else { throw ClassGraphException . newClassGraphException ( "Got unexpected type: " + type ) ; } }
Resolve the type variables in a type using a type variable resolution list producing a resolved type .