Package org.codehaus.groovy.runtime
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 Foowill 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, V21, V22, 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 implementationssuperClass
- corresponding to the superclass class visitorinterfaces
- extra interfaces the proxy should implementproxyLoader
- the class loader which should be used to load the generated proxydelegateClass
- if not null, generate a delegate field with the corresponding classemptyBody
- if set to true, the unimplemented abstract methods will receive an empty body instead of throwing anUnsupportedOperationException
.
-
-
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 classorg.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 classorg.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
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.
-