use of org.codehaus.groovy.runtime.GeneratedClosure in project groovy by apache.
the class MetaClassImpl method invokeMethod.
/**
* <p>Invokes a method on the given receiver for the specified arguments. The sender is the class that invoked the method on the object.
* The MetaClass will attempt to establish the method to invoke based on the name and arguments provided.
*
* <p>The isCallToSuper and fromInsideClass help the Groovy runtime perform optimisations on the call to go directly
* to the super class if necessary
*
* @param sender The java.lang.Class instance that invoked the method
* @param object The object which the method was invoked on
* @param methodName The name of the method
* @param originalArguments The arguments to the method
* @param isCallToSuper Whether the method is a call to a super class method
* @param fromInsideClass Whether the call was invoked from the inside or the outside of the class
*
* @return The return value of the method
*
* @see MetaClass#invokeMethod(Class, Object, String, Object[], boolean, boolean)
*/
public Object invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass) {
checkInitalised();
if (object == null) {
throw new NullPointerException("Cannot invoke method: " + methodName + " on null object");
}
final Object[] arguments = originalArguments == null ? EMPTY_ARGUMENTS : originalArguments;
// final Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
//
// unwrap(arguments);
MetaMethod method = null;
if (CLOSURE_CALL_METHOD.equals(methodName) && object instanceof GeneratedClosure) {
method = getMethodWithCaching(sender, "doCall", arguments, isCallToSuper);
}
if (method == null) {
method = getMethodWithCaching(sender, methodName, arguments, isCallToSuper);
}
MetaClassHelper.unwrap(arguments);
if (method == null)
method = tryListParamMetaMethod(sender, methodName, isCallToSuper, arguments);
final boolean isClosure = object instanceof Closure;
if (isClosure) {
final Closure closure = (Closure) object;
final Object owner = closure.getOwner();
if (CLOSURE_CALL_METHOD.equals(methodName) || CLOSURE_DO_CALL_METHOD.equals(methodName)) {
final Class objectClass = object.getClass();
if (objectClass == MethodClosure.class) {
final MethodClosure mc = (MethodClosure) object;
methodName = mc.getMethod();
final Class ownerClass = owner instanceof Class ? (Class) owner : owner.getClass();
final MetaClass ownerMetaClass = registry.getMetaClass(ownerClass);
return ownerMetaClass.invokeMethod(ownerClass, owner, methodName, arguments, false, false);
} else if (objectClass == CurriedClosure.class) {
final CurriedClosure cc = (CurriedClosure) object;
// change the arguments for an uncurried call
final Object[] curriedArguments = cc.getUncurriedArguments(arguments);
final Class ownerClass = owner instanceof Class ? (Class) owner : owner.getClass();
final MetaClass ownerMetaClass = registry.getMetaClass(ownerClass);
return ownerMetaClass.invokeMethod(owner, methodName, curriedArguments);
}
if (method == null)
invokeMissingMethod(object, methodName, arguments);
}
final Object delegate = closure.getDelegate();
final boolean isClosureNotOwner = owner != closure;
final int resolveStrategy = closure.getResolveStrategy();
final Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
switch(resolveStrategy) {
case Closure.TO_SELF:
method = closure.getMetaClass().pickMethod(methodName, argClasses);
if (method != null)
return method.invoke(closure, arguments);
break;
case Closure.DELEGATE_ONLY:
if (method == null && delegate != closure && delegate != null) {
MetaClass delegateMetaClass = lookupObjectMetaClass(delegate);
method = delegateMetaClass.pickMethod(methodName, argClasses);
if (method != null)
return delegateMetaClass.invokeMethod(delegate, methodName, originalArguments);
else if (delegate != closure && (delegate instanceof GroovyObject)) {
return invokeMethodOnGroovyObject(methodName, originalArguments, delegate);
}
}
break;
case Closure.OWNER_ONLY:
if (method == null && owner != closure) {
MetaClass ownerMetaClass = lookupObjectMetaClass(owner);
return ownerMetaClass.invokeMethod(owner, methodName, originalArguments);
}
break;
case Closure.DELEGATE_FIRST:
if (method == null && delegate != closure && delegate != null) {
MetaClass delegateMetaClass = lookupObjectMetaClass(delegate);
method = delegateMetaClass.pickMethod(methodName, argClasses);
if (method != null)
return delegateMetaClass.invokeMethod(delegate, methodName, originalArguments);
}
if (method == null && owner != closure) {
MetaClass ownerMetaClass = lookupObjectMetaClass(owner);
method = ownerMetaClass.pickMethod(methodName, argClasses);
if (method != null)
return ownerMetaClass.invokeMethod(owner, methodName, originalArguments);
}
if (method == null && resolveStrategy != Closure.TO_SELF) {
// still no methods found, test if delegate or owner are GroovyObjects
// and invoke the method on them if so.
MissingMethodException last = null;
if (delegate != closure && (delegate instanceof GroovyObject)) {
try {
return invokeMethodOnGroovyObject(methodName, originalArguments, delegate);
} catch (MissingMethodException mme) {
if (last == null)
last = mme;
}
}
if (isClosureNotOwner && (owner instanceof GroovyObject)) {
try {
return invokeMethodOnGroovyObject(methodName, originalArguments, owner);
} catch (MissingMethodException mme) {
last = mme;
}
}
if (last != null)
return invokeMissingMethod(object, methodName, originalArguments, last, isCallToSuper);
}
break;
default:
if (method == null && owner != closure) {
MetaClass ownerMetaClass = lookupObjectMetaClass(owner);
method = ownerMetaClass.pickMethod(methodName, argClasses);
if (method != null)
return ownerMetaClass.invokeMethod(owner, methodName, originalArguments);
}
if (method == null && delegate != closure && delegate != null) {
MetaClass delegateMetaClass = lookupObjectMetaClass(delegate);
method = delegateMetaClass.pickMethod(methodName, argClasses);
if (method != null)
return delegateMetaClass.invokeMethod(delegate, methodName, originalArguments);
}
if (method == null && resolveStrategy != Closure.TO_SELF) {
// still no methods found, test if delegate or owner are GroovyObjects
// and invoke the method on them if so.
MissingMethodException last = null;
if (isClosureNotOwner && (owner instanceof GroovyObject)) {
try {
return invokeMethodOnGroovyObject(methodName, originalArguments, owner);
} catch (MissingMethodException mme) {
if (methodName.equals(mme.getMethod())) {
if (last == null)
last = mme;
} else {
throw mme;
}
} catch (InvokerInvocationException iie) {
if (iie.getCause() instanceof MissingMethodException) {
MissingMethodException mme = (MissingMethodException) iie.getCause();
if (methodName.equals(mme.getMethod())) {
if (last == null)
last = mme;
} else {
throw iie;
}
} else
throw iie;
}
}
if (delegate != closure && (delegate instanceof GroovyObject)) {
try {
return invokeMethodOnGroovyObject(methodName, originalArguments, delegate);
} catch (MissingMethodException mme) {
last = mme;
} catch (InvokerInvocationException iie) {
if (iie.getCause() instanceof MissingMethodException) {
last = (MissingMethodException) iie.getCause();
} else
throw iie;
}
}
if (last != null)
return invokeMissingMethod(object, methodName, originalArguments, last, isCallToSuper);
}
}
}
if (method != null) {
return method.doMethodInvoke(object, arguments);
} else {
return invokePropertyOrMissing(object, methodName, originalArguments, fromInsideClass, isCallToSuper);
}
}
use of org.codehaus.groovy.runtime.GeneratedClosure in project gradle by gradle.
the class MixInClosurePropertiesAsMethodsDynamicObject method tryInvokeMethod.
@Override
public DynamicInvokeResult tryInvokeMethod(String name, Object... arguments) {
DynamicInvokeResult result = super.tryInvokeMethod(name, arguments);
if (result.isFound()) {
return result;
}
DynamicInvokeResult propertyResult = tryGetProperty(name);
if (propertyResult.isFound()) {
Object property = propertyResult.getValue();
if (property instanceof Closure) {
Closure closure = (Closure) property;
closure.setResolveStrategy(Closure.DELEGATE_FIRST);
BeanDynamicObject dynamicObject = new BeanDynamicObject(closure);
result = dynamicObject.tryInvokeMethod("doCall", arguments);
if (!result.isFound() && !(closure instanceof GeneratedClosure)) {
return DynamicInvokeResult.found(closure.call(arguments));
}
return result;
}
}
return DynamicInvokeResult.notFound();
}
use of org.codehaus.groovy.runtime.GeneratedClosure in project groovy-core by groovy.
the class ClosureMetaMethod method createMethodList.
public static List<MetaMethod> createMethodList(final String name, final Class declaringClass, final Closure closure) {
List<MetaMethod> res = new ArrayList<MetaMethod>();
if (closure instanceof MethodClosure) {
MethodClosure methodClosure = (MethodClosure) closure;
Object owner = closure.getOwner();
Class ownerClass = (Class) (owner instanceof Class ? owner : owner.getClass());
for (CachedMethod method : ReflectionCache.getCachedClass(ownerClass).getMethods()) {
if (method.getName().equals(methodClosure.getMethod())) {
MetaMethod metaMethod = new MethodClosureMetaMethod(name, declaringClass, closure, method);
res.add(adjustParamTypesForStdMethods(metaMethod, name));
}
}
} else {
if (closure instanceof GeneratedClosure) {
for (CachedMethod method : ReflectionCache.getCachedClass(closure.getClass()).getMethods()) {
if (method.getName().equals("doCall")) {
MetaMethod metaMethod = new ClosureMetaMethod(name, declaringClass, closure, method);
res.add(adjustParamTypesForStdMethods(metaMethod, name));
}
}
} else {
MetaMethod metaMethod = new AnonymousMetaMethod(closure, name, declaringClass);
res.add(adjustParamTypesForStdMethods(metaMethod, name));
}
}
return res;
}
use of org.codehaus.groovy.runtime.GeneratedClosure in project gradle by gradle.
the class ConfigureUtil method configureTarget.
private static <T> void configureTarget(Closure configureClosure, T target, ConfigureDelegate closureDelegate) {
if (!(configureClosure instanceof GeneratedClosure)) {
new ClosureBackedAction<T>(configureClosure, Closure.DELEGATE_FIRST, false).execute(target);
return;
}
// Hackery to make closure execution faster, by short-circuiting the expensive property and method lookup on Closure
Closure withNewOwner = configureClosure.rehydrate(target, closureDelegate, configureClosure.getThisObject());
new ClosureBackedAction<T>(withNewOwner, Closure.OWNER_ONLY, false).execute(target);
}
use of org.codehaus.groovy.runtime.GeneratedClosure in project gradle by gradle.
the class ConfigureUtil method configureTarget.
private static <T> void configureTarget(Closure configureClosure, T target, ConfigureDelegate closureDelegate) {
if (!(configureClosure instanceof GeneratedClosure)) {
new ClosureBackedAction<T>(configureClosure, Closure.DELEGATE_FIRST, false).execute(target);
return;
}
// Hackery to make closure execution faster, by short-circuiting the expensive property and method lookup on Closure
Closure withNewOwner = configureClosure.rehydrate(target, closureDelegate, configureClosure.getThisObject());
new ClosureBackedAction<T>(withNewOwner, Closure.OWNER_ONLY, false).execute(target);
}
Aggregations