Top Description Inners Fields Constructors Methods
org.codehaus.groovy.runtime

public Class ProxyGeneratorAdapter

extends ClassVisitor
implements Opcodes
Class Inheritance
All Implemented Interfaces
org.objectweb.asm.Opcodes
Annotations
@SuppressWarnings:rawtypes
Imports
groovy.lang.Closure, .GeneratedGroovyProxy, .GroovyClassLoader, .GroovyObject, .GroovyRuntimeException, org.codehaus.groovy.ast.ClassHelper, .ClassNode, org.codehaus.groovy.classgen.asm.BytecodeHelper, org.codehaus.groovy.classgen.asm.util.TypeUtil, org.codehaus.groovy.control.CompilationUnit, .CompilerConfiguration, .ErrorCollector, .Phases, .SourceUnit, org.codehaus.groovy.tools.GroovyClass, org.codehaus.groovy.transform.trait.Traits, org.objectweb.asm.ClassVisitor, .ClassWriter, .Label, .MethodVisitor, .Opcodes, .Type, java.lang.reflect.Constructor, .InvocationTargetException, .Method, .Modifier, java.util.ArrayList, .Arrays, .Collection, .Collections, .HashMap, .HashSet, .LinkedHashSet, .List, .Map, .Set, java.util.concurrent.atomic.AtomicLong

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

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static class
private static class

Field Summary

Modifier and TypeField and Description
private final Class<T>
private final Constructor<T>
private static final String
private static final String
private final Class<T>
private final Map<String, Boolean>
private static final Object[]
private static final Map<String, Boolean>
private final boolean
private final boolean
private static final Set<String>
private static List<Method>
private final boolean
private final Set<Class<T>>
private final ProxyGeneratorAdapter.InnerLoader
private static List<Method>
private final Set<String>
private static final AtomicLong
private final String
private final Class<T>
private final Set<Object>
Inherited from org.objectweb.asm.ClassVisitor:
apicv

Constructor Summary

AccessConstructor and Description
public
ProxyGeneratorAdapter(final Map<Object, Object>
the delegates implementations
closureMap
,
final Class<?>
corresponding to the superclass class visitor
superClass
,
final Class<T>[]
extra interfaces the proxy should implement
interfaces
,
final ClassLoader
the class loader which should be used to load the generated proxy
proxyLoader
,
final boolean
if set to true, the unimplemented abstract methods will receive an empty body instead of throwing an UnsupportedOperationException.
emptyBody
,
final Class<?>
if not null, generate a delegate field with the corresponding class
delegateClass
)

Construct a proxy generator.

Method Summary

Modifier and TypeMethod and Description
private void
addDelegateFields()

Creates delegate fields for every closure defined in the map.

private Class<T>
adjustSuperClass(final Class<T> superClass, Class<T>[] interfaces)

private void
boxPrimitiveType(final MethodVisitor mv, final int idx, final Type arg)

private static Set<ClassNode>
collectTraits(final Class<T>[] interfaces)

private static boolean
containsEquivalentMethod(final Collection<Method> publicAndProtectedMethods, final Method candidate)

private MethodVisitor
createConstructor(final int access, final String name, final String desc, final String signature, final String[] exceptions)

private static Set<String>
createDelegateMethodList(final Class<T> superClass, final Class<T> delegateClass, final Class<T>[] interfaces)

private MethodVisitor
createGetProxyTargetMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions)

private void
createGroovyObjectSupport()

When an object doesn't implement the GroovyObject interface, we generate bytecode for the GroovyObject interface methods.

private static ProxyGeneratorAdapter.InnerLoader
createInnerLoader(final ClassLoader parent, final Class<T>[] interfaces)

public GroovyObject
delegatingProxy(final Object delegate, final Map<Object, Object> map, Object... constructorArgs)

public static Closure<V>
ensureClosure(final Object o)

Ensures that the provided object is wrapped into a closure if it's not a closure.

private ProxyGeneratorAdapter.InnerLoader
findClassLoader(final Class<T> clazz, final Class<T>[] interfaces)

private static List<Method>
getInheritedMethods(final Class<T> baseClass, final List<Method> methods)

private static int
getLoadInsn(final Type type)

private static int
getReturnInsn(final Type type)

private static int
private static String
private static boolean
hasMatchingParameterTypes(final Method method, final Method candidate)

private void
private void
private static boolean
isImplemented(final Class<T> clazz, final String name, final String desc)

private static boolean
isPrimitive(final Type type)

protected MethodVisitor
makeDelegateCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags)

Generate a call to the delegate object.

protected MethodVisitor
makeDelegateToClosureCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags)

public GroovyObject
proxy(final Map<Object, Object> map, Object... constructorArgs)

private String
private static int
registerLen(Type[] args)

private static int
registerLen(final Type arg)

private static void
unwrapResult(final MethodVisitor mv, final String desc)

public void
visit(final int
the class version. The minor version is stored in the 16 most significant bits, and the major version in the 16 least significant bits.
version
,
final int
the class's access flags (see Opcodes). This parameter also indicates if the class is deprecated Opcodes#ACC_DEPRECATED or a record Opcodes#ACC_RECORD.
access
,
final String
the internal name of the class (see Type#getInternalName()).
name
,
final String
the signature of this class. May be null if the class is not a generic one, and does not extend or implement generic classes or interfaces.
signature
,
final String
the internal of name of the super class (see Type#getInternalName()). For interfaces, the super class is Object. May be null, but only for the Object class.
superName
,
final String[]
the internal names of the class's interfaces (see Type#getInternalName()). May be null.
interfaces
)

Overrides org.objectweb.asm.ClassVisitor.visit.

Visits the header of the class.
private void
visitClass(final Class<T>
an class for which to generate bytecode
clazz
)

Visit every class/interface this proxy should implement, and generate the appropriate bytecode for delegation if available.

public MethodVisitor
visitMethod(final int
the method's access flags (see Opcodes). This parameter also indicates if the method is synthetic and/or deprecated.
access
,
final String
the method's name.
name
,
final String
the method's descriptor (see Type).
desc
,
final String
the method's signature. May be null if the method parameters, return type and exceptions do not use generic types.
signature
,
final String[]
the internal names of the method's exception classes (see Type#getInternalName()). May be null.
exceptions
)

Overrides org.objectweb.asm.ClassVisitor.visitMethod.

Visits a method of the class.
Inherited from org.objectweb.asm.ClassVisitor:
getDelegatevisitAnnotationvisitAttributevisitEndvisitFieldvisitInnerClassvisitModulevisitNestHostvisitNestMembervisitOuterClassvisitPermittedSubclassvisitRecordComponentvisitSourcevisitTypeAnnotation

Field Detail

cachedClassback to summary
private final Class<T> cachedClass
cachedNoArgConstructorback to summary
private final Constructor<T> cachedNoArgConstructor
CLOSURES_MAP_FIELDback to summary
private static final String CLOSURES_MAP_FIELD
DELEGATE_OBJECT_FIELDback to summary
private static final String DELEGATE_OBJECT_FIELD
delegateClassback to summary
private final Class<T> delegateClass
delegatedClosuresback to summary
private final Map<String, Boolean> delegatedClosures
EMPTY_ARGSback to summary
private static final Object[] EMPTY_ARGS
EMPTY_DELEGATECLOSURE_MAPback to summary
private static final Map<String, Boolean> EMPTY_DELEGATECLOSURE_MAP
emptyBodyback to summary
private final boolean emptyBody
generateDelegateFieldback to summary
private final boolean generateDelegateField
GROOVYOBJECT_METHOD_NAMESback to summary
private static final Set<String> GROOVYOBJECT_METHOD_NAMES
GROOVYOBJECT_METHODSback to summary
private static List<Method> GROOVYOBJECT_METHODS
hasWildcardback to summary
private final boolean hasWildcard
implClassesback to summary
private final Set<Class<T>> implClasses
innerLoaderback to summary
private final ProxyGeneratorAdapter.InnerLoader innerLoader
OBJECT_METHODSback to summary
private static List<Method> OBJECT_METHODS
objectDelegateMethodsback to summary
private final Set<String> objectDelegateMethods
proxyCounterback to summary
private static final AtomicLong proxyCounter
proxyNameback to summary
private final String proxyName
superClassback to summary
private final Class<T> superClass
visitedMethodsback to summary
private final Set<Object> visitedMethods

Constructor Detail

ProxyGeneratorAdapterback to summary
public ProxyGeneratorAdapter(final Map<Object, Object> closureMap, final Class<?> superClass, final Class<T>[] interfaces, final ClassLoader proxyLoader, final boolean emptyBody, final 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:Map<Object, Object>

the delegates implementations

superClass:Class<?>

corresponding to the superclass class visitor

interfaces:Class<T>[]

extra interfaces the proxy should implement

proxyLoader:ClassLoader

the class loader which should be used to load the generated proxy

emptyBody:boolean

if set to true, the unimplemented abstract methods will receive an empty body instead of throwing an UnsupportedOperationException.

delegateClass:Class<?>

if not null, generate a delegate field with the corresponding class

Method Detail

addDelegateFieldsback to summary
private void addDelegateFields()

Creates delegate fields for every closure defined in the map.

adjustSuperClassback to summary
private Class<T> adjustSuperClass(final Class<T> superClass, Class<T>[] interfaces)
boxPrimitiveTypeback to summary
private void boxPrimitiveType(final MethodVisitor mv, final int idx, final Type arg)
collectTraitsback to summary
private static Set<ClassNode> collectTraits(final Class<T>[] interfaces)
containsEquivalentMethodback to summary
private static boolean containsEquivalentMethod(final Collection<Method> publicAndProtectedMethods, final Method candidate)
createConstructorback to summary
private MethodVisitor createConstructor(final int access, final String name, final String desc, final String signature, final String[] exceptions)
createDelegateMethodListback to summary
private static Set<String> createDelegateMethodList(final Class<T> superClass, final Class<T> delegateClass, final Class<T>[] interfaces)
createGetProxyTargetMethodback to summary
private MethodVisitor createGetProxyTargetMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions)
createGroovyObjectSupportback to summary
private void createGroovyObjectSupport()

When an object doesn't implement the GroovyObject interface, we generate bytecode for the GroovyObject interface methods. Otherwise, the superclass is expected to implement them.

createInnerLoaderback to summary
private static ProxyGeneratorAdapter.InnerLoader createInnerLoader(final ClassLoader parent, final Class<T>[] interfaces)
delegatingProxyback to summary
public GroovyObject delegatingProxy(final Object delegate, final Map<Object, Object> map, Object... constructorArgs)
Annotations
@SuppressWarnings:unchecked
ensureClosureback to summary
public static Closure<V> ensureClosure(final 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.

Annotations
@SuppressWarnings:unchecked
findClassLoaderback to summary
private ProxyGeneratorAdapter.InnerLoader findClassLoader(final Class<T> clazz, final Class<T>[] interfaces)
getInheritedMethodsback to summary
private static List<Method> getInheritedMethods(final Class<T> baseClass, final List<Method> methods)
getLoadInsnback to summary
private static int getLoadInsn(final Type type)
getReturnInsnback to summary
private static int getReturnInsn(final Type type)
getTypeArgsRegisterLengthback to summary
private static int getTypeArgsRegisterLength(Type[] args)
getWrappedClassDescriptorback to summary
private static String getWrappedClassDescriptor(final Type type)
hasMatchingParameterTypesback to summary
private static boolean hasMatchingParameterTypes(final Method method, final Method candidate)
initializeDelegateClosureback to summary
private void initializeDelegateClosure(final MethodVisitor mv, final Type[] args)
initializeDelegateObjectback to summary
private void initializeDelegateObject(final MethodVisitor mv, final Type[] args)
isImplementedback to summary
private static boolean isImplemented(final Class<T> clazz, final String name, final String desc)
isPrimitiveback to summary
private static boolean isPrimitive(final Type type)
makeDelegateCallback to summary
protected MethodVisitor makeDelegateCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags)

Generate a call to the delegate object.

makeDelegateToClosureCallback to summary
protected MethodVisitor makeDelegateToClosureCall(final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags)
proxyback to summary
public GroovyObject proxy(final Map<Object, Object> map, Object... constructorArgs)
Annotations
@SuppressWarnings:unchecked
proxyNameback to summary
private String proxyName()
registerLenback to summary
private static int registerLen(Type[] args)
registerLenback to summary
private static int registerLen(final Type arg)
unwrapResultback to summary
private static void unwrapResult(final MethodVisitor mv, final String desc)
visitback to summary
public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces)

Overrides org.objectweb.asm.ClassVisitor.visit.

Doc from org.objectweb.asm.ClassVisitor.visit.

Visits the header of the class.

Parameters
version:int

the class version. The minor version is stored in the 16 most significant bits, and the major version in the 16 least significant bits.

access:int

the class's access flags (see Opcodes). This parameter also indicates if the class is deprecated Opcodes#ACC_DEPRECATED or a record Opcodes#ACC_RECORD.

name:String

the internal name of the class (see Type#getInternalName()).

signature:String

the signature of this class. May be null if the class is not a generic one, and does not extend or implement generic classes or interfaces.

superName:String

the internal of name of the super class (see Type#getInternalName()). For interfaces, the super class is Object. May be null, but only for the Object class.

interfaces:String[]

the internal names of the class's interfaces (see Type#getInternalName()). May be null.

Annotations
@Override
visitClassback to summary
private void visitClass(final Class<T> clazz)

Visit every class/interface this proxy should implement, and generate the appropriate bytecode for delegation if available.

Parameters
clazz:Class<T>

an class for which to generate bytecode

visitMethodback to summary
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions)

Overrides org.objectweb.asm.ClassVisitor.visitMethod.

Doc from org.objectweb.asm.ClassVisitor.visitMethod.

Visits a method of the class. This method must return a new MethodVisitor instance (or null) each time it is called, i.e., it should not return a previously returned visitor.

Parameters
access:int

the method's access flags (see Opcodes). This parameter also indicates if the method is synthetic and/or deprecated.

name:String

the method's name.

desc:String

the method's descriptor (see Type).

signature:String

the method's signature. May be null if the method parameters, return type and exceptions do not use generic types.

exceptions:String[]

the internal names of the method's exception classes (see Type#getInternalName()). May be null.

Returns:MethodVisitor

an object to visit the byte code of the method, or null if this class visitor is not interested in visiting the code of this method.

Annotations
@Override
org.codehaus.groovy.runtime back to summary

private Class ProxyGeneratorAdapter.InnerLoader

extends GroovyClassLoader
Class Inheritance

Field Summary

Modifier and TypeField and Description
pack-priv List<ClassLoader>
Inherited from groovy.lang.GroovyClassLoader:
classCachesourceCache

Constructor Summary

AccessConstructor and Description
protected
InnerLoader(final ClassLoader parent, final Class<T>[] interfaces)

Method Summary

Modifier and TypeMethod and Description
public Class<T>
defineClass(final String name, final byte[] data)

Overrides groovy.lang.GroovyClassLoader.defineClass.

open up the super class define that takes raw bytes
public Class<T>
loadClass(final String
The binary name of the class
name
)

Overrides groovy.lang.GroovyClassLoader.loadClass.

Loads the class with the specified binary name.
Inherited from groovy.lang.GroovyClassLoader:
addClasspathaddURLclearCacheclosecreateCollectorcreateCompilationUnitdefineClassgenerateScriptNamegetClassCacheEntrygetClassPathgetLoadedClassesgetPermissionsgetResourceLoadergetTimeStamphasCompatibleConfigurationisRecompilableisShouldRecompileisSourceNewerloadClassloadClassloadClassparseClassparseClassparseClassparseClassparseClassparseClassparseClassrecompileremoveClassCacheEntrysetClassCacheEntrysetResourceLoadersetShouldRecompile

Field Detail

internalClassLoadersback to summary
pack-priv List<ClassLoader> internalClassLoaders

Constructor Detail

InnerLoaderback to summary
protected InnerLoader(final ClassLoader parent, final Class<T>[] interfaces)

Method Detail

defineClassback to summary
public Class<T> defineClass(final String name, final byte[] data)

Overrides groovy.lang.GroovyClassLoader.defineClass.

Doc from groovy.lang.GroovyClassLoader.defineClass.

open up the super class define that takes raw bytes

Annotations
@Override
loadClassback to summary
public Class<T> loadClass(final String name) throws ClassNotFoundException

Overrides groovy.lang.GroovyClassLoader.loadClass.

Doc from java.lang.ClassLoader.loadClass.

Loads the class with the specified binary name. This method searches for classes in the same manner as the loadClass(String, boolean) method. It is invoked by the Java virtual machine to resolve class references. Invoking this method is equivalent to invoking loadClass(name, false).

Parameters
name:String

The binary name of the class

Returns:Class<T>

The resulting Class object

Annotations
@Override
Exceptions
ClassNotFoundException:
If the class was not found
org.codehaus.groovy.runtime back to summary

private Class ProxyGeneratorAdapter.ReturnValueWrappingClosure<V>

extends Closure<V>
Class Inheritance

Field Summary

Modifier and TypeField and Description
private static final long
private final V
Inherited from groovy.lang.Closure:
DELEGATE_FIRSTDELEGATE_ONLYDONEIDENTITYmaximumNumberOfParametersOWNER_FIRSTOWNER_ONLYparameterTypesSKIPTO_SELF

Constructor Summary

AccessConstructor and Description
public
ReturnValueWrappingClosure(final V returnValue)

Method Summary

Modifier and TypeMethod and Description
public V
call(final Object... args)

Overrides groovy.lang.Closure.call.

Invokes the closure with given argument(s), returning any value if applicable.
Inherited from groovy.lang.Closure:
andThenandThenSelfandThenSelfasWritablecallcallclonecomposecomposeSelfcomposeSelfcurrycurrydehydrategetDelegategetDirectivegetMaximumNumberOfParametersgetOwnergetParameterTypesgetPropertygetResolveStrategygetThisObjectisCaseleftShiftleftShiftmemoizememoizeAtLeastmemoizeAtMostmemoizeBetweenncurryncurryrcurryrcurryrehydraterightShiftrunsetDelegatesetDirectivesetPropertysetResolveStrategythrowRuntimeExceptiontrampolinetrampoline

Field Detail

serialVersionUIDback to summary
private static final long serialVersionUID

Hides groovy.lang.Closure.serialVersionUID.

valueback to summary
private final V value

Constructor Detail

ReturnValueWrappingClosureback to summary
public ReturnValueWrappingClosure(final V returnValue)

Method Detail

callback to summary
public V call(final Object... args)

Overrides groovy.lang.Closure.call.

Doc from groovy.lang.Closure.call.

Invokes the closure with given argument(s), returning any value if applicable.

Returns:V

The value if applicable or null if there is no return statement in the closure.

Annotations
@Override