Package: org.codehaus.groovy.transform.stc

## [Java] Class GroovyTypeCheckingExtensionSupport

- org.codehaus.groovy.transform.stc.GroovyTypeCheckingExtensionSupport

-     public class GroovyTypeCheckingExtensionSupport
      extends AbstractTypeCheckingExtension

  Base class for type checking extensions written in Groovy. Compared to its superclass, TypeCheckingExtension, this class adds a number of utility methods aimed at leveraging the syntax of the Groovy language to improve expressiveness and conciseness.

  Since:
    2.1.0

- - ### Nested Class Summary

    Nested classes
    Modifiers | Name | Description
    --- | --- | ---
    `static class` | `GroovyTypeCheckingExtensionSupport.TypeCheckingDSL` | Event handler registration: setup Registers closure that runs after the type checker finishes initialization finish Registers closure that runs after the type checker completes type checking beforeVisitClass Registers closure that runs before type checking a class afterVisitClass Registers closure that runs after having finished the visit of a type checked class beforeVisitMethod Registers closure that runs before type checking a method body afterVisitMethod Registers closure that runs after type checking a method body beforeMethodCall Registers closure that runs before the type checker starts type checking a method call afterMethodCall Registers closure that runs once the type checker has finished type checking a method call methodNotFound Registers closure that runs when it fails to find an appropriate method for a method call ambiguousMethods Registers closure that runs when the type checker cannot choose between several candidate methods onMethodSelection Registers closure that runs when it finds a method appropriate for a method call unresolvedVariable Registers closure that runs when the type checker finds an unresolved variable unresolvedProperty Registers closure that runs when the type checker cannot find a property on the receiver unresolvedAttribute Registers closure that runs when the type checker cannot find an attribute on the receiver incompatibleAssignment Registers closure that runs when the type checker thinks that the right-hand side of an assignment is incompatible with the left-hand side incompatibleReturnType Registers closure that runs when the type checker thinks that a return value is incompatibe with the return type

  - Inherited fields
    Fields inherited from class | Fields
    --- | ---
    `class AbstractTypeCheckingExtension` | `context, debug, handled`
    `class TypeCheckingExtension` | `typeCheckingVisitor`

  - ### Constructor Summary

    Constructors
    Constructor and description
    `GroovyTypeCheckingExtensionSupport(StaticTypeCheckingVisitor typeCheckingVisitor, String scriptPath, CompilationUnit compilationUnit)` Builds a type checking extension relying on a Groovy script (type checking DSL).

  - ### Methods Summary

    Methods
    Type Params | Return Type | Name and description
    --- | --- | ---
    `` | `public void` | `afterMethodCall(MethodCall call)` * Allows the extension to perform additional tasks after the type checker actually visits a method call. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. * Parameters: `call` - a method call, either a MethodCallExpression, StaticMethodCallExpression, or ConstructorCallExpression
    `` | `public void` | `afterVisitClass(ClassNode node)` * Allows the extension to perform additional tasks after the type checker actually visited a class node. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. * Parameters: `node` - a class node
    `` | `public void` | `afterVisitMethod(MethodNode node)` * Allows the extension to perform additional tasks after the type checker actually visited a method node. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. * Parameters: `node` - a method node
    `` | `public boolean` | `beforeMethodCall(MethodCall call)` * Allows the extension to perform additional tasks before the type checker actually visits a method call. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. * * Parameters: `call` - a method call, either a MethodCallExpression, StaticMethodCallExpression, or ConstructorCallExpression * Returns: false if the type checker should visit the node, or true if this extension replaces what the * type checker would do with the method call.
    `` | `public boolean` | `beforeVisitClass(ClassNode node)` * Allows the extension to perform additional tasks before the type checker actually visits a class node. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. * Parameters: `node` - a class node * Returns: false if the type checker should visit the node, or true if this extension replaces what the * type checker would do with the class.
    `` | `public boolean` | `beforeVisitMethod(MethodNode node)` * Allows the extension to perform additional tasks before the type checker actually visits a method node. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. * Parameters: `node` - a method node * Returns: false if the type checker should visit the node, or true if this extension replaces what the * type checker would do with the method.
    `` | `public boolean` | `equals(Object that)` Compares extensions by script specification and compilation unit.
    `` | `public void` | `finish()` * Subclasses should implement this method if they need to perform additional * checks after the type checker has finished its work. This is particularly * useful for situations where you need multiple passes. Some checks in that * case may be deferred to the end, using this method.
    `` | `public Map<String, Object>` | `getOptions()` * Returns the options passed to this extension via the parameterized extension syntax, * e.g. `@TypeChecked(extensions='my.Extension(key: value)')`. * * Returns: the options map, never null * Since: 6.0.0
    `` | `public List<MethodNode>` | `handleAmbiguousMethods(List<MethodNode> nodes, Expression origin)` * This method is called by the type checker before throwing an "ambiguous method" error, giving the chance * to the extension to select the method properly. This means that when this method is called, the "nodes" * parameter contains at least two methods. If the returned list still contains at least two methods, then the * type checker will throw an ambiguous method call error. If the returned method contains 1 element, then * the type checker will not throw any error. * * It is invalid to return an empty list. * * Parameters: `nodes` - the list of ambiguous methods * `origin` - the expression which originated the method selection process * Returns: a single element list of disambiguated selection, or more elements if still ambiguous. It is not allowed * to return an empty list.
    `` | `public boolean` | `handleIncompatibleAssignment(ClassNode lhsType, ClassNode rhsType, Expression assignmentExpression)` * This method is called by the type checker when an assignment is not allowed by the type checker. * Extensions may override this method to allow such assignments where the type checker normally disallows * them. * * Parameters: `lhsType` - the type of the left hand side of the assignment, as found by the type checker * `rhsType` - the type of the right hand side of the assignment, as found by the type checker * `assignmentExpression` - the assignment expression which triggered this call * Returns: `boolean` false if the extension does not handle this assignment, true otherwise
    `` | `public boolean` | `handleIncompatibleReturnType(ReturnStatement returnStatement, ClassNode inferredReturnType)` * Allows the extension to catch incompatible return types. This event is called whenever the type * checker finds that an inferred return type is incompatible with the declared return type of * a method. * * Parameters: `returnStatement` - the statement that triggered the error * `inferredReturnType` - the inferred return type for this statement * Returns: false if the extension doesn't handle the error, true otherwise
    `` | `public List<MethodNode>` | `handleMissingMethod(ClassNode receiver, String name, ArgumentListExpression argumentList, ClassNode[] argumentTypes, MethodCall call)` * This method is called by the type checker when a method call cannot be resolved. Extensions * may override this method to handle missing methods and prevent the type checker from throwing an * error. * * * Parameters: `receiver` - the type of the receiver * `name` - the name of the called method * `argumentList` - the list of arguments of the call * `argumentTypes` - the types of the arguments of the call * `call` - the method call itself, if needed * Returns: an empty list if the extension cannot resolve the method, or a list of potential * methods if the extension finds candidates. This method must not return null.
    `` | `public boolean` | `handleUnresolvedAttribute(AttributeExpression aexp)` * This method is called by the type checker when an attribute expression cannot * be resolved (for example, when an attribute doesn't exist). It gives the extension * a chance to resolve it. * * Parameters: `aexp` - the unresolved attribute * Returns: `boolean` false if this extension doesn't resolve the attribute, true * if it resolves the attribute.
    `` | `public boolean` | `handleUnresolvedProperty(PropertyExpression pexp)` * This method is called by the type checker when a property expression cannot * be resolved (for example, when a property doesn't exist). It gives the extension * a chance to resolve it. * * Parameters: `pexp` - the unresolved property * Returns: `boolean` false if this extension doesn't resolve the property, true * if it resolves the property.
    `` | `public boolean` | `handleUnresolvedVariableExpression(VariableExpression vexp)` * This method is called by the type checker when a variable expression cannot * be resolved. It gives the extension a chance to resolve it for the type * checker. * * Parameters: `vexp` - the unresolved variable extension * Returns: `boolean` false if the extension doesn't handle it, * true if the extension handles this variable.
    `` | `public int` | `hashCode()` Returns a hash code based on the script specification and compilation unit.
    `` | `public void` | `onMethodSelection(Expression expression, MethodNode target)` * Allows the extension to listen to method selection events. Given an expression, which may be a method * call expression, a static method call expression, a pre/postfix expression, ..., if a corresponding * method is found, this method is called. * Parameters: `expression` - the expression for which a corresponding method has been found * `target` - the method which has been chosen by the type checker
    `` | `public void` | `setDebug(boolean debug)` Enables or disables debug logging for the backing extension.
    `` | `public void` | `setup()` * Subclasses should implement this method whenever they need to perform * special checks before the type checker starts working.

  - ### Inherited Methods Summary

    Inherited Methods
    Methods inherited from class | Name
    --- | ---
    `class AbstractTypeCheckingExtension` | `argTypeMatches, argTypeMatches, argTypesMatches, argTypesMatches, delegatesTo, delegatesTo, delegatesTo, firstArgTypesMatches, firstArgTypesMatches, getArguments, getCurrentScope, getEnclosingBinaryExpression, getEnclosingBinaryExpressionStack, getEnclosingClassNode, getEnclosingClassNodes, getEnclosingClosure, getEnclosingClosureStack, getEnclosingMethod, getEnclosingMethodCall, getEnclosingMethodCalls, getEnclosingMethods, getGeneratedMethods, isAnnotatedBy, isAnnotatedBy, isDynamic, isExtensionMethod, isGenerated, isMethodCall, log, makeDynamic, makeDynamic, makeDynamic, makeDynamic, makeDynamic, makeDynamic, newMethod, newMethod, newMethod, newScope, newScope, popEnclosingBinaryExpression, popEnclosingClassNode, popEnclosingClosure, popEnclosingMethod, popEnclosingMethodCall, popTemporaryTypeInfo, pushEnclosingBinaryExpression, pushEnclosingClassNode, pushEnclosingClosureExpression, pushEnclosingMethod, pushEnclosingMethodCall, pushTemporaryTypeInfo, safeCall, scopeExit, scopeExit, setHandled, unique, withTypeChecker`
    `class TypeCheckingExtension` | `addStaticTypeError, afterMethodCall, afterVisitClass, afterVisitMethod, beforeMethodCall, beforeVisitClass, beforeVisitMethod, buildListType, buildMapType, classNodeFor, classNodeFor, existsProperty, existsProperty, extractStaticReceiver, finish, getArgumentTypes, getOptions, getTargetMethod, getType, handleAmbiguousMethods, handleIncompatibleAssignment, handleIncompatibleReturnType, handleMissingMethod, handleUnresolvedAttribute, handleUnresolvedProperty, handleUnresolvedVariableExpression, isStaticMethodCallOnClass, lookupClassNodeFor, onMethodSelection, parameterizedType, setOptions, setup, storeType`

- - ### Constructor Detail

    - #### public GroovyTypeCheckingExtensionSupport(StaticTypeCheckingVisitor typeCheckingVisitor, String scriptPath, CompilationUnit compilationUnit)

      Builds a type checking extension relying on a Groovy script (type checking DSL). The `scriptPath` may include parameters in Groovy named-argument style, e.g. `"groovy.typecheckers.NullChecker(strict: true)"`.

      Parameters:
        `typeCheckingVisitor` - the type checking visitor
        `scriptPath` - the path to the type checking script (in classpath), optionally with parameters
        compilationUnit

  - ### Method Detail

    - #### public void afterMethodCall(MethodCall call)

      * Allows the extension to perform additional tasks after the type checker actually visits a method call. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. *

      Parameters:
        `call` - a method call, either a MethodCallExpression, StaticMethodCallExpression, or ConstructorCallExpression

    - #### public void afterVisitClass(ClassNode node)

      * Allows the extension to perform additional tasks after the type checker actually visited a class node. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. *

      Parameters:
        `node` - a class node

    - #### public void afterVisitMethod(MethodNode node)

      * Allows the extension to perform additional tasks after the type checker actually visited a method node. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. *

      Parameters:
        `node` - a method node

    - #### public boolean beforeMethodCall(MethodCall call)

      * Allows the extension to perform additional tasks before the type checker actually visits a method call. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. * *

      Parameters:
        `call` - a method call, either a MethodCallExpression, StaticMethodCallExpression, or ConstructorCallExpression *
      Returns:
        false if the type checker should visit the node, or true if this extension replaces what the * type checker would do with the method call.

    - #### public boolean beforeVisitClass(ClassNode node)

      * Allows the extension to perform additional tasks before the type checker actually visits a class node. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. *

      Parameters:
        `node` - a class node *
      Returns:
        false if the type checker should visit the node, or true if this extension replaces what the * type checker would do with the class.

    - #### public boolean beforeVisitMethod(MethodNode node)

      * Allows the extension to perform additional tasks before the type checker actually visits a method node. * Compared to a custom visitor, this method ensures that the node being visited is a node which would have * been visited by the type checker. This is in particular important for nodes which are marked with * TypeCheckingMode.SKIP. *

      Parameters:
        `node` - a method node *
      Returns:
        false if the type checker should visit the node, or true if this extension replaces what the * type checker would do with the method.

    - #### public boolean equals(Object that)

      Compares extensions by script specification and compilation unit.

    - #### public void finish()

      * Subclasses should implement this method if they need to perform additional * checks after the type checker has finished its work. This is particularly * useful for situations where you need multiple passes. Some checks in that * case may be deferred to the end, using this method.

    - #### public Map<String, Object> getOptions()

      * Returns the options passed to this extension via the parameterized extension syntax, * e.g. `@TypeChecked(extensions='my.Extension(key: value)')`. * *

      Returns:
        the options map, never null *
      Since:
        6.0.0

    - #### public List<MethodNode> handleAmbiguousMethods(List<MethodNode> nodes, Expression origin)

      * This method is called by the type checker before throwing an "ambiguous method" error, giving the chance * to the extension to select the method properly. This means that when this method is called, the "nodes" * parameter contains at least two methods. If the returned list still contains at least two methods, then the * type checker will throw an ambiguous method call error. If the returned method contains 1 element, then * the type checker will not throw any error. * * It is invalid to return an empty list. * *

      Parameters:
        `nodes` - the list of ambiguous methods *
        `origin` - the expression which originated the method selection process *
      Returns:
        a single element list of disambiguated selection, or more elements if still ambiguous. It is not allowed * to return an empty list.

    - #### public boolean handleIncompatibleAssignment(ClassNode lhsType, ClassNode rhsType, Expression assignmentExpression)

      * This method is called by the type checker when an assignment is not allowed by the type checker. * Extensions may override this method to allow such assignments where the type checker normally disallows * them. * *

      Parameters:
        `lhsType` - the type of the left hand side of the assignment, as found by the type checker *
        `rhsType` - the type of the right hand side of the assignment, as found by the type checker *
        `assignmentExpression` - the assignment expression which triggered this call *
      Returns:
        `boolean` false if the extension does not handle this assignment, true otherwise

    - #### public boolean handleIncompatibleReturnType(ReturnStatement returnStatement, ClassNode inferredReturnType)

      * Allows the extension to catch incompatible return types. This event is called whenever the type * checker finds that an inferred return type is incompatible with the declared return type of * a method. * *

      Parameters:
        `returnStatement` - the statement that triggered the error *
        `inferredReturnType` - the inferred return type for this statement *
      Returns:
        false if the extension doesn't handle the error, true otherwise

    - #### public List<MethodNode> handleMissingMethod(ClassNode receiver, String name, ArgumentListExpression argumentList, ClassNode[] argumentTypes, MethodCall call)

      * This method is called by the type checker when a method call cannot be resolved. Extensions * may override this method to handle missing methods and prevent the type checker from throwing an * error. * * *

      Parameters:
        `receiver` - the type of the receiver *
        `name` - the name of the called method *
        `argumentList` - the list of arguments of the call *
        `argumentTypes` - the types of the arguments of the call *
        `call` - the method call itself, if needed *
      Returns:
        an empty list if the extension cannot resolve the method, or a list of potential * methods if the extension finds candidates. This method must not return null.

    - #### public boolean handleUnresolvedAttribute(AttributeExpression aexp)

      * This method is called by the type checker when an attribute expression cannot * be resolved (for example, when an attribute doesn't exist). It gives the extension * a chance to resolve it. * *

      Parameters:
        `aexp` - the unresolved attribute *
      Returns:
        `boolean` false if this extension doesn't resolve the attribute, true * if it resolves the attribute.

    - #### public boolean handleUnresolvedProperty(PropertyExpression pexp)

      * This method is called by the type checker when a property expression cannot * be resolved (for example, when a property doesn't exist). It gives the extension * a chance to resolve it. * *

      Parameters:
        `pexp` - the unresolved property *
      Returns:
        `boolean` false if this extension doesn't resolve the property, true * if it resolves the property.

    - #### public boolean handleUnresolvedVariableExpression(VariableExpression vexp)

      * This method is called by the type checker when a variable expression cannot * be resolved. It gives the extension a chance to resolve it for the type * checker. * *

      Parameters:
        `vexp` - the unresolved variable extension *
      Returns:
        `boolean` false if the extension doesn't handle it, * true if the extension handles this variable.

    - #### public int hashCode()

      Returns a hash code based on the script specification and compilation unit.

    - #### public void onMethodSelection(Expression expression, MethodNode target)

      * Allows the extension to listen to method selection events. Given an expression, which may be a method * call expression, a static method call expression, a pre/postfix expression, ..., if a corresponding * method is found, this method is called. *

      Parameters:
        `expression` - the expression for which a corresponding method has been found *
        `target` - the method which has been chosen by the type checker

    - #### public void setDebug(boolean debug)

      Enables or disables debug logging for the backing extension.

    - #### public void setup()

      * Subclasses should implement this method whenever they need to perform * special checks before the type checker starts working.