<commit_before>/*******************************************************************************
 * Copyright (c) 2009-2011 Sonatype, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution.
 * The Eclipse Public License is available at
 *   http://www.eclipse.org/legal/epl-v10.html
 * The Apache License v2.0 is available at
 *   http://www.apache.org/licenses/LICENSE-2.0.html
 * You may elect to redistribute this code under either of these licenses.
 *******************************************************************************/
package org.sonatype.guice.bean.reflect;

import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;

import com.google.inject.TypeLiteral;

/**
 * Utility methods for dealing with generic type parameters.
 */
public final class TypeParameters
{
    // ----------------------------------------------------------------------
    // Constants
    // ----------------------------------------------------------------------

    private static final TypeLiteral<?>[] NO_TYPE_LITERALS = {};

    private static final TypeLiteral<?> OBJECT_TYPE_LITERAL = TypeLiteral.get( Object.class );

    // ----------------------------------------------------------------------
    // Constructors
    // ----------------------------------------------------------------------

    private TypeParameters()
    {
        // static utility class, not allowed to create instances
    }

    // ----------------------------------------------------------------------
    // Utility methods
    // ----------------------------------------------------------------------

    /**
     * Get all type parameters from a generic type, for example {@code [Foo,Bar]} from {@code Map<Foo,Bar>}.
     * 
     * @param genericType The generic type
     * @return Array of type parameters
     */
    public static TypeLiteral<?>[] get( final TypeLiteral<?> genericType )
    {
        final Type type = genericType.getType();
        if ( type instanceof ParameterizedType )
        {
            final Type[] arguments = ( (ParameterizedType) type ).getActualTypeArguments();
            final TypeLiteral<?>[] parameters = new TypeLiteral[arguments.length];
            for ( int i = 0; i < arguments.length; i++ )
            {
                parameters[i] = expand( arguments[i] );
            }
            return parameters;
        }
        if ( type instanceof GenericArrayType )
        {
            return new TypeLiteral[] { expand( ( (GenericArrayType) type ).getGenericComponentType() ) };
        }
        return NO_TYPE_LITERALS;
    }

    /**
     * Get an indexed type parameter from a generic type, for example {@code Bar} from {@code Map<Foo,Bar>}.
     * 
     * @param genericType The generic type
     * @param index The parameter index
     * @return Indexed type parameter; {@code TypeLiteral<Object>} if the given type is a raw class
     */
    public static TypeLiteral<?> get( final TypeLiteral<?> genericType, final int index )
    {
        final Type type = genericType.getType();
        if ( type instanceof ParameterizedType )
        {
            return expand( ( (ParameterizedType) type ).getActualTypeArguments()[index] );
        }
        if ( type instanceof GenericArrayType )
        {
            if ( 0 == index )
            {
                return expand( ( (GenericArrayType) type ).getGenericComponentType() );
            }
            throw new ArrayIndexOutOfBoundsException( index );
        }
        return OBJECT_TYPE_LITERAL;
    }

    /**
     * Determines if the subType can be converted to the generic superType via an identity or widening conversion.
     * 
     * @param superType The superType
     * @param subType The subType
     * @return {@code 1} if it is strongly assignable; {@code -1} if it is weakly assignable; otherwise {@code 0}
     * @see Class#isAssignableFrom(Class)
     */
    public static int isAssignableFrom( final TypeLiteral<?> superType, final TypeLiteral<?> subType )
    {
        final Class<?> superClazz = superType.getRawType();
        final Class<?> subClazz = subType.getRawType();
        if ( !superClazz.isAssignableFrom( subClazz ) )
        {
            return Object.class == subClazz ? -1 : 0;
        }
        int result = 1;
        final TypeLiteral<?>[] superParams = TypeParameters.get( superType );
        final TypeLiteral<?>[] subParams = TypeParameters.get( subType.getSupertype( superClazz ) );
        for ( int i = 0, len = Math.min( superParams.length, subParams.length ); i < len; i++ )
        {
            final int paramResult = isAssignableFrom( superParams[i], subParams[i] );
            if ( paramResult == 0 )
            {
                return 0;
            }
            if ( paramResult < 0 )
            {
                result = -1;
            }
        }<commit_msg>Generic isAssignableFrom...<commit_after>/*******************************************************************************
 * Copyright (c) 2009-2011 Sonatype, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution.
 * The Eclipse Public License is available at
 *   http://www.eclipse.org/legal/epl-v10.html
 * The Apache License v2.0 is available at
 *   http://www.apache.org/licenses/LICENSE-2.0.html
 * You may elect to redistribute this code under either of these licenses.
 *******************************************************************************/
package org.sonatype.guice.bean.reflect;

import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;

import com.google.inject.TypeLiteral;

/**
 * Utility methods for dealing with generic type parameters.
 */
public final class TypeParameters
{
    // ----------------------------------------------------------------------
    // Constants
    // ----------------------------------------------------------------------

    private static final TypeLiteral<?>[] NO_TYPE_LITERALS = {};

    private static final TypeLiteral<?> OBJECT_TYPE_LITERAL = TypeLiteral.get( Object.class );

    // ----------------------------------------------------------------------
    // Constructors
    // ----------------------------------------------------------------------

    private TypeParameters()
    {
        // static utility class, not allowed to create instances
    }

    // ----------------------------------------------------------------------
    // Utility methods
    // ----------------------------------------------------------------------

    /**
     * Get all type parameters from a generic type, for example {@code [Foo,Bar]} from {@code Map<Foo,Bar>}.
     * 
     * @param genericType The generic type
     * @return Array of type parameters
     */
    public static TypeLiteral<?>[] get( final TypeLiteral<?> genericType )
    {
        final Type type = genericType.getType();
        if ( type instanceof ParameterizedType )
        {
            final Type[] arguments = ( (ParameterizedType) type ).getActualTypeArguments();
            final TypeLiteral<?>[] parameters = new TypeLiteral[arguments.length];
            for ( int i = 0; i < arguments.length; i++ )
            {
                parameters[i] = expand( arguments[i] );
            }
            return parameters;
        }
        if ( type instanceof GenericArrayType )
        {
            return new TypeLiteral[] { expand( ( (GenericArrayType) type ).getGenericComponentType() ) };
        }
        return NO_TYPE_LITERALS;
    }

    /**
     * Get an indexed type parameter from a generic type, for example {@code Bar} from {@code Map<Foo,Bar>}.
     * 
     * @param genericType The generic type
     * @param index The parameter index
     * @return Indexed type parameter; {@code TypeLiteral<Object>} if the given type is a raw class
     */
    public static TypeLiteral<?> get( final TypeLiteral<?> genericType, final int index )
    {
        final Type type = genericType.getType();
        if ( type instanceof ParameterizedType )
        {
            return expand( ( (ParameterizedType) type ).getActualTypeArguments()[index] );
        }
        if ( type instanceof GenericArrayType )
        {
            if ( 0 == index )
            {
                return expand( ( (GenericArrayType) type ).getGenericComponentType() );
            }
            throw new ArrayIndexOutOfBoundsException( index );
        }
        return OBJECT_TYPE_LITERAL;
    }

    /**
     * Determines if the subType can be converted to the generic superType via an identity or widening conversion.
     * 
     * @param superType The superType
     * @param subType The subType
     * @return {@code 1} if it is strongly assignable; {@code -1} if it is weakly assignable; otherwise {@code 0}
     * @see Class#isAssignableFrom(Class)
     */
    public static int isAssignableFrom( final TypeLiteral<?> superType, final TypeLiteral<?> subType )
    {
        final Class<?> superClazz = superType.getRawType();
        final Class<?> subClazz = subType.getRawType();

        if ( !superClazz.isAssignableFrom( subClazz ) )
        {
            return 0; // raw types don't match -> bail out
        }

        if ( superClazz == superType.getType() )
        {
            return 1; // no generic types involved -> OK!
        }

        int result = 1;
        final TypeLiteral<?>[] superParams = TypeParameters.get( superType );
        if ( superParams.length > 0 )
        {
            // all parameters must be assignable for the generic type to be assignable
            final TypeLiteral<?>[] subParams = TypeParameters.get( subType.getSupertype( superClazz ) );
            for ( int i = 0, len = Math.min( superParams.length, subParams.length ); i < len; i++ )
            {
                final int paramResult = isAssignableFrom( superParams[i], subParams[i] );
                if ( paramResult == 0 && Object.class != subParams[i].getRawType() )
                {
                    return 0; // parameter not assignable, and not "place-holder" like <T>
                }
                if ( paramResult <= 0 )
                {
                    result = -1; // "place-holder" parameters like <T> are weakly assignable
                }
            }
        }

{'fraction_non_alphanumeric': 0.19795382016144172, 'fraction_numerical': 0.005913272010512484, 'mean_word_length': 1.8039473684210525, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2021839', 'n_tokens_mistral': 2604, 'n_tokens_neox': 2509, 'n_words': 810}