Package org.codehaus.groovy.ast.tools

## Class GenericsUtils

- java.lang.Object
- - org.codehaus.groovy.ast.tools.GenericsUtils

-     public class GenericsUtils
      extends Object

  Utility methods to deal with generic types.

- - ### Field Summary

    Fields
    Modifier and Type | Field | Description
    --- | --- | ---
    `static GenericsType[]` | `EMPTY_GENERICS_ARRAY` |
    `static String` | `JAVA_LANG_OBJECT` |

  - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---
    `GenericsUtils()` |

  - ### Method Summary

    All Methods Static Methods Concrete Methods Deprecated Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `static Map<String,​ClassNode>` | `addMethodGenerics​(MethodNode current, Map<String,​ClassNode> oldSpec)` |
    `static GenericsType[]` | `alignGenericTypes​(GenericsType[] redirectGenericTypes, GenericsType[] parameterizedTypes, GenericsType[] alignmentTarget)` | Deprecated. You shouldn't call this method because it is inherently unreliable
    `static GenericsType[]` | `applyGenericsContextToPlaceHolders​(Map<String,​ClassNode> genericsSpec, GenericsType[] oldPlaceHolders)` | Transforms generics types from an old context to a new context using the given spec.
    `static GenericsType` | `buildWildcardType​(ClassNode... types)` | Generates a wildcard generic type in order to be used for checks against class nodes.
    `static void` | `clearParameterizedTypeCache()` | Clear the parameterized type cache It is useful to IDE as the type being compiled are continuously being edited/altered, see GROOVY-8675
    `static ClassNode` | `correctToGenericsSpec​(Map<String,​ClassNode> genericsSpec, ClassNode type)` |
    `static ClassNode` | `correctToGenericsSpec​(Map<String,​ClassNode> genericsSpec, GenericsType type)` |
    `static MethodNode` | `correctToGenericsSpec​(Map<String,​ClassNode> genericsSpec, MethodNode mn)` |
    `static ClassNode` | `correctToGenericsSpecRecurse​(Map<String,​ClassNode> genericsSpec, ClassNode type)` |
    `static ClassNode[]` | `correctToGenericsSpecRecurse​(Map<String,​ClassNode> genericsSpec, ClassNode[] types)` |
    `static ClassNode` | `correctToGenericsSpecRecurse​(Map<String,​ClassNode> genericsSpec, ClassNode type, List<String> exclusions)` |
    `static Map<String,​ClassNode>` | `createGenericsSpec​(ClassNode current)` |
    `static Map<String,​ClassNode>` | `createGenericsSpec​(ClassNode current, Map<String,​ClassNode> oldSpec)` |
    `static Map<GenericsType.GenericsTypeName,​GenericsType>` | `extractPlaceholders​(ClassNode cn)` |
    `static void` | `extractPlaceholders​(ClassNode node, Map<GenericsType.GenericsTypeName,​GenericsType> map)` | For a given classnode, fills in the supplied map with the parameterized types it defines.
    `static void` | `extractSuperClassGenerics​(ClassNode type, ClassNode target, Map<String,​ClassNode> spec)` |
    `static ClassNode` | `findActualTypeByGenericsPlaceholderName​(String placeholderName, Map<GenericsType,​GenericsType> genericsPlaceholderAndTypeMap)` | Gets the actual type according to the placeholder name.
    `static ClassNode` | `findParameterizedType​(ClassNode genericsClass, ClassNode actualType)` | Convenience method for `findParameterizedType(ClassNode, ClassNode, boolean)` when the `tryToFindExactType` boolean is `false`.
    `static ClassNode` | `findParameterizedType​(ClassNode genericsClass, ClassNode actualType, boolean tryToFindExactType)` | Get the parameterized type by searching the whole class hierarchy according to generics class and actual receiver.
    `static ClassNode` | `findParameterizedTypeFromCache​(ClassNode genericsClass, ClassNode actualType)` | Convenience method for `findParameterizedTypeFromCache(ClassNode, ClassNode, boolean)` when the `tryToFindExactType` boolean is `false`.
    `static ClassNode` | `findParameterizedTypeFromCache​(ClassNode genericsClass, ClassNode actualType, boolean tryToFindExactType)` | Try to get the parameterized type from the cache.
    `static ClassNode` | `getSuperClass​(ClassNode type, ClassNode target)` |
    `static boolean` | `hasNonPlaceHolders​(ClassNode type)` | Checks if the type has any non-placeholder (aka resolved) generics.
    `static boolean` | `hasPlaceHolders​(ClassNode type)` | Checks if the type has any placeholder (aka unresolved) generics.
    `static boolean` | `hasUnresolvedGenerics​(ClassNode type)` | Checks for any placeholder (aka unresolved) generics.
    `static ClassNode` | `makeClassSafe​(Class klass)` |
    `static ClassNode` | `makeClassSafe0​(ClassNode type, GenericsType... genericTypes)` |
    `static ClassNode` | `makeClassSafeWithGenerics​(Class klass, ClassNode genericsType)` |
    `static ClassNode` | `makeClassSafeWithGenerics​(ClassNode type, GenericsType... genericTypes)` |
    `static Map<GenericsType,​GenericsType>` | `makeDeclaringAndActualGenericsTypeMap​(ClassNode declaringClass, ClassNode actualReceiver)` | map declaring generics type to actual generics type, e.g.
    `static Map<GenericsType,​GenericsType>` | `makeDeclaringAndActualGenericsTypeMapOfExactType​(ClassNode declaringClass, ClassNode actualReceiver)` | The method is similar with `makeDeclaringAndActualGenericsTypeMap(ClassNode, ClassNode)`, The main difference is that the method will try to map all placeholders found to the relevant exact types, but the other will not try even if the parameterized type has placeholders
    `static ClassNode` | `newClass​(ClassNode type)` |
    `static ClassNode` | `nonGeneric​(ClassNode type)` |
    `static ClassNode` | `parameterizeInterfaceGenerics​(ClassNode hint, ClassNode target)` | Deprecated. Use #parameterizeType instead
    `static Tuple2<ClassNode[],​ClassNode>` | `parameterizeSAM​(ClassNode samType)` | Gets the parameter and return types of the abstract method of SAM.
    `static ClassNode` | `parameterizeType​(ClassNode hint, ClassNode target)` | Interface class nodes retrieved from `ClassNode.getInterfaces()` or `ClassNode.getAllInterfaces()` are returned with generic type arguments.
    `static ClassNode[]` | `parseClassNodesFromString​(String option, SourceUnit sourceUnit, CompilationUnit compilationUnit, MethodNode mn, ASTNode usage)` |
    `static String` | `toGenericTypesString​(GenericsType[] genericsTypes)` |

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### EMPTY_GENERICS_ARRAY

          public static final GenericsType[] EMPTY_GENERICS_ARRAY

    - #### JAVA_LANG_OBJECT

          public static final String JAVA_LANG_OBJECT

      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### GenericsUtils

          public GenericsUtils()

  - ### Method Detail

    - #### alignGenericTypes

          @Deprecated
          public static GenericsType[] alignGenericTypes​(GenericsType[] redirectGenericTypes,
                                                         GenericsType[] parameterizedTypes,
                                                         GenericsType[] alignmentTarget)

      Deprecated.
      You shouldn't call this method because it is inherently unreliable
      Given a parameterized type and a generic type information, aligns actual type parameters. For example, if a class uses generic type

          <T,U,V>

      (redirectGenericTypes), is used with actual type parameters

          <java.lang.String, U,V>

      , then a class or interface using generic types

          <T,V>

      will be aligned to

          <java.lang.String,V>

      Parameters:
        `redirectGenericTypes` - the type arguments or the redirect class node
        `parameterizedTypes` - the actual type arguments used on this class node
        `alignmentTarget` - the generic type arguments to which we want to align to
      Returns:
        aligned type arguments

    - #### buildWildcardType

          public static GenericsType buildWildcardType​(ClassNode... types)

      Generates a wildcard generic type in order to be used for checks against class nodes. See `GenericsType.isCompatibleWith(org.codehaus.groovy.ast.ClassNode)`.
      Parameters:
        `types` - the type to be used as the wildcard upper bound
      Returns:
        a wildcard generics type

    - #### extractPlaceholders

          public static Map<GenericsType.GenericsTypeName,​GenericsType> extractPlaceholders​(ClassNode cn)

    - #### extractPlaceholders

          public static void extractPlaceholders​(ClassNode node,
                                                 Map<GenericsType.GenericsTypeName,​GenericsType> map)

      For a given classnode, fills in the supplied map with the parameterized types it defines.
      Parameters:
        `node` - the class node to check
        `map` - the generics type information collector

    - #### toGenericTypesString

          public static String toGenericTypesString​(GenericsType[] genericsTypes)

    - #### parameterizeInterfaceGenerics

          @Deprecated
          public static ClassNode parameterizeInterfaceGenerics​(ClassNode hint,
                                                                ClassNode target)

      Deprecated.
      Use #parameterizeType instead
      Interface class nodes retrieved from `ClassNode.getInterfaces()` or `ClassNode.getAllInterfaces()` are returned with generic type arguments. This method allows returning a parameterized interface given the parameterized class node which implements this interface.
      Parameters:
        `hint` - the class node where generics types are parameterized
        `target` - the interface we want to parameterize generics types
      Returns:
        a parameterized interface class node

    - #### parameterizeType

          public static ClassNode parameterizeType​(ClassNode hint,
                                                   ClassNode target)

      Interface class nodes retrieved from `ClassNode.getInterfaces()` or `ClassNode.getAllInterfaces()` are returned with generic type arguments. This method allows returning a parameterized interface given the parameterized class node which implements this interface.
      Parameters:
        `hint` - the class node where generics types are parameterized
        `target` - the interface we want to parameterize generics types
      Returns:
        a parameterized interface class node

    - #### nonGeneric

          public static ClassNode nonGeneric​(ClassNode type)

    - #### newClass

          public static ClassNode newClass​(ClassNode type)

    - #### makeClassSafe

          public static ClassNode makeClassSafe​(Class klass)

    - #### makeClassSafeWithGenerics

          public static ClassNode makeClassSafeWithGenerics​(Class klass,
                                                            ClassNode genericsType)

    - #### makeClassSafe0

          public static ClassNode makeClassSafe0​(ClassNode type,
                                                 GenericsType... genericTypes)

    - #### makeClassSafeWithGenerics

          public static ClassNode makeClassSafeWithGenerics​(ClassNode type,
                                                            GenericsType... genericTypes)

    - #### correctToGenericsSpec

          public static MethodNode correctToGenericsSpec​(Map<String,​ClassNode> genericsSpec,
                                                         MethodNode mn)

    - #### correctToGenericsSpecRecurse

          public static ClassNode correctToGenericsSpecRecurse​(Map<String,​ClassNode> genericsSpec,
                                                               ClassNode type)

    - #### correctToGenericsSpecRecurse

          public static ClassNode[] correctToGenericsSpecRecurse​(Map<String,​ClassNode> genericsSpec,
                                                                 ClassNode[] types)

      Since:
        2.4.1

    - #### correctToGenericsSpecRecurse

          public static ClassNode correctToGenericsSpecRecurse​(Map<String,​ClassNode> genericsSpec,
                                                               ClassNode type,
                                                               List<String> exclusions)

    - #### correctToGenericsSpec

          public static ClassNode correctToGenericsSpec​(Map<String,​ClassNode> genericsSpec,
                                                        GenericsType type)

    - #### correctToGenericsSpec

          public static ClassNode correctToGenericsSpec​(Map<String,​ClassNode> genericsSpec,
                                                        ClassNode type)

    - #### createGenericsSpec

          public static Map<String,​ClassNode> createGenericsSpec​(ClassNode current)

    - #### createGenericsSpec

          public static Map<String,​ClassNode> createGenericsSpec​(ClassNode current,
                                                                       Map<String,​ClassNode> oldSpec)

    - #### addMethodGenerics

          public static Map<String,​ClassNode> addMethodGenerics​(MethodNode current,
                                                                      Map<String,​ClassNode> oldSpec)

    - #### extractSuperClassGenerics

          public static void extractSuperClassGenerics​(ClassNode type,
                                                       ClassNode target,
                                                       Map<String,​ClassNode> spec)

    - #### getSuperClass

          public static ClassNode getSuperClass​(ClassNode type,
                                                ClassNode target)

    - #### parseClassNodesFromString

          public static ClassNode[] parseClassNodesFromString​(String option,
                                                              SourceUnit sourceUnit,
                                                              CompilationUnit compilationUnit,
                                                              MethodNode mn,
                                                              ASTNode usage)

    - #### applyGenericsContextToPlaceHolders

          public static GenericsType[] applyGenericsContextToPlaceHolders​(Map<String,​ClassNode> genericsSpec,
                                                                          GenericsType[] oldPlaceHolders)

      Transforms generics types from an old context to a new context using the given spec. This method assumes all generics types will be placeholders. WARNING: The resulting generics types may or may not be placeholders after the transformation.
      Parameters:
        `genericsSpec` - the generics context information spec
        `oldPlaceHolders` - the old placeholders
      Returns:
        the new generics types

    - #### findParameterizedTypeFromCache

          public static ClassNode findParameterizedTypeFromCache​(ClassNode genericsClass,
                                                                 ClassNode actualType)

      Convenience method for `findParameterizedTypeFromCache(ClassNode, ClassNode, boolean)` when the `tryToFindExactType` boolean is `false`.

    - #### findParameterizedTypeFromCache

          public static ClassNode findParameterizedTypeFromCache​(ClassNode genericsClass,
                                                                 ClassNode actualType,
                                                                 boolean tryToFindExactType)

      Try to get the parameterized type from the cache. If no cached item found, cache and return the result of `findParameterizedType(ClassNode, ClassNode, boolean)`

    - #### findParameterizedType

          public static ClassNode findParameterizedType​(ClassNode genericsClass,
                                                        ClassNode actualType)

      Convenience method for `findParameterizedType(ClassNode, ClassNode, boolean)` when the `tryToFindExactType` boolean is `false`.

    - #### findParameterizedType

          public static ClassNode findParameterizedType​(ClassNode genericsClass,
                                                        ClassNode actualType,
                                                        boolean tryToFindExactType)

      Get the parameterized type by searching the whole class hierarchy according to generics class and actual receiver. `findParameterizedTypeFromCache(ClassNode, ClassNode, boolean)` is strongly recommended for better performance.
      Parameters:
        `genericsClass` - the generics class
        `actualType` - the actual type
        `tryToFindExactType` - whether to try to find exact type
      Returns:
        the parameterized type

    - #### clearParameterizedTypeCache

          public static void clearParameterizedTypeCache()

      Clear the parameterized type cache It is useful to IDE as the type being compiled are continuously being edited/altered, see GROOVY-8675

    - #### makeDeclaringAndActualGenericsTypeMap

          public static Map<GenericsType,​GenericsType> makeDeclaringAndActualGenericsTypeMap​(ClassNode declaringClass,
                                                                                                   ClassNode actualReceiver)

      map declaring generics type to actual generics type, e.g. GROOVY-7204: declaring generics types: T, S extends Serializable actual generics types : String, Long the result map is [ T: String, S: Long ] The resolved types can not help us to choose methods correctly if the argument is a string: T: Object, S: Serializable so we need actual types: T: String, S: Long

    - #### makeDeclaringAndActualGenericsTypeMapOfExactType

          public static Map<GenericsType,​GenericsType> makeDeclaringAndActualGenericsTypeMapOfExactType​(ClassNode declaringClass,
                                                                                                              ClassNode actualReceiver)

      The method is similar with `makeDeclaringAndActualGenericsTypeMap(ClassNode, ClassNode)`, The main difference is that the method will try to map all placeholders found to the relevant exact types, but the other will not try even if the parameterized type has placeholders
      Parameters:
        `declaringClass` - the generics class node declaring the generics types
        `actualReceiver` - the sub-class class node
      Returns:
        the placeholder-to-actualtype mapping
      Since:
        3.0.0

    - #### hasNonPlaceHolders

          public static boolean hasNonPlaceHolders​(ClassNode type)

      Checks if the type has any non-placeholder (aka resolved) generics.
      Since:
        3.0.0

    - #### hasPlaceHolders

          public static boolean hasPlaceHolders​(ClassNode type)

      Checks if the type has any placeholder (aka unresolved) generics.
      Since:
        3.0.0

    - #### hasUnresolvedGenerics

          public static boolean hasUnresolvedGenerics​(ClassNode type)

      Checks for any placeholder (aka unresolved) generics.

    - #### parameterizeSAM

          public static Tuple2<ClassNode[],​ClassNode> parameterizeSAM​(ClassNode samType)

      Gets the parameter and return types of the abstract method of SAM. If the abstract method is not parameterized, we will get generics placeholders, e.g. T, U For example, the abstract method of `Function` is

                R apply(T t);

      We parameterize the above interface as `Function<String, Integer>`, then the abstract method will be

                Integer apply(String t);

      When we call `parameterizeSAM` on the ClassNode `Function<String, Integer>`, we can get parameter types and return type of the above abstract method, i.e. ClassNode `ClassHelper.STRING_TYPE` and `ClassHelper.Integer_TYPE`
      Parameters:
        `samType` - the class node which contains only one abstract method
      Since:
        3.0.0

    - #### findActualTypeByGenericsPlaceholderName

          public static ClassNode findActualTypeByGenericsPlaceholderName​(String placeholderName,
                                                                          Map<GenericsType,​GenericsType> genericsPlaceholderAndTypeMap)

      Gets the actual type according to the placeholder name.
      Parameters:
        `placeholderName` - the placeholder name (i.e. "T", "E", etc.)
        `genericsPlaceholderAndTypeMap` - the result of `makeDeclaringAndActualGenericsTypeMap(ClassNode, ClassNode)`