Class ClosureSignatureHint
- java.lang.Object
- 
- groovy.transform.stc.ClosureSignatureHint
 
- 
- Direct Known Subclasses:
- FromAbstractTypeMethods,- FromString,- MapEntryOrKeyValue,- SingleSignatureClosureHint
 
 public abstract class ClosureSignatureHint extends java.lang.ObjectA closure signature hint class is always used in conjunction with the ClosureParamsannotation. It is called at compile time (or may be used by IDEs) to infer the types of the parameters of aClosure.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 ClosureParamsannotation on theClosureargument. If it is found, then it creates an instance of the hint class and calls thegetClosureSignatures(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 Closureclass.Several predefined hints can be found, which should cover most of the use cases. - Since:
- 2.3.0
 
- 
- 
Constructor SummaryConstructors Constructor Description ClosureSignatureHint()
 - 
Method SummaryAll Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description protected ClassNodefindClassNode(SourceUnit sourceUnit, CompilationUnit compilationUnit, java.lang.String className)Finds a class node given a string representing the type.abstract java.util.List<ClassNode[]>getClosureSignatures(MethodNode node, SourceUnit sourceUnit, CompilationUnit compilationUnit, java.lang.String[] options, ASTNode usage)Subclasses should implement this method, which returns the list of accepted closure signatures.static ClassNodepickGenericType(ClassNode type, int gtIndex)A helper method which will extract the n-th generic type from a class node.static ClassNodepickGenericType(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.
 
- 
- 
- 
Method Detail- 
pickGenericTypepublic static ClassNode pickGenericType(ClassNode type, int gtIndex) A helper method which will extract the n-th generic type from a class node.- Parameters:
- type- the class node from which to pick a generic type
- gtIndex- the index of the generic type to extract
- Returns:
- the n-th generic type, or ClassHelper.OBJECT_TYPEif it doesn't exist.
 
 - 
pickGenericTypepublic 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- the method node from which the generic type should be picked
- parameterIndex- the index of the parameter in the method parameter list
- gtIndex- the index of the generic type to extract
- Returns:
- the generic type, or ClassHelper.OBJECT_TYPEif it doesn't exist.
 
 - 
getClosureSignaturespublic abstract java.util.List<ClassNode[]> getClosureSignatures(MethodNode node, SourceUnit sourceUnit, CompilationUnit compilationUnit, java.lang.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 Closureparameter annotated withClosureParams. 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 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:- the method node corresponding to the target method (here, the DefaultGroovyMethods.collect(java.lang.Iterable, groovy.lang.Closure)method
- the (optional) list of options found in the annotation
 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- the method node for which a- Closureparameter was annotated with- ClosureParams
- sourceUnit- the source unit of the file being compiled
- compilationUnit- the compilation unit of the file being compiled
- options- 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- the AST node, in the compiled file, which triggered a call to this method. Normally only used for logging/error handling
 
- the method node corresponding to the target method (here, the 
 - 
findClassNodeprotected ClassNode findClassNode(SourceUnit sourceUnit, CompilationUnit compilationUnit, java.lang.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- source unit
- compilationUnit- compilation unit
- className- the name of the class we want to get a- ClassNodefor
- Returns:
- a ClassNode representing the type
 
 
- 
 
-