Class ProxyGeneratorAdapter

java.lang.Object
org.objectweb.asm.ClassVisitor
org.codehaus.groovy.runtime.ProxyGeneratorAdapter
All Implemented Interfaces:
org.objectweb.asm.Opcodes

public class ProxyGeneratorAdapter
extends org.objectweb.asm.ClassVisitor
implements org.objectweb.asm.Opcodes
A proxy generator responsible for mapping a map of closures to a class implementing a list of interfaces. For example, the following code:
     abstract class Foo {
         abstract void bar();
         abstract void baz();
     }
     def dyn = [bar: { println 'hello' }, baz: { println 'world'}] as Foo
 
will generate a proxy class which extends class Foo and delegates method calls to the provided closures. The generated proxy implements the GroovyObject interface. Additionally, this proxy generator supports delegation to another object. In that case, if a method is defined both in the closure map and the delegate, the version from the map is preferred. This allows overriding methods from delegates with ease. Internally, the proxy generator makes use of ASM to generate bytecode, for improved performance as compared to the legacy proxy generation mechanism which made use of string templates.
Since:
2.0.0
  • Field Summary

    Fields inherited from class org.objectweb.asm.ClassVisitor

    api, cv

    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, V9
  • Constructor Summary

    Constructors
    Constructor Description
    ProxyGeneratorAdapter​(java.util.Map<java.lang.Object,​java.lang.Object> closureMap, java.lang.Class<?> superClass, java.lang.Class[] interfaces, java.lang.ClassLoader proxyLoader, boolean emptyBody, java.lang.Class<?> delegateClass)
    Construct a proxy generator.
  • Method Summary

    Modifier and Type Method Description
    GroovyObject delegatingProxy​(java.lang.Object delegate, java.util.Map<java.lang.Object,​java.lang.Object> map, java.lang.Object... constructorArgs)  
    static Closure ensureClosure​(java.lang.Object o)
    Ensures that the provided object is wrapped into a closure if it's not a closure.
    protected org.objectweb.asm.MethodVisitor makeDelegateCall​(java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.String[] exceptions, int accessFlags)
    Generate a call to the delegate object.
    protected org.objectweb.asm.MethodVisitor makeDelegateToClosureCall​(java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.String[] exceptions, int accessFlags)  
    GroovyObject proxy​(java.util.Map<java.lang.Object,​java.lang.Object> map, java.lang.Object... constructorArgs)  
    void visit​(int version, int access, java.lang.String name, java.lang.String signature, java.lang.String superName, java.lang.String[] interfaces)  
    org.objectweb.asm.MethodVisitor visitMethod​(int access, java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.String[] exceptions)  

    Methods inherited from class org.objectweb.asm.ClassVisitor

    getDelegate, visitAnnotation, visitAttribute, visitEnd, visitField, visitInnerClass, visitModule, visitNestHost, visitNestMember, visitOuterClass, visitPermittedSubclass, visitRecordComponent, visitSource, visitTypeAnnotation

    Methods inherited from class java.lang.Object

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

    • ProxyGeneratorAdapter

      public ProxyGeneratorAdapter​(java.util.Map<java.lang.Object,​java.lang.Object> closureMap, java.lang.Class<?> superClass, java.lang.Class[] interfaces, java.lang.ClassLoader proxyLoader, boolean emptyBody, java.lang.Class<?> delegateClass)
      Construct a proxy generator. This generator is used when we need to create a proxy object for a class or an interface given a map of closures.
      Parameters:
      closureMap - the delegates implementations
      superClass - corresponding to the superclass class visitor
      interfaces - extra interfaces the proxy should implement
      proxyLoader - the class loader which should be used to load the generated proxy
      delegateClass - if not null, generate a delegate field with the corresponding class
      emptyBody - if set to true, the unimplemented abstract methods will receive an empty body instead of throwing an UnsupportedOperationException.
  • Method Details

    • visit

      public void visit​(int version, int access, java.lang.String name, java.lang.String signature, java.lang.String superName, java.lang.String[] interfaces)
      Overrides:
      visit in class org.objectweb.asm.ClassVisitor
    • visitMethod

      public org.objectweb.asm.MethodVisitor visitMethod​(int access, java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.String[] exceptions)
      Overrides:
      visitMethod in class org.objectweb.asm.ClassVisitor
    • makeDelegateCall

      protected org.objectweb.asm.MethodVisitor makeDelegateCall​(java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.String[] exceptions, int accessFlags)
      Generate a call to the delegate object.
    • makeDelegateToClosureCall

      protected org.objectweb.asm.MethodVisitor makeDelegateToClosureCall​(java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.String[] exceptions, int accessFlags)
    • proxy

      public GroovyObject proxy​(java.util.Map<java.lang.Object,​java.lang.Object> map, java.lang.Object... constructorArgs)
    • delegatingProxy

      public GroovyObject delegatingProxy​(java.lang.Object delegate, java.util.Map<java.lang.Object,​java.lang.Object> map, java.lang.Object... constructorArgs)
    • ensureClosure

      public static Closure ensureClosure​(java.lang.Object o)
      Ensures that the provided object is wrapped into a closure if it's not a closure. Do not trust IDEs, this method is used in bytecode.