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 unreliablestatic 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-8675static 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, boolean tryToFindExactType)
Get the parameterized type by search the whole class hierarchy according to generics class and actual receiver.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 parameterizedType)
Check whether the ClassNode has non generics placeholders, aka not placeholderstatic boolean
hasPlaceHolders(ClassNode parameterizedType)
Check whether the ClassNode has generics placeholdersstatic 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 withmakeDeclaringAndActualGenericsTypeMap(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 placeholdersstatic ClassNode
newClass(ClassNode type)
static ClassNode
nonGeneric(ClassNode type)
static ClassNode
parameterizeInterfaceGenerics(ClassNode hint, ClassNode target)
Deprecated.Use #parameterizeType insteadstatic 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 fromClassNode.getInterfaces()
orClassNode.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)
-
-
-
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
-
-
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 unreliableGiven 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 nodeparameterizedTypes
- the actual type arguments used on this class nodealignmentTarget
- 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. SeeGenericsType.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 checkmap
- 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 insteadInterface class nodes retrieved fromClassNode.getInterfaces()
orClassNode.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 parameterizedtarget
- 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 fromClassNode.getInterfaces()
orClassNode.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 parameterizedtarget
- the interface we want to parameterize generics types- Returns:
- a parameterized interface class node
-
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, 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)
-
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 specoldPlaceHolders
- the old placeholders- Returns:
- the new generics types
-
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 offindParameterizedType(ClassNode, ClassNode, boolean)
-
findParameterizedType
public static ClassNode findParameterizedType(ClassNode genericsClass, ClassNode actualType, boolean tryToFindExactType)
Get the parameterized type by search 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 classactualType
- the actual typetryToFindExactType
- 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 withmakeDeclaringAndActualGenericsTypeMap(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 typesactualReceiver
- the sub-class class node- Returns:
- the placeholder-to-actualtype mapping
- Since:
- 3.0.0
-
hasNonPlaceHolders
public static boolean hasNonPlaceHolders(ClassNode parameterizedType)
Check whether the ClassNode has non generics placeholders, aka not placeholder- Parameters:
parameterizedType
- the class node- Returns:
- the result
- Since:
- 3.0.0
-
hasPlaceHolders
public static boolean hasPlaceHolders(ClassNode parameterizedType)
Check whether the ClassNode has generics placeholders- Parameters:
parameterizedType
- the class node- Returns:
- the result
- Since:
- 3.0.0
-
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 ofFunction
isR apply(T t);
We parameterize the above interface asFunction<String, Integer>
, then the abstract method will beInteger apply(String t);
When we callparameterizeSAM
on the ClassNodeFunction<String, Integer>
, we can get parameter types and return type of the above abstract method, i.e. ClassNodeClassHelper.STRING_TYPE
andClassHelper.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 ofmakeDeclaringAndActualGenericsTypeMap(ClassNode, ClassNode)
-
-