use of org.codehaus.groovy.runtime.CurriedClosure 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.CurriedClosure in project groovy by apache.
the class MetaClassImpl method doInvokeMethod.
private Object doInvokeMethod(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 = getMetaMethod(sender, object, methodName, isCallToSuper, arguments);
final boolean isClosure = object instanceof Closure;
if (isClosure) {
final Closure closure = (Closure) object;
final Object owner = closure.getOwner();
if (CALL_METHOD.equals(methodName) || DO_CALL_METHOD.equals(methodName)) {
final Class objectClass = object.getClass();
if (objectClass == MethodClosure.class) {
return this.invokeMethodClosure(object, arguments);
} 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:
Tuple2<Object, MetaMethod> tuple = invokeMethod(method, delegate, closure, methodName, argClasses, originalArguments, owner);
Object result = tuple.getV1();
method = tuple.getV2();
if (InvokeMethodResult.NONE != result) {
return result;
}
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:
Tuple2<Object, MetaMethod> t = invokeMethod(method, delegate, closure, methodName, argClasses, originalArguments, owner);
Object r = t.getV1();
method = t.getV2();
if (InvokeMethodResult.NONE != r) {
return r;
}
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) {
MetaMethod transformedMetaMethod = VM_PLUGIN.transformMetaMethod(this, method);
return transformedMetaMethod.doMethodInvoke(object, arguments);
} else {
return invokePropertyOrMissing(object, methodName, originalArguments, fromInsideClass, isCallToSuper);
}
}
use of org.codehaus.groovy.runtime.CurriedClosure in project groovy-core by groovy.
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);
}
}
Aggregations