Class AbstractASTTransformation

java.lang.Object
org.codehaus.groovy.transform.AbstractASTTransformation
All Implemented Interfaces:
ASTTransformation, ErrorCollecting
Direct Known Subclasses:
ActiveObjectASTTransformation, AutoCloneASTStubber, AutoCloneASTTransformation, AutoFinalASTTransformation, AutoImplementASTStubber, AutoImplementASTTransformation, BaseScriptASTTransformation, BindableASTStubber, BuilderASTStubber, BuilderASTTransformation, DelegateASTStubber, DelegateASTTransformation, EqualsAndHashCodeASTStubber, EqualsAndHashCodeASTTransformation, ExternalizeMethodsASTStubber, ExternalizeMethodsASTTransformation, ExternalizeVerifierASTTransformation, FinalASTStubber, FinalASTTransformation, GinqASTTransformation, ImmutableASTTransformation, IndexedPropertyASTStubber, IndexedPropertyASTTransformation, InheritConstructorsASTStubber, InheritConstructorsASTTransformation, LazyASTStubber, LazyASTTransformation, LogASTTransformation, MapConstructorASTStubber, MapConstructorASTTransformation, MemoizedASTTransformation, MixinASTTransformation, NamedVariantASTStubber, NamedVariantASTTransformation, NonSealedASTTransformation, NotYetImplementedASTTransformation, NullCheckASTTransformation, PackageScopeASTTransformation, ReadWriteLockASTTransformation, RecordBaseASTStubber, RecordCompletionASTTransformation, RecordTypeASTTransformation, SealedASTTransformation, SealedCompletionASTTransformation, SingletonASTStubber, SingletonASTTransformation, SortableASTStubber, SortableASTTransformation, SourceURIASTTransformation, SynchronizedASTTransformation, TailRecursiveASTTransformation, ToStringASTStubber, ToStringASTTransformation, TraitASTTransformation, TupleConstructorASTStubber, TupleConstructorASTTransformation, VetoableASTStubber

public abstract class AbstractASTTransformation extends Object implements ASTTransformation, ErrorCollecting
Abstract base class for AST transformations.

Provides utility methods for extracting annotation members, validating properties/fields, and filtering members based on include/exclude specifications.

  • Field Details

    • RETENTION_CLASSNODE

      public static final ClassNode RETENTION_CLASSNODE
      A shared ClassNode representing the Retention annotation. Used for checking retention policy of annotations during AST transformation.
    • sourceUnit

      protected SourceUnit sourceUnit
      The source unit associated with the compilation context. Provides access to error collection and source file information during AST transformation.
  • Constructor Details

    • AbstractASTTransformation

      public AbstractASTTransformation()
  • Method Details

    • copyAnnotatedNodeAnnotations

      protected List<AnnotationNode> copyAnnotatedNodeAnnotations(AnnotatedNode annotatedNode, String myTypeName)
      Copies all candidateAnnotations with retention policy RetentionPolicy.RUNTIME and RetentionPolicy.CLASS.

      Annotations with GeneratedClosure members are not supported for now.

    • copyAnnotatedNodeAnnotations

      protected List<AnnotationNode> copyAnnotatedNodeAnnotations(AnnotatedNode annotatedNode, String myTypeName, boolean includeGenerated)
      Copies all candidateAnnotations with retention policy RetentionPolicy.RUNTIME and RetentionPolicy.CLASS.

      Annotations with GeneratedClosure members are not supported for now.

    • getAnnotationName

      public String getAnnotationName()
      If the transform is associated with a single annotation, returns a name suitable for displaying in error messages.
      Returns:
      The simple name of the annotation including the "@" or null if no such name is defined
    • init

      protected void init(ASTNode[] nodes, SourceUnit sourceUnit)
      Initializes the transformation with the annotation and source unit context. This method must be called before the transformation processes any AST nodes.
      Parameters:
      nodes - An array containing exactly 2 elements: the first must be an AnnotationNode specifying the annotation driving the transformation, and the second must be an AnnotatedNode to which the annotation is applied.
      sourceUnit - The source compilation unit providing error collection and source info
      Throws:
      GroovyBugError - if nodes is null, has wrong size, or wrong element types
    • memberHasValue

      public boolean memberHasValue(AnnotationNode node, String name, Object value)
      Checks whether an annotation member has a specific value.
      Parameters:
      node - the annotation node to check
      name - the name of the annotation member
      value - the expected value to match against
      Returns:
      true if the member exists and is a ConstantExpression with the given value
    • getMemberValue

      public Object getMemberValue(AnnotationNode node, String name)
      Retrieves the value of an annotation member that is a constant expression.
      Parameters:
      node - the annotation node to query
      name - the name of the annotation member
      Returns:
      the constant value of the member, or null if the member doesn't exist or is not a ConstantExpression
    • getMemberStringValue

      public static String getMemberStringValue(AnnotationNode node, String name, String defaultValue)
      Retrieves the string value of an annotation member with a default fallback. Returns the default value if the member is undefined (see Undefined).
      Parameters:
      node - the annotation node to query
      name - the name of the annotation member
      defaultValue - the value to return if the member is missing or undefined
      Returns:
      the string value of the member, or the default value if the member is undefined or not a ConstantExpression
    • getMemberStringValue

      public static String getMemberStringValue(AnnotationNode node, String name)
      Retrieves the string value of an annotation member. This is a convenience overload that calls getMemberStringValue(AnnotationNode, String, String) with null as the default value.
      Parameters:
      node - the annotation node to query
      name - the name of the annotation member
      Returns:
      the string value of the member, or null if the member is missing or undefined
    • getMemberIntValue

      public int getMemberIntValue(AnnotationNode node, String name)
      Retrieves the integer value of an annotation member.
      Parameters:
      node - the annotation node to query
      name - the name of the annotation member
      Returns:
      the integer value if the member is a ConstantExpression holding an Integer, otherwise 0
    • getMemberClassValue

      public ClassNode getMemberClassValue(AnnotationNode node, String name)
      Retrieves the ClassNode value of an annotation member. This is a convenience overload that calls getMemberClassValue(AnnotationNode, String, ClassNode) with null as the default value.
      Parameters:
      node - the annotation node to query
      name - the name of the annotation member
      Returns:
      the ClassNode value if the member is a ClassExpression with a defined type, otherwise null
    • getMemberClassValue

      public ClassNode getMemberClassValue(AnnotationNode node, String name, ClassNode defaultValue)
      Retrieves the ClassNode value of an annotation member with a default fallback. Validates that the member is a ClassExpression and generates errors for invalid expression types (VariableExpression or ConstantExpression).
      Parameters:
      node - the annotation node to query
      name - the name of the annotation member
      defaultValue - the value to return if the member is missing or not a valid ClassExpression
      Returns:
      the ClassNode value if the member is a ClassExpression with a defined type, otherwise the default value
    • getMemberStringList

      public static List<String> getMemberStringList(AnnotationNode anno, String name)
      Retrieves a list of string values from a list-type annotation member. Handles both ListExpression members and comma/space-separated string values. Returns null if the member is the undefined marker.
      Parameters:
      anno - the annotation node to query
      name - the name of the annotation member
      Returns:
      a list of strings if the member contains string values, or null if the member is missing or undefined
    • getMemberClassList

      public List<ClassNode> getMemberClassList(AnnotationNode anno, String name)
      Retrieves a list of ClassNode values from a list-type annotation member. Handles both single ClassExpression members and ListExpression members. Generates errors for invalid expression types and returns null if the member is undefined.
      Parameters:
      anno - the annotation node to query
      name - the name of the annotation member
      Returns:
      a list of ClassNode values if the member contains class values, or null if missing or undefined
    • addError

      public void addError(String msg, ASTNode node)
      Records a transformation error message associated with an AST node. The error is collected and reported at the end of compilation. This method implements ErrorCollecting.addError(String, ASTNode).
      Specified by:
      addError in interface ErrorCollecting
      Parameters:
      msg - the error message to report
      node - the AST node associated with the error for source location tracking
    • checkNotInterface

      protected boolean checkNotInterface(ClassNode cNode, String annotationName)
      Validates that the target class node is not an interface. Generates an error if the target is an interface since transformation cannot be applied.
      Parameters:
      cNode - the class node to validate
      annotationName - the name of the annotation for error reporting
      Returns:
      true if the class is not an interface, false otherwise
    • hasAnnotation

      public boolean hasAnnotation(ClassNode node, ClassNode annotation)
      Checks whether a class node has a specific annotation.
      Parameters:
      node - the class node to check
      annotation - the annotation ClassNode to look for
      Returns:
      true if the node is annotated with the given annotation
    • tokenize

      public static List<String> tokenize(String rawExcludes)
      Tokenizes a string into a list of individual tokens using comma and space as delimiters.
      Parameters:
      rawExcludes - a comma or space-separated string, or null
      Returns:
      a list of tokens, or an empty list if the input is null
    • markAsInternal

      public static void markAsInternal(AnnotatedNode node)
      Since:
      6.0.0
      See Also:
    • deemedInternalName

      public static boolean deemedInternalName(String name)
      Determines whether a name is considered internal and should typically be excluded. A name is considered internal if it contains a dollar sign ('$'), which is commonly used for generated member names.
      Parameters:
      name - the name to check
      Returns:
      true if the name contains a dollar sign, false otherwise
    • deemedInternal

      public static boolean deemedInternal(AnnotatedNode node)
      Since:
      6.0.0
      See Also:
    • shouldSkipUndefinedAware

      public static boolean shouldSkipUndefinedAware(String name, List<String> excludes, List<String> includes)
      Determines whether a name should be skipped based on include/exclude filters and the undefined marker semantics. This method provides a convenient overload that calls shouldSkipUndefinedAware(String, List, List, boolean) with allNames set to false.
      Parameters:
      name - the name to check
      excludes - a list of names to exclude, or null
      includes - a list of names to include, or null
      Returns:
      true if the name should be skipped (in excludes, internal, or not in includes when includes is specified)
    • shouldSkipUndefinedAware

      public static boolean shouldSkipUndefinedAware(String name, List<String> excludes, List<String> includes, boolean allNames)
      Determines whether a name should be skipped based on include/exclude filters with support for the undefined marker semantics.
      Parameters:
      name - the name to check
      excludes - a list of names to exclude, or null
      includes - a list of names to include, or null
      allNames - if false, also skips names that are deemed internal (containing '$'); if true, only respects explicit include/exclude lists
      Returns:
      true if the name should be skipped
    • shouldSkipUndefinedAware

      public static boolean shouldSkipUndefinedAware(AnnotatedNode node, List<String> excludes, List<String> includes, boolean allNames)
      Variant that checks both the name and @Internal annotation.
      Since:
      6.0.0
    • shouldSkip

      public static boolean shouldSkip(String name, List<String> excludes, List<String> includes)
      Determines whether a name should be skipped based on include/exclude filters. This method provides a convenient overload that calls shouldSkip(String, List, List, boolean) with allNames set to false.
      Parameters:
      name - the name to check
      excludes - a list of names to exclude, or null
      includes - a list of names to include, or null (if non-empty and name not in it, name is skipped)
      Returns:
      true if the name should be skipped (in excludes, internal, or not in includes when includes is non-empty)
    • shouldSkip

      public static boolean shouldSkip(String name, List<String> excludes, List<String> includes, boolean allNames)
      Determines whether a name should be skipped based on include/exclude filters.
      Parameters:
      name - the name to check
      excludes - a list of names to exclude, or null
      includes - a list of names to include, or null (if non-empty and name not in it, name is skipped)
      allNames - if false, also skips names that are deemed internal (containing '$'); if true, only respects explicit include/exclude lists
      Returns:
      true if the name should be skipped
    • shouldSkip

      public static boolean shouldSkip(AnnotatedNode node, List<String> excludes, List<String> includes, boolean allNames)
      Variant that checks both the name and @Internal annotation.
      Since:
      6.0.0
    • shouldSkipOnDescriptorUndefinedAware

      public static boolean shouldSkipOnDescriptorUndefinedAware(boolean checkReturn, Map genericsSpec, MethodNode mNode, List<ClassNode> excludeTypes, List<ClassNode> includeTypes)
      Determines whether a method should be skipped based on method descriptor matching against include/exclude type lists. Allows filtering methods by their signature and return type for selective processing during transformations that handle multiple methods.
      Parameters:
      checkReturn - if true, compares full method descriptors including return type; if false, compares only parameter descriptors excluding return type
      genericsSpec - a map of generic type specifications for resolving generic method signatures
      mNode - the method node to evaluate
      excludeTypes - a list of ClassNodes specifying methods to exclude, or null
      includeTypes - a list of ClassNodes specifying methods to include, or null
      Returns:
      true if the method should be skipped (in excludeTypes or not in includeTypes when includeTypes is specified)
    • checkIncludeExcludeUndefinedAware

      protected boolean checkIncludeExcludeUndefinedAware(AnnotationNode node, List<String> excludes, List<String> includes, String typeName)
      Validates that only one of 'includes' or 'excludes' is specified, not both. Generates an error if both are provided.
      Parameters:
      node - the annotation node associated with this check for error reporting
      excludes - the excludes list, or null
      includes - the includes list, or null
      typeName - the transformation type name for error reporting
      Returns:
      false if both includes and excludes are non-null/non-empty, true otherwise
    • checkIncludeExcludeUndefinedAware

      protected void checkIncludeExcludeUndefinedAware(AnnotationNode node, List<String> excludes, List<String> includes, List<ClassNode> excludeTypes, List<ClassNode> includeTypes, String typeName)
      Validates that only one filtering list is specified among 'includes', 'excludes', 'includeTypes', and 'excludeTypes'. Generates an error if more than one filtering specification is provided.
      Parameters:
      node - the annotation node associated with this check for error reporting
      excludes - the string excludes list, or null
      includes - the string includes list, or null
      excludeTypes - the type excludes list, or null
      includeTypes - the type includes list, or null
      typeName - the transformation type name for error reporting
    • checkPropertyList

      public boolean checkPropertyList(ClassNode cNode, List<String> propertyNameList, String listName, AnnotationNode anno, String typeName, boolean includeFields)
      Validates that all property names in the given list exist in the target class. This is a convenience overload that calls checkPropertyList(ClassNode, List, String, AnnotationNode, String, boolean, boolean, boolean, boolean, boolean) with defaults: includeSuperProperties=false, allProperties=false, includeSuperFields=false, includeStatic=false.
      Parameters:
      cNode - the class node to validate properties against
      propertyNameList - the list of property names to verify, or null
      listName - the name of the list (for error reporting, e.g., "includes" or "excludes")
      anno - the annotation node for error reporting
      typeName - the transformation type name for error reporting
      includeFields - whether to also check for matching field names
      Returns:
      true if all properties exist or the list is null/empty, false if any property is not found
    • checkPropertyList

      public boolean checkPropertyList(ClassNode cNode, List<String> propertyNameList, String listName, AnnotationNode anno, String typeName, boolean includeFields, boolean includeSuperProperties, boolean allProperties)
      Validates that all property names in the given list exist in the target class. This is a convenience overload that calls checkPropertyList(ClassNode, List, String, AnnotationNode, String, boolean, boolean, boolean, boolean, boolean) with defaults: includeSuperFields=false, includeStatic=false.
      Parameters:
      cNode - the class node to validate properties against
      propertyNameList - the list of property names to verify, or null
      listName - the name of the list (for error reporting, e.g., "includes" or "excludes")
      anno - the annotation node for error reporting
      typeName - the transformation type name for error reporting
      includeFields - whether to also check for matching field names
      includeSuperProperties - whether to include inherited properties
      allProperties - whether to include all accessible properties
      Returns:
      true if all properties exist or the list is null/empty, false if any property is not found
    • checkPropertyList

      public boolean checkPropertyList(ClassNode cNode, List<String> propertyNameList, String listName, AnnotationNode anno, String typeName, boolean includeFields, boolean includeSuperProperties, boolean allProperties, boolean includeSuperFields, boolean includeStatic)
      Validates that all property names in the given list exist in the target class. Checks both properties and optionally fields in the class and its superclasses. Generates errors for any properties or fields that cannot be found.
      Parameters:
      cNode - the class node to validate properties against
      propertyNameList - the list of property names to verify, or null
      listName - the name of the list (for error reporting, e.g., "includes" or "excludes")
      anno - the annotation node for error reporting
      typeName - the transformation type name for error reporting
      includeFields - whether to also check for matching field names in the current class
      includeSuperProperties - whether to include inherited properties from superclasses
      allProperties - whether to include all accessible properties or only declared ones
      includeSuperFields - whether to also check superclass fields
      includeStatic - whether to include static properties
      Returns:
      true if all properties exist or the list is null/empty, false if any property is not found