Package: org.codehaus.groovy.ast.tools

## [Java] Class GenericsUtils

- org.codehaus.groovy.ast.tools.GenericsUtils

-     public class GenericsUtils
      extends Object

  Utility methods for working with parameterized (generic) types in Groovy AST.

  Provides comprehensive support for generic type operations including:

  - Type parameter extraction and alignment
  - Wildcard type construction and handling
  - Generic type specification creation and resolution
  - Inheritance hierarchy generic type parameterization
  - Type compatibility and assignability checks with generics

  Used extensively in static type checking, method resolution, and AST transformation to properly handle Java generic type syntax in Groovy code.

  See Also:
    for type parameter/argument representation
    for class information with generics
    for related class utilities

- - ### Field Summary

    Fields
    Modifiers | Name | Description
    --- | --- | ---
    `static GenericsType[]` | `EMPTY_GENERICS_ARRAY` | An empty array of generic type arguments, used as a constant to avoid repeated allocations.
    `static String` | `JAVA_LANG_OBJECT` | Canonical string representation of `java.lang.Object`.

  - ### Methods Summary

    Methods
    Type Params | Return Type | Name and description
    --- | --- | ---
    `` | `public static Map<String, ClassNode>` | `addMethodGenerics(MethodNode node, Map<String, ClassNode> oldSpec)` Since: 2.4.1
    `` | `public static GenericsType[]` | `alignGenericTypes(GenericsType[] redirectGenericTypes, GenericsType[] parameterizedTypes, GenericsType[] alignmentTarget)` Given a parameterized type and a generic type information, aligns actual type parameters.
    `` | `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.
    `` | `public static GenericsType` | `buildWildcardType(ClassNode upperBounds)` Generates a wildcard generic type in order to be used for checks against class nodes.
    `` | `public static void` | `clearParameterizedTypeCache()` Clears the parameterized type cache.
    `` | `public static MethodNode` | `correctToGenericsSpec(Map<String, ClassNode> genericsSpec, MethodNode mn)` Since: 2.3.0
    `` | `public static ClassNode` | `correctToGenericsSpec(Map<String, ClassNode> genericsSpec, GenericsType type)` Since: 2.3.0
    `` | `public static ClassNode` | `correctToGenericsSpec(Map<String, ClassNode> genericsSpec, ClassNode type)` Since: 2.3.0
    `` | `public static ClassNode` | `correctToGenericsSpecRecurse(Map<String, ClassNode> genericsSpec, ClassNode type)` Since: 2.3.0
    `` | `public static ClassNode[]` | `correctToGenericsSpecRecurse(Map<String, ClassNode> genericsSpec, ClassNode[] types)` Since: 2.4.1
    `` | `public static ClassNode` | `correctToGenericsSpecRecurse(Map<String, ClassNode> genericsSpec, ClassNode type, List<String> exclusions)` Since: 2.4.1
    `` | `public static Map<String, ClassNode>` | `createGenericsSpec(ClassNode type)` Since: 2.4.0
    `` | `public static Map<String, ClassNode>` | `createGenericsSpec(ClassNode type, Map<String, ClassNode> oldSpec)` Since: 2.3.0
    `` | `public static ClassNode` | `erasure(ClassNode type)` Computes the erasure of a type, safe to declare in a generated signature that cannot carry the original type variables: a generics placeholder is replaced by its bound (`T extends Number` → `Number`) and type arguments are dropped (`List<T>` → `List`).
    `` | `public static Map<GenericsType.GenericsTypeName, GenericsType>` | `extractPlaceholders(ClassNode type)` Returns the type parameter/argument relationships of the specified type.
    `` | `public static void` | `extractPlaceholders(ClassNode type, Map<GenericsType.GenericsTypeName, GenericsType> placeholders)` Populates the supplied map with the type parameter/argument relationships of the specified type.
    `` | `public static void` | `extractSuperClassGenerics(ClassNode type, ClassNode target, Map<String, ClassNode> spec)` Since: 2.3.1
    `` | `public static ClassNode` | `findActualTypeByGenericsPlaceholderName(String placeholderName, Map<GenericsType, GenericsType> genericsPlaceholderAndTypeMap)` Gets the actual type according to the placeholder name.
    `` | `public static ClassNode` | `findParameterizedType(ClassNode genericsClass, ClassNode actualType)` Convenience method for findParameterizedType(ClassNode,ClassNode,boolean) with `tryToFindExactType` set to `false`.
    `` | `public static ClassNode` | `findParameterizedType(ClassNode genericsClass, ClassNode actualType, boolean tryToFindExactType)` Gets the parameterized type by searching the whole class hierarchy according to generics class and actual receiver.
    `` | `public static ClassNode` | `findParameterizedTypeFromCache(ClassNode genericsClass, ClassNode actualType)` Convenience method for findParameterizedTypeFromCache(ClassNode,ClassNode,boolean) with `tryToFindExactType` set to `false`.
    `` | `public static ClassNode` | `findParameterizedTypeFromCache(ClassNode genericsClass, ClassNode actualType, boolean tryToFindExactType)` Try to get the parameterized type from the cache.
    `` | `public static ClassNode` | `getSuperClass(ClassNode type, ClassNode target)` Since: 3.0.0
    `` | `public static boolean` | `hasNonPlaceHolders(ClassNode type)` Checks if the type has any non-placeholder (aka resolved) generics.
    `` | `public static boolean` | `hasPlaceHolders(ClassNode type)` Checks if the type has any placeholder (aka unresolved) generics.
    `` | `public static boolean` | `hasUnresolvedGenerics(ClassNode type)` Checks for any placeholder (aka unresolved) generics.
    `` | `public static ClassNode` | `makeClassSafe(Class klass)` Since: 2.3.0
    `` | `public static ClassNode` | `makeClassSafe0(ClassNode type, GenericsType genericTypes)` Since: 2.3.0
    `` | `public static ClassNode` | `makeClassSafeWithGenerics(Class klass, ClassNode genericsType)` Since: 2.4.0
    `` | `public static ClassNode` | `makeClassSafeWithGenerics(ClassNode type, GenericsType genericTypes)` Since: 2.3.0
    `` | `public static Map<GenericsType, GenericsType>` | `makeDeclaringAndActualGenericsTypeMap(ClassNode declaringClass, ClassNode actualReceiver)` map declaring generics type to actual generics type, e.g.
    `` | `public static Map<GenericsType, GenericsType>` | `makeDeclaringAndActualGenericsTypeMapOfExactType(ClassNode declaringClass, ClassNode actualReceiver)` The method is similar with GenericsUtils.makeDeclaringAndActualGenericsTypeMap, 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
    `` | `public static ClassNode` | `newClass(ClassNode type)` Since: 2.3.0
    `` | `public static ClassNode` | `nonGeneric(ClassNode type)` Since: 2.3.0
    `` | `public static ClassNode` | `parameterizeInterfaceGenerics(ClassNode hint, ClassNode target)` Interface class nodes retrieved from ClassNode.getInterfaces or ClassNode.getAllInterfaces are returned with generic type arguments.
    `` | `public static Tuple2<ClassNode, ClassNode>` | `parameterizeSAM(ClassNode samType)` Gets the parameter and return types of the abstract method of SAM.
    `` | `public static ClassNode` | `parameterizeType(ClassNode hint, ClassNode target)` Interface class nodes retrieved from ClassNode.getInterfaces or ClassNode.getAllInterfaces are returned with generic type arguments.
    `` | `public static ClassNode[]` | `parseClassNodesFromString(String option, SourceUnit sourceUnit, CompilationUnit compilationUnit, MethodNode mn, ASTNode usage)` Since: 2.4.0
    `` | `public static String` | `toGenericTypesString(GenericsType[] genericsTypes)` Since: 3.0.0

  - ### Inherited Methods Summary

    Inherited Methods
    Methods inherited from class | Name
    --- | ---
    `class Object` | `equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### public static final GenericsType[] EMPTY_GENERICS_ARRAY

      An empty array of generic type arguments, used as a constant to avoid repeated allocations.

      Since:
        2.0.0

    - #### public static final String JAVA_LANG_OBJECT

      Canonical string representation of `java.lang.Object`.

      Since:
        3.0.0

  - ### Method Detail

    - #### public static Map<String, ClassNode> addMethodGenerics(MethodNode node, Map<String, ClassNode> oldSpec)

      Since:
        2.4.1

    - #### @Deprecated(forRemoval = true, since = "2.3.0")
      public static GenericsType[] alignGenericTypes(GenericsType[] redirectGenericTypes, GenericsType[] parameterizedTypes, GenericsType[] alignmentTarget)

      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>

      deprecated:
        You shouldn't call this method because it is inherently unreliable.
      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
      Since:
        2.0.0

    - #### 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
      Since:
        2.5.0

    - #### public static GenericsType buildWildcardType(ClassNode upperBounds)

      Generates a wildcard generic type in order to be used for checks against class nodes. See GenericsType.isCompatibleWith.

      Since:
        2.0.0

    - #### public static void clearParameterizedTypeCache()

      Clears the parameterized type cache.

      It is useful to IDE as the type being compiled are continuously being edited/altered; see GROOVY-8675

      Since:
        3.0.0

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

      Since:
        2.3.0

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

      Since:
        2.3.0

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

      Since:
        2.3.0

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

      Since:
        2.3.0

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

      Since:
        2.4.1

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

      Since:
        2.4.1

    - #### public static Map<String, ClassNode> createGenericsSpec(ClassNode type)

      Since:
        2.4.0

    - #### public static Map<String, ClassNode> createGenericsSpec(ClassNode type, Map<String, ClassNode> oldSpec)

      Since:
        2.3.0

    - #### public static ClassNode erasure(ClassNode type)

      Computes the erasure of a type, safe to declare in a generated signature that cannot carry the original type variables: a generics placeholder is replaced by its bound (`T extends Number` → `Number`) and type arguments are dropped (`List<T>` → `List`).

      Since:
        6.0.0

    - #### public static Map<GenericsType.GenericsTypeName, GenericsType> extractPlaceholders(ClassNode type)

      Returns the type parameter/argument relationships of the specified type.

      Since:
        2.0.0

    - #### public static void extractPlaceholders(ClassNode type, Map<GenericsType.GenericsTypeName, GenericsType> placeholders)

      Populates the supplied map with the type parameter/argument relationships of the specified type.

      Since:
        2.0.0

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

      Since:
        2.3.1

    - #### @Deprecated(forRemoval = true, since = "5.0.0")
      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
      Since:
        3.0.0

    - #### public static ClassNode findParameterizedType(ClassNode genericsClass, ClassNode actualType)

      Convenience method for findParameterizedType(ClassNode,ClassNode,boolean) with `tryToFindExactType` set to `false`.

      Since:
        3.0.0

    - #### public static ClassNode findParameterizedType(ClassNode genericsClass, ClassNode actualType, boolean tryToFindExactType)

      Gets 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.

      Since:
        3.0.0

    - #### public static ClassNode findParameterizedTypeFromCache(ClassNode genericsClass, ClassNode actualType)

      Convenience method for findParameterizedTypeFromCache(ClassNode,ClassNode,boolean) with `tryToFindExactType` set to `false`.

      Since:
        3.0.0

    - #### 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).

      Since:
        3.0.0

    - #### public static ClassNode getSuperClass(ClassNode type, ClassNode target)

      Since:
        3.0.0

    - #### public static boolean hasNonPlaceHolders(ClassNode type)

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

      Since:
        3.0.0

    - #### public static boolean hasPlaceHolders(ClassNode type)

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

      Since:
        3.0.0

    - #### public static boolean hasUnresolvedGenerics(ClassNode type)

      Checks for any placeholder (aka unresolved) generics.

      Since:
        4.0.0

    - #### public static ClassNode makeClassSafe(Class klass)

      Since:
        2.3.0

    - #### public static ClassNode makeClassSafe0(ClassNode type, GenericsType genericTypes)

      Since:
        2.3.0

    - #### public static ClassNode makeClassSafeWithGenerics(Class klass, ClassNode genericsType)

      Since:
        2.4.0

    - #### public static ClassNode makeClassSafeWithGenerics(ClassNode type, GenericsType genericTypes)

      Since:
        2.3.0

    - #### @Deprecated(forRemoval = true, since = "5.0.0")
      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

      Since:
        3.0.0

    - #### @Deprecated(forRemoval = true, since = "5.0.0")
      public static Map<GenericsType, GenericsType> makeDeclaringAndActualGenericsTypeMapOfExactType(ClassNode declaringClass, ClassNode actualReceiver)

      The method is similar with GenericsUtils.makeDeclaringAndActualGenericsTypeMap, 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 subclass class node
      Returns:
        the placeholder-to-actualtype mapping
      Since:
        3.0.0

    - #### public static ClassNode newClass(ClassNode type)

      Since:
        2.3.0

    - #### public static ClassNode nonGeneric(ClassNode type)

      Since:
        2.3.0

    - #### @Deprecated(forRemoval = true, since = "2.5.0")
      public static ClassNode parameterizeInterfaceGenerics(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.

      deprecated:
        Use #parameterizeType instead
      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
      Since:
        2.0.0

    - #### 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

    - #### 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 ClassNode where generics types are parameterized
        `target` - the interface we want to parameterize generics types
      Returns:
        a parameterized interface ClassNode
      Since:
        2.1.0

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

      Since:
        2.4.0

    - #### public static String toGenericTypesString(GenericsType[] genericsTypes)

      Since:
        3.0.0