Class GenericsUtils


public class GenericsUtils
extends java.lang.Object
Utility methods to deal with generic types.
  • Field Details


      public static final GenericsType[] EMPTY_GENERICS_ARRAY

      public static final java.lang.String JAVA_LANG_OBJECT
      See Also:
      Constant Field Values
  • Constructor Details

    • GenericsUtils

      public GenericsUtils()
  • Method Details

    • alignGenericTypes

      @Deprecated public static GenericsType[] alignGenericTypes​(GenericsType[] redirectGenericTypes, GenericsType[] parameterizedTypes, GenericsType[] alignmentTarget)
      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
      (redirectGenericTypes), is used with actual type parameters
      <java.lang.String, U,V>
      , then a class or interface using generic types
      will be aligned to
      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
      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).
      types - the type to be used as the wildcard upper bound
      a wildcard generics type
    • extractPlaceholders

      public static java.util.Map<GenericsType.GenericsTypeName,​GenericsType> extractPlaceholders​(ClassNode type)
      Returns the type parameter/argument relationships of the specified type.
      type - the class node to check
    • extractPlaceholders

      public static void extractPlaceholders​(ClassNode type, java.util.Map<GenericsType.GenericsTypeName,​GenericsType> placeholders)
      Populates the supplied map with the type parameter/argument relationships of the specified type.
      type - the class node to check
      placeholders - the generics type information collector
    • toGenericTypesString

      public static java.lang.String toGenericTypesString​(GenericsType[] genericsTypes)
    • parameterizeInterfaceGenerics

      @Deprecated public static ClassNode parameterizeInterfaceGenerics​(ClassNode hint, ClassNode target)
      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.
      hint - the class node where generics types are parameterized
      target - the interface we want to parameterize generics types
      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.
      hint - the class node where generics types are parameterized
      target - the interface we want to parameterize generics types
      a parameterized interface class node
    • nonGeneric

      public static ClassNode nonGeneric​(ClassNode type)
    • newClass

      public static ClassNode newClass​(ClassNode type)
    • makeClassSafe

      public static ClassNode makeClassSafe​(java.lang.Class klass)
    • makeClassSafeWithGenerics

      public static ClassNode makeClassSafeWithGenerics​(java.lang.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​(java.util.Map<java.lang.String,​ClassNode> genericsSpec, MethodNode mn)
    • correctToGenericsSpecRecurse

      public static ClassNode correctToGenericsSpecRecurse​(java.util.Map<java.lang.String,​ClassNode> genericsSpec, ClassNode type)
    • correctToGenericsSpecRecurse

      public static ClassNode[] correctToGenericsSpecRecurse​(java.util.Map<java.lang.String,​ClassNode> genericsSpec, ClassNode[] types)
    • correctToGenericsSpecRecurse

      public static ClassNode correctToGenericsSpecRecurse​(java.util.Map<java.lang.String,​ClassNode> genericsSpec, ClassNode type, java.util.List<java.lang.String> exclusions)
    • correctToGenericsSpec

      public static ClassNode correctToGenericsSpec​(java.util.Map<java.lang.String,​ClassNode> genericsSpec, GenericsType type)
    • correctToGenericsSpec

      public static ClassNode correctToGenericsSpec​(java.util.Map<java.lang.String,​ClassNode> genericsSpec, ClassNode type)
    • createGenericsSpec

      public static java.util.Map<java.lang.String,​ClassNode> createGenericsSpec​(ClassNode current)
    • createGenericsSpec

      public static java.util.Map<java.lang.String,​ClassNode> createGenericsSpec​(ClassNode current, java.util.Map<java.lang.String,​ClassNode> oldSpec)
    • addMethodGenerics

      public static java.util.Map<java.lang.String,​ClassNode> addMethodGenerics​(MethodNode current, java.util.Map<java.lang.String,​ClassNode> oldSpec)
    • extractSuperClassGenerics

      public static void extractSuperClassGenerics​(ClassNode type, ClassNode target, java.util.Map<java.lang.String,​ClassNode> spec)
    • getSuperClass

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

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

      public static GenericsType[] applyGenericsContextToPlaceHolders​(java.util.Map<java.lang.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.
      genericsSpec - the generics context information spec
      oldPlaceHolders - the old placeholders
      the new generics types
    • clearParameterizedTypeCache

      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

    • 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 tryToFindExactType is false.
    • findParameterizedType

      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.

    • makeDeclaringAndActualGenericsTypeMap

      public static java.util.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 java.util.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
      declaringClass - the generics class node declaring the generics types
      actualReceiver - the sub-class class node
      the placeholder-to-actualtype mapping
    • hasNonPlaceHolders

      public static boolean hasNonPlaceHolders​(ClassNode type)
      Checks if the type has any non-placeholder (aka resolved) generics.
    • hasPlaceHolders

      public static boolean hasPlaceHolders​(ClassNode type)
      Checks if the type has any placeholder (aka unresolved) generics.
    • 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
      samType - the class node which contains only one abstract method
    • findActualTypeByGenericsPlaceholderName

      public static ClassNode findActualTypeByGenericsPlaceholderName​(java.lang.String placeholderName, java.util.Map<GenericsType,​GenericsType> genericsPlaceholderAndTypeMap)
      Gets the actual type according to the placeholder name.
      placeholderName - the placeholder name (i.e. "T", "E", etc.)
      genericsPlaceholderAndTypeMap - the result of makeDeclaringAndActualGenericsTypeMap(ClassNode, ClassNode)