Class ClassNode

  • All Implemented Interfaces:
    GroovydocHolder<AnnotatedNode>, NodeMetaDataHandler, org.objectweb.asm.Opcodes
    Direct Known Subclasses:
    CompileUnit.ConstructedOuterNestedClassNode, DecompiledClassNode, InnerClassNode, MixinNode, WideningCategories.LowestUpperBoundClassNode

    public class ClassNode
    extends AnnotatedNode
    implements org.objectweb.asm.Opcodes
    Represents a class in the AST.

    A ClassNode should be created using the methods in ClassHelper. This ClassNode may be used to represent a class declaration or any other type. This class uses a proxy mechanism allowing to create a class for a plain name at AST creation time. In another phase of the compiler the real ClassNode for the plain name may be found. To avoid the need of exchanging this ClassNode with an instance of the correct ClassNode the correct ClassNode is set as redirect. Most method calls are then redirected to that ClassNode.

    There are three types of ClassNodes:

    1. Primary ClassNodes:
      A primary ClassNode is one where we have a source representation which is to be compiled by Groovy and which we have an AST for. The groovy compiler will output one class for each such ClassNode that passes through AsmBytecodeGenerator... not more, not less. That means for example Closures become such ClassNodes too at some point.
    2. ClassNodes create through different sources (typically created from a java.lang.reflect.Class object):
      The compiler will not output classes from these, the methods usually do not contain bodies. These kind of ClassNodes will be used in different checks, but not checks that work on the method bodies. For example if such a ClassNode is a super class to a primary ClassNode, then the abstract method test and others will be done with data based on these. Theoretically it is also possible to mix both (1 and 2) kind of classes in a hierarchy, but this probably works only in the newest Groovy versions. Such ClassNodes normally have to isResolved() returning true without having a redirect.In the Groovy compiler the only version of this, that exists, is a ClassNode created through a Class instance
    3. Labels:
      ClassNodes created through ClassHelper.makeWithoutCaching. They are place holders, its redirect points to the real structure, which can be a label too, but following all redirects it should end with a ClassNode from one of the other two categories. If ResolveVisitor finds such a node, it tries to set the redirects. Any such label created after ResolveVisitor has done its work needs to have a redirect pointing to case 1 or 2. If not the compiler may react strange... this can be considered as a kind of dangling pointer.
    Note: the redirect mechanism is only allowed for classes that are not primary ClassNodes. Typically this is done for classes created by name only. The redirect itself can be any type of ClassNode.

    To describe generic type signature see getGenericsTypes() and setGenericsTypes(GenericsType[]). These methods are not proxied, they describe the type signature used at the point of declaration or the type signatures provided by the class. If the type signatures provided by the class are needed, then a call to redirect() will help.

    See Also:
    ClassHelper
    • Field Detail

      • EMPTY_ARRAY

        public static final ClassNode[] EMPTY_ARRAY
      • isPrimaryNode

        protected boolean isPrimaryNode
      • lazyInitLock

        protected final Object lazyInitLock
      • clazz

        protected Class clazz
    • Constructor Detail

      • ClassNode

        public ClassNode​(Class<?> c)
        Creates a non-primary ClassNode from a real class.
      • ClassNode

        public ClassNode​(String name,
                         int modifiers,
                         ClassNode superClass)
        Parameters:
        name - the fully-qualified name of the class
        modifiers - the modifiers; see Opcodes
        superClass - the base class; use "java.lang.Object" if no direct base class
      • ClassNode

        public ClassNode​(String name,
                         int modifiers,
                         ClassNode superClass,
                         ClassNode[] interfaces,
                         MixinNode[] mixins)
        Parameters:
        name - the fully-qualified name of the class
        modifiers - the modifiers; see Opcodes
        superClass - the base class; use "java.lang.Object" if no direct base class
        interfaces - the interfaces for this class
        mixins - the mixins for this class
    • Method Detail

      • redirect

        public ClassNode redirect()
        Returns the ClassNode this node is a proxy for or the node itself.
      • isRedirectNode

        public boolean isRedirectNode()
      • setRedirect

        public void setRedirect​(ClassNode node)
        Sets this instance as proxy for the given ClassNode.
        Parameters:
        node - the class to redirect to; if null the redirect is removed
      • makeArray

        public ClassNode makeArray()
        Returns a ClassNode representing an array of the type represented by this.
      • isPrimaryClassNode

        public boolean isPrimaryClassNode()
        Returns:
        true if this instance is a primary ClassNode
      • getEnclosingMethod

        public MethodNode getEnclosingMethod()
      • setEnclosingMethod

        public void setEnclosingMethod​(MethodNode enclosingMethod)
      • isSyntheticPublic

        public boolean isSyntheticPublic()
        Indicates that this class has been "promoted" to public by Groovy when in fact there was no public modifier explicitly in the source code. That is, it remembers that it has applied Groovy's "public classes by default" rule. This property is typically only of interest to AST transform writers.
        Returns:
        true if node is public but had no explicit public modifier
      • setSyntheticPublic

        public void setSyntheticPublic​(boolean syntheticPublic)
      • setSuperClass

        public void setSuperClass​(ClassNode superClass)
        Sets the superclass of this ClassNode.
      • getFields

        public List<FieldNode> getFields()
        Returns:
        the fields associated with this ClassNode
      • getInterfaces

        public ClassNode[] getInterfaces()
        Returns:
        the interfaces implemented by this ClassNode
      • setInterfaces

        public void setInterfaces​(ClassNode[] interfaces)
      • getMixins

        public MixinNode[] getMixins()
        Returns:
        the mixins associated with this ClassNode
      • setMixins

        public void setMixins​(MixinNode[] mixins)
      • getMethods

        public List<MethodNode> getMethods()
        Returns:
        the methods associated with this ClassNode
      • getAbstractMethods

        public List<MethodNode> getAbstractMethods()
        Returns:
        the abstract methods associated with this ClassNode
      • getAllDeclaredMethods

        public List<MethodNode> getAllDeclaredMethods()
      • getAllInterfaces

        public Set<ClassNode> getAllInterfaces()
      • getName

        public String getName()
      • getUnresolvedName

        public String getUnresolvedName()
      • getModifiers

        public int getModifiers()
      • setModifiers

        public void setModifiers​(int modifiers)
      • getDeclaredConstructor

        public ConstructorNode getDeclaredConstructor​(Parameter[] parameters)
        Returns:
        the constructor matching the given parameters or null
      • removeConstructor

        public void removeConstructor​(ConstructorNode node)
      • setModule

        public void setModule​(ModuleNode module)
      • addField

        public void addField​(FieldNode node)
      • addFieldFirst

        public void addFieldFirst​(FieldNode node)
      • addProperty

        public void addProperty​(PropertyNode node)
      • hasProperty

        public boolean hasProperty​(String name)
      • addMethod

        public void addMethod​(MethodNode node)
      • removeMethod

        public void removeMethod​(MethodNode node)
      • addMethod

        public MethodNode addMethod​(String name,
                                    int modifiers,
                                    ClassNode returnType,
                                    Parameter[] parameters,
                                    ClassNode[] exceptions,
                                    Statement code)
        If a method with the given name and parameters is already defined then it is returned otherwise the given method is added to this node. This method is useful for default method adding like getProperty() or invokeMethod() where there may already be a method defined in a class and so the default implementations should not be added if already present.
      • addInterface

        public void addInterface​(ClassNode type)
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class Object
      • addMixin

        public void addMixin​(MixinNode mixin)
      • getDeclaredField

        public FieldNode getDeclaredField​(String name)
        Finds a field matching the given name in this class.
        Parameters:
        name - the name of the field of interest
        Returns:
        the method matching the given name and parameters or null
      • getField

        public FieldNode getField​(String name)
        Finds a field matching the given name in this class or a parent class.
        Parameters:
        name - the name of the field of interest
        Returns:
        the method matching the given name and parameters or null
      • getOuterField

        public FieldNode getOuterField​(String name)
        Returns:
        the field on the outer class or null if this is not an inner class
      • getOuterClass

        public ClassNode getOuterClass()
      • addObjectInitializerStatements

        public void addObjectInitializerStatements​(Statement statements)
        Adds a statement to the object initializer.
        Parameters:
        statements - the statement to be added
      • getObjectInitializerStatements

        public List<Statement> getObjectInitializerStatements()
      • addStaticInitializerStatements

        public void addStaticInitializerStatements​(List<Statement> staticStatements,
                                                   boolean fieldInit)
      • positionStmtsAfterEnumInitStmts

        public void positionStmtsAfterEnumInitStmts​(List<Statement> staticFieldStatements)
      • getDeclaredMethods

        public List<MethodNode> getDeclaredMethods​(String name)
        This methods returns a list of all methods of the given name defined in the current class
        Returns:
        the method list
        See Also:
        getMethods(String)
      • getMethods

        public List<MethodNode> getMethods​(String name)
        This methods creates a list of all methods with this name of the current class and of all super classes
        Returns:
        the methods list
        See Also:
        getDeclaredMethods(String)
      • getDeclaredMethod

        public MethodNode getDeclaredMethod​(String name,
                                            Parameter[] parameters)
        Finds a method matching the given name and parameters in this class.
        Returns:
        the method matching the given name and parameters or null
      • getMethod

        public MethodNode getMethod​(String name,
                                    Parameter[] parameters)
        Finds a method matching the given name and parameters in this class or any parent class.
        Returns:
        the method matching the given name and parameters or null
      • isDerivedFrom

        public boolean isDerivedFrom​(ClassNode type)
        Parameters:
        type - the ClassNode of interest
        Returns:
        true if this node is derived from the given ClassNode
      • isDerivedFromGroovyObject

        public boolean isDerivedFromGroovyObject()
        Returns:
        true if this type implements GroovyObject
      • implementsAnyInterfaces

        public boolean implementsAnyInterfaces​(ClassNode... classNodes)
        Parameters:
        classNodes - the class nodes for the interfaces
        Returns:
        true if this type implements any of the given interfaces
      • implementsInterface

        public boolean implementsInterface​(ClassNode classNode)
        Parameters:
        classNode - the class node for the interface
        Returns:
        true if this type implements the given interface
      • declaresAnyInterfaces

        public boolean declaresAnyInterfaces​(ClassNode... classNodes)
        Parameters:
        classNodes - the class nodes for the interfaces
        Returns:
        true if this type declares that it implements any of the given interfaces or if one of its interfaces extends directly/indirectly any of the given interfaces
      • declaresInterface

        public boolean declaresInterface​(ClassNode classNode)
        Parameters:
        classNode - the class node for the interface
        Returns:
        true if this class declares that it implements the given interface or if one of its interfaces extends directly/indirectly the interface NOTE: Doesn't consider an interface to implement itself. I think this is intended to be called on ClassNodes representing classes, not interfaces.
      • getSuperClass

        public ClassNode getSuperClass()
        Returns:
        the ClassNode of the super class of this type
      • getUnresolvedSuperClass

        public ClassNode getUnresolvedSuperClass()
      • getUnresolvedSuperClass

        public ClassNode getUnresolvedSuperClass​(boolean useRedirect)
      • setUnresolvedSuperClass

        public void setUnresolvedSuperClass​(ClassNode superClass)
      • getUnresolvedInterfaces

        public ClassNode[] getUnresolvedInterfaces()
      • getUnresolvedInterfaces

        public ClassNode[] getUnresolvedInterfaces​(boolean useRedirect)
      • setCompileUnit

        protected void setCompileUnit​(CompileUnit cu)
      • parametersEqual

        protected boolean parametersEqual​(Parameter[] a,
                                          Parameter[] b)
        Returns:
        true if the two arrays are of the same size and have the same contents
      • getPackageName

        public String getPackageName()
      • getNameWithoutPackage

        public String getNameWithoutPackage()
      • getGetterMethod

        public MethodNode getGetterMethod​(String getterName,
                                          boolean searchSuperClasses)
      • getSetterMethod

        public MethodNode getSetterMethod​(String setterName,
                                          boolean voidOnly)
      • isStaticClass

        public boolean isStaticClass()
        Is this class declared in a static method (such as a closure / inner class declared in a static method)
      • setStaticClass

        public void setStaticClass​(boolean staticClass)
      • isScriptBody

        public boolean isScriptBody()
        Returns:
        true if this inner class or closure was declared inside a script body
      • setScriptBody

        public void setScriptBody​(boolean scriptBody)
      • isScript

        public boolean isScript()
      • setScript

        public void setScript​(boolean script)
      • toString

        public String toString​(boolean showRedirect)
      • hasPossibleMethod

        public boolean hasPossibleMethod​(String name,
                                         Expression arguments)
        Determines if the type has a possibly-matching instance method with the given name and arguments.
        Parameters:
        name - the name of the method of interest
        arguments - the arguments to match against
        Returns:
        true if a matching method was found
      • hasPossibleStaticMethod

        public boolean hasPossibleStaticMethod​(String name,
                                               Expression arguments)
        Checks if the given method has a possibly matching static method with the given name and arguments.
        Parameters:
        name - the name of the method of interest
        arguments - the arguments to match against
        Returns:
        true if a matching method was found
      • isInterface

        public boolean isInterface()
      • isAbstract

        public boolean isAbstract()
      • isResolved

        public boolean isResolved()
      • isArray

        public boolean isArray()
      • getComponentType

        public ClassNode getComponentType()
      • getTypeClass

        public Class getTypeClass()
        Returns the concrete class this classnode relates to. However, this method is inherently unsafe as it may return null depending on the compile phase you are using. AST transformations should never use this method directly, but rather obtain a new class node using getPlainNodeReference().
        Returns:
        the class this classnode relates to. May return null.
      • hasPackageName

        public boolean hasPackageName()
      • setAnnotated

        public void setAnnotated​(boolean annotated)
        Marks if the current class uses annotations or not.
      • isAnnotated

        public boolean isAnnotated()
      • getGenericsTypes

        public GenericsType[] getGenericsTypes()
      • setGenericsTypes

        public void setGenericsTypes​(GenericsType[] genericsTypes)
      • setGenericsPlaceHolder

        public void setGenericsPlaceHolder​(boolean placeholder)
      • isGenericsPlaceHolder

        public boolean isGenericsPlaceHolder()
      • isUsingGenerics

        public boolean isUsingGenerics()
      • setUsingGenerics

        public void setUsingGenerics​(boolean usesGenerics)
      • getPlainNodeReference

        public ClassNode getPlainNodeReference()
      • isAnnotationDefinition

        public boolean isAnnotationDefinition()
      • renameField

        public void renameField​(String oldName,
                                String newName)
      • removeField

        public void removeField​(String oldName)
      • isEnum

        public boolean isEnum()
      • getInnerClasses

        public Iterator<InnerClassNode> getInnerClasses()
        Returns:
        iterator of inner classes defined inside this one