Class Verifier

java.lang.Object
org.codehaus.groovy.classgen.Verifier
All Implemented Interfaces:
GroovyClassVisitor, org.objectweb.asm.Opcodes

public class Verifier extends Object implements GroovyClassVisitor, org.objectweb.asm.Opcodes
Verifies the AST node and adds any default AST code before bytecode generation occurs.

Checks include:

  • Methods with duplicate signatures
  • Duplicate interfaces
  • Reassigned final variables/parameters
  • Uninitialized variables
  • Bad code in object initializers or constructors
  • Mismatches in modifiers or return types between implementations and interfaces/abstract classes
  • Invalid record component names
Added code includes:
  • Methods needed to implement GroovyObject
  • Property accessor methods
  • Covariant methods
  • Additional methods/constructors as needed for default parameters
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static interface 
    Strategy invoked for each synthetic method or constructor generated for default arguments.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    Synthetic timestamp field used for backwards-compatible script metadata.
    static final String
    Alternate synthetic timestamp field retained for binary compatibility.
    static final String
    Metadata key marking methods generated to support default arguments.
    static final String
    Metadata key used to retain a property's original initializer expression.
    static final String
    Synthetic field name used to cache static metaclass initialization checks.
    static final String
    Metadata key used when swapping initializer statements during verification.

    Fields inherited from interface org.objectweb.asm.Opcodes

    AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_DEPRECATED, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_MANDATED, ACC_MODULE, ACC_NATIVE, ACC_OPEN, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_RECORD, ACC_STATIC, ACC_STATIC_PHASE, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_TRANSITIVE, ACC_VARARGS, ACC_VOLATILE, ACONST_NULL, ALOAD, ANEWARRAY, ARETURN, ARRAYLENGTH, ASM10_EXPERIMENTAL, ASM4, ASM5, ASM6, ASM7, ASM8, ASM9, ASTORE, ATHROW, BALOAD, BASTORE, BIPUSH, CALOAD, CASTORE, CHECKCAST, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DMUL, DNEG, DOUBLE, DREM, DRETURN, DSTORE, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F_APPEND, F_CHOP, F_FULL, F_NEW, F_SAME, F_SAME1, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAT, FMUL, FNEG, FREM, FRETURN, FSTORE, FSUB, GETFIELD, GETSTATIC, GOTO, H_GETFIELD, H_GETSTATIC, H_INVOKEINTERFACE, H_INVOKESPECIAL, H_INVOKESTATIC, H_INVOKEVIRTUAL, H_NEWINVOKESPECIAL, H_PUTFIELD, H_PUTSTATIC, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILOAD, IMUL, INEG, INSTANCEOF, INTEGER, INVOKEDYNAMIC, INVOKEINTERFACE, INVOKESPECIAL, INVOKESTATIC, INVOKEVIRTUAL, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISUB, IUSHR, IXOR, JSR, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDIV, LLOAD, LMUL, LNEG, LONG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSUB, LUSHR, LXOR, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, NEW, NEWARRAY, NOP, NULL, POP, POP2, PUTFIELD, PUTSTATIC, RET, RETURN, SALOAD, SASTORE, SIPUSH, SOURCE_DEPRECATED, SOURCE_MASK, SWAP, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, TABLESWITCH, TOP, UNINITIALIZED_THIS, V_PREVIEW, V1_1, V1_2, V1_3, V1_4, V1_5, V1_6, V1_7, V1_8, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V9
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    protected void
    Adds the synthetic support code required by a generated closure class.
    protected void
    addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode type)
    Adds a synthetic constructor variant for default arguments.
    protected void
    Adds bridge methods needed to support covariant overrides.
    protected void
    Adds a synthetic no-arg constructor when the class requires one.
    protected void
    Creates a new constructor for each combination of default parameter expressions.
    protected void
    Creates a new method for each combination of default parameter expressions.
    protected void
    Creates a new helper method for each combination of default parameter expressions.
    protected void
    Applies default-argument generation to a single method or constructor.
    protected void
    addFieldInitialization(List list, List staticList, FieldNode fieldNode, boolean isEnumClassNode, List initStmtsAfterEnumValuesInit, Set explicitStaticPropsInEnum)
    Routes a field initializer into the appropriate instance or static initialization block.
    protected void
    Adds the GroovyObject contract and supporting methods when needed.
    protected void
    Adds object and static initializer wiring for the supplied class.
    protected void
    Adds initializer statements to the supplied constructor context.
    protected MethodNode
    addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code)
    Helper method to add a new method to a ClassNode.
    protected void
    addMethod$$bridge(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code)
    Deprecated.
    protected void
    Registers a generated property accessor or mutator with the current class.
    protected void
    Ensures the supplied method has an explicit return statement when required.
    protected void
    Deprecated.
    static String
    Capitalizes the start of the given bean property name.
    protected Statement
    Creates the bytecode-backed statement block for a generated property getter.
    protected Statement
    Creates the bytecode-backed statement block for a generated property setter.
    Returns the class node currently being verified.
    Creates the callback used when final-variable analysis finds invalid assignments.
    Returns the method node currently being verified.
    static long
    getTimestamp(Class<?> clazz)
    Looks up the synthetic timestamp stored on a generated class.
    static Long
    Extracts a timestamp value from a synthetic timestamp field name.
    protected void
    Sets the class node to be verified.
    When constant expressions are created, the value is always wrapped to a non-primitive type.
    void
    Visit a ClassNode.
    void
    Visit a ConstructorNode.
    void
    Visit a FieldNode.
    void
    Extension point invoked when traversing a generic type; the default implementation does nothing.
    void
    Visit a MethodNode.
    void
    Visit a PropertyNode.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • SWAP_INIT

      public static final String SWAP_INIT
      Metadata key used when swapping initializer statements during verification.
      See Also:
    • STATIC_METACLASS_BOOL

      public static final String STATIC_METACLASS_BOOL
      Synthetic field name used to cache static metaclass initialization checks.
      See Also:
    • INITIAL_EXPRESSION

      public static final String INITIAL_EXPRESSION
      Metadata key used to retain a property's original initializer expression.
      See Also:
    • DEFAULT_PARAMETER_GENERATED

      public static final String DEFAULT_PARAMETER_GENERATED
      Metadata key marking methods generated to support default arguments.
      See Also:
    • __TIMESTAMP

      public static final String __TIMESTAMP
      Synthetic timestamp field used for backwards-compatible script metadata.
      See Also:
    • __TIMESTAMP__

      public static final String __TIMESTAMP__
      Alternate synthetic timestamp field retained for binary compatibility.
      See Also:
  • Constructor Details

    • Verifier

      public Verifier()
  • Method Details

    • getClassNode

      public ClassNode getClassNode()
      Returns the class node currently being verified.
      Returns:
      the current class node
    • setClassNode

      protected void setClassNode(ClassNode classNode)
      Sets the class node to be verified.
      Parameters:
      classNode - the class node to verify
    • getMethodNode

      public MethodNode getMethodNode()
      Returns the method node currently being verified.
      Returns:
      the current method node
    • visitClass

      public void visitClass(ClassNode node)
      Visit a ClassNode.
      Specified by:
      visitClass in interface GroovyClassVisitor
    • getFinalVariablesCallback

      protected FinalVariableAnalyzer.VariableNotFinalCallback getFinalVariablesCallback()
      Creates the callback used when final-variable analysis finds invalid assignments.
      Returns:
      the callback passed to FinalVariableAnalyzer
    • addDefaultConstructor

      protected void addDefaultConstructor(ClassNode node)
      Adds a synthetic no-arg constructor when the class requires one.
      Parameters:
      node - the class being verified
    • addGroovyObjectInterfaceAndMethods

      protected void addGroovyObjectInterfaceAndMethods(ClassNode node, String classInternalName)
      Adds the GroovyObject contract and supporting methods when needed.
      Parameters:
      node - the class being enhanced
      classInternalName - the internal JVM name of the class
    • addMethod

      protected MethodNode addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code)
      Helper method to add a new method to a ClassNode. Depending on the shouldBeSynthetic flag the call will either be made to ClassNode.addSyntheticMethod() or ClassNode.addMethod(). If a non-synthetic method is to be added the ACC_SYNTHETIC modifier is removed if it has been accidentally supplied.
    • addMethod$$bridge

      @Deprecated protected void addMethod$$bridge(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code)
      Deprecated.
      Adds a method while preserving the legacy addMethod$$bridge entry point.
      Parameters:
      node - the target class
      shouldBeSynthetic - whether the generated method should be marked synthetic
      name - the method name
      modifiers - the method modifiers
      returnType - the method return type
      parameters - the method parameters
      exceptions - the declared exceptions
      code - the method body
    • addTimeStamp

      @Deprecated(since="2.4.0") protected void addTimeStamp(ClassNode node)
      Deprecated.
      Adds legacy synthetic timestamp fields for scripts and generated classes.
      Parameters:
      node - the class being enhanced
    • visitConstructor

      public void visitConstructor(ConstructorNode node)
      Visit a ConstructorNode.
      Specified by:
      visitConstructor in interface GroovyClassVisitor
    • visitMethod

      public void visitMethod(MethodNode node)
      Visit a MethodNode.
      Specified by:
      visitMethod in interface GroovyClassVisitor
    • addReturnIfNeeded

      protected void addReturnIfNeeded(MethodNode node)
      Ensures the supplied method has an explicit return statement when required.
      Parameters:
      node - the method to normalize
    • visitField

      public void visitField(FieldNode node)
      Visit a FieldNode.
      Specified by:
      visitField in interface GroovyClassVisitor
    • visitProperty

      public void visitProperty(PropertyNode node)
      Visit a PropertyNode.
      Specified by:
      visitProperty in interface GroovyClassVisitor
    • addPropertyMethod

      protected void addPropertyMethod(MethodNode method)
      Registers a generated property accessor or mutator with the current class.
      Parameters:
      method - the generated property method
    • addDefaultParameterMethods

      protected void addDefaultParameterMethods(ClassNode type)
      Creates a new method for each combination of default parameter expressions.
    • addDefaultParameterConstructors

      protected void addDefaultParameterConstructors(ClassNode type)
      Creates a new constructor for each combination of default parameter expressions.
    • addConstructor

      protected void addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode type)
      Adds a synthetic constructor variant for default arguments.
      Parameters:
      newParams - the parameters of the generated constructor
      ctor - the source constructor
      code - the generated constructor body
      type - the declaring type
    • addDefaultParameters

      protected void addDefaultParameters(List<? extends MethodNode> methods, Verifier.DefaultArgsAction action)
      Creates a new helper method for each combination of default parameter expressions.
    • addDefaultParameters

      protected void addDefaultParameters(Verifier.DefaultArgsAction action, MethodNode method)
      Applies default-argument generation to a single method or constructor.
      Parameters:
      action - the generation strategy
      method - the method or constructor to expand
    • addClosureCode

      protected void addClosureCode(InnerClassNode node)
      Adds the synthetic support code required by a generated closure class.
      Parameters:
      node - the closure class node
    • addInitialization

      protected void addInitialization(ClassNode node)
      Adds object and static initializer wiring for the supplied class.
      Parameters:
      node - the class being enhanced
    • addInitialization

      protected void addInitialization(ClassNode node, ConstructorNode constructorNode)
      Adds initializer statements to the supplied constructor context.
      Parameters:
      node - the class being enhanced
      constructorNode - the constructor receiving initialization code
    • addFieldInitialization

      protected void addFieldInitialization(List list, List staticList, FieldNode fieldNode, boolean isEnumClassNode, List initStmtsAfterEnumValuesInit, Set explicitStaticPropsInEnum)
      Routes a field initializer into the appropriate instance or static initialization block.
      Parameters:
      list - the instance-initializer statements
      staticList - the static-initializer statements
      fieldNode - the field whose initializer is being processed
      isEnumClassNode - whether the declaring class is an enum
      initStmtsAfterEnumValuesInit - enum statements that must run after constant initialization
      explicitStaticPropsInEnum - explicitly declared static enum properties
    • capitalize

      public static String capitalize(String name)
      Capitalizes the start of the given bean property name.
    • createGetterBlock

      protected Statement createGetterBlock(PropertyNode propertyNode, FieldNode field)
      Creates the bytecode-backed statement block for a generated property getter.
      Parameters:
      propertyNode - the property being served
      field - the backing field
      Returns:
      the generated getter body
    • createSetterBlock

      protected Statement createSetterBlock(PropertyNode propertyNode, FieldNode field)
      Creates the bytecode-backed statement block for a generated property setter.
      Parameters:
      propertyNode - the property being updated
      field - the backing field
      Returns:
      the generated setter body
    • visitGenericType

      public void visitGenericType(GenericsType genericsType)
      Extension point invoked when traversing a generic type; the default implementation does nothing.
    • getTimestampFromFieldName

      public static Long getTimestampFromFieldName(String fieldName)
      Extracts a timestamp value from a synthetic timestamp field name.
      Parameters:
      fieldName - the field name to inspect
      Returns:
      the parsed timestamp, or null if the name is not a timestamp field
    • getTimestamp

      public static long getTimestamp(Class<?> clazz)
      Looks up the synthetic timestamp stored on a generated class.
      Parameters:
      clazz - the generated class to inspect
      Returns:
      the stored timestamp, or Long.MAX_VALUE if none is available
    • addCovariantMethods

      protected void addCovariantMethods(ClassNode classNode)
      Adds bridge methods needed to support covariant overrides.
      Parameters:
      classNode - the class being enhanced
    • transformToPrimitiveConstantIfPossible

      public static ConstantExpression transformToPrimitiveConstantIfPossible(ConstantExpression constantExpression)
      When constant expressions are created, the value is always wrapped to a non-primitive type. Some constant expressions are optimized to return primitive types, but not all primitives are handled. This method guarantees to return a similar constant expression but with a primitive type instead of a boxed type.

      Additionally, single char strings are converted to 'char' types.

      Parameters:
      constantExpression - a constant expression
      Returns:
      the same instance of constant expression if the type is already primitive, or a primitive constant if possible.