Top Description Constructors Methods
groovy.transform.stc

public abstract Class ClosureSignatureHint

extends Object
Class Inheritance
Known Direct Subclasses
groovy.transform.stc.FromAbstractTypeMethods, groovy.transform.stc.FromString, groovy.transform.stc.MapEntryOrKeyValue, groovy.transform.stc.SingleSignatureClosureHint
Imports
org.codehaus.groovy.ast.ASTNode, .ClassHelper, .ClassNode, .GenericsType, .MethodNode, .Parameter, org.codehaus.groovy.control.CompilationUnit, .SourceUnit, java.util.List

A closure signature hint class is always used in conjunction with the ClosureParams annotation. It is called at compile time (or may be used by IDEs) to infer the types of the parameters of a groovy.lang.Closure.

A closure hint class is responsible for generating the list of arguments that a closure accepts. Since closures may accept several signatures, getClosureSignatures(org.codehaus.groovy.ast.MethodNode, org.codehaus.groovy.control.SourceUnit, org.codehaus.groovy.control.CompilationUnit, String[], org.codehaus.groovy.ast.ASTNode) should return a list.

Whenever the type checker encounters a method call that targets a method accepting a closure, it will search for the ClosureParams annotation on the groovy.lang.Closure argument. If it is found, then it creates an instance of the hint class and calls the getClosureSignatures(org.codehaus.groovy.ast.MethodNode, org.codehaus.groovy.control.SourceUnit, org.codehaus.groovy.control.CompilationUnit, String[], org.codehaus.groovy.ast.ASTNode) method, which will in turn return the list of signatures.

Note that the signature concept here is used only to describe the parameter types, not the result type, which is found in the generic type argument of the groovy.lang.Closure class.

Several predefined hints can be found, which should cover most of the use cases.

Since
2.3.0

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
protected ClassNode

Returns:

a ClassNode representing the type
findClassNode
(final SourceUnit
source unit
sourceUnit
,
final CompilationUnit
compilation unit
compilationUnit
,
final String
the name of the class we want to get a org.codehaus.groovy.ast.ClassNode for
className
)

Finds a class node given a string representing the type.

public abstract List<ClassNode[]>
getClosureSignatures(MethodNode
the method node for which a groovy.lang.Closure parameter was annotated with ClosureParams
node
,
SourceUnit
the source unit of the file being compiled
sourceUnit
,
CompilationUnit
the compilation unit of the file being compiled
compilationUnit
,
String[]
the options, corresponding to the ClosureParams#options() found on the annotation @return a non-null list of signature, where a signature corresponds to an array of class nodes, each of them matching a parameter.
options
,
ASTNode
the AST node, in the compiled file, which triggered a call to this method. Normally only used for logging/error handling
usage
)

Subclasses should implement this method, which returns the list of accepted closure signatures.

public static ClassNode

Returns:

the n-th generic type, or org.codehaus.groovy.ast.ClassHelper#OBJECT_TYPE if it doesn't exist.
pickGenericType
(ClassNode
the class node from which to pick a generic type
type
,
int
the index of the generic type to extract
gtIndex
)

A helper method which will extract the n-th generic type from a class node.

public static ClassNode

Returns:

the generic type, or org.codehaus.groovy.ast.ClassHelper#OBJECT_TYPE if it doesn't exist.
pickGenericType
(MethodNode
the method node from which the generic type should be picked
node
,
int
the index of the parameter in the method parameter list
parameterIndex
,
int
the index of the generic type to extract
gtIndex
)

A helper method which will extract the n-th generic type from the n-th parameter of a method node.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Constructor Detail

ClosureSignatureHintback to summary
public ClosureSignatureHint()

Method Detail

findClassNodeback to summary
protected ClassNode findClassNode(final SourceUnit sourceUnit, final CompilationUnit compilationUnit, final String className)

Finds a class node given a string representing the type. Performs a lookup in the compilation unit to check if it is done in the same source unit.

Parameters
sourceUnit:SourceUnit

source unit

compilationUnit:CompilationUnit

compilation unit

className:String

the name of the class we want to get a org.codehaus.groovy.ast.ClassNode for

Returns:ClassNode

a ClassNode representing the type

getClosureSignaturesback to summary
public abstract List<ClassNode[]> getClosureSignatures(MethodNode node, SourceUnit sourceUnit, CompilationUnit compilationUnit, String[] options, ASTNode usage)

Subclasses should implement this method, which returns the list of accepted closure signatures.

The compiler will call this method each time, in a source file, a method call using a closure literal is encountered and that the target method has the corresponding groovy.lang.Closure parameter annotated with groovy.transform.stc.ClosureParams. So imagine the following code needs to be compiled:

@groovy.transform.TypeChecked void doSomething() { println ['a','b'].collect { it.toUpperCase() } }

The collect method accepts a closure, but normally, the type checker doesn't have enough type information in the sole org.codehaus.groovy.runtime.DefaultGroovyMethods#collect(java.lang.Iterable, groovy.lang.Closure) method signature to infer the type of it. With the annotation, it will now try to find an annotation on the closure parameter. If it finds it, then an instance of the hint class is created and the type checker calls it with the following arguments:

Now, the hint instance can return the list of expected parameters. Here, it would have to say that the collect method accepts a closure for which the only argument is of the type of the first generic type of the first argument.

With that type information, the type checker can now infer that the type of it is String, because the first argument (here the receiver of the collect method) is a List<String>

Subclasses are therefore expected to return the signatures according to the available context, which is only the target method and the potential options.

Parameters
node:MethodNode

the method node for which a groovy.lang.Closure parameter was annotated with ClosureParams

sourceUnit:SourceUnit

the source unit of the file being compiled

compilationUnit:CompilationUnit

the compilation unit of the file being compiled

options:String[]

the options, corresponding to the ClosureParams#options() found on the annotation @return a non-null list of signature, where a signature corresponds to an array of class nodes, each of them matching a parameter.

usage:ASTNode

the AST node, in the compiled file, which triggered a call to this method. Normally only used for logging/error handling

pickGenericTypeback to summary
public static ClassNode pickGenericType(ClassNode type, int gtIndex)

A helper method which will extract the n-th generic type from a class node.

Parameters
type:ClassNode

the class node from which to pick a generic type

gtIndex:int

the index of the generic type to extract

Returns:ClassNode

the n-th generic type, or org.codehaus.groovy.ast.ClassHelper#OBJECT_TYPE if it doesn't exist.

pickGenericTypeback to summary
public static ClassNode pickGenericType(MethodNode node, int parameterIndex, int gtIndex)

A helper method which will extract the n-th generic type from the n-th parameter of a method node.

Parameters
node:MethodNode

the method node from which the generic type should be picked

parameterIndex:int

the index of the parameter in the method parameter list

gtIndex:int

the index of the generic type to extract

Returns:ClassNode

the generic type, or org.codehaus.groovy.ast.ClassHelper#OBJECT_TYPE if it doesn't exist.