use of org.codehaus.groovy.runtime.MethodClosure in project groovy by apache.
the class MetaClassImpl method invokeMethodClosure.
private Object invokeMethodClosure(Object object, Object[] arguments) {
MethodClosure mc = (MethodClosure) object;
Object owner = mc.getOwner();
String methodName = mc.getMethod();
boolean ownerIsClass = (owner instanceof Class);
Class ownerClass = ownerIsClass ? (Class) owner : owner.getClass();
final MetaClass ownerMetaClass = registry.getMetaClass(ownerClass);
try {
return ownerMetaClass.invokeMethod(ownerClass, owner, methodName, arguments, false, false);
} catch (MissingMethodExceptionNoStack | InvokerInvocationException e) {
if (ownerIsClass) {
if (MethodClosure.NEW.equals(methodName)) {
// CONSTRUCTOR REFERENCE
if (!ownerClass.isArray()) {
return ownerMetaClass.invokeConstructor(arguments);
} else {
if (arguments.length == 0) {
throw new GroovyRuntimeException("The arguments(specifying size) are required to create array[" + ownerClass.getCanonicalName() + "]");
}
int arrayDimension = ArrayTypeUtils.dimension(ownerClass);
if (arguments.length > arrayDimension) {
throw new GroovyRuntimeException("The length[" + arguments.length + "] of arguments should not be greater than the dimensions[" + arrayDimension + "] of array[" + ownerClass.getCanonicalName() + "]");
}
int[] sizeArray = new int[arguments.length];
for (int i = 0, n = sizeArray.length; i < n; i += 1) {
Object argument = arguments[i];
if (argument instanceof Integer) {
sizeArray[i] = (Integer) argument;
} else {
sizeArray[i] = Integer.parseInt(String.valueOf(argument));
}
}
Class arrayType = arguments.length == arrayDimension ? // Just for better performance, though we can use reduceDimension only
ArrayTypeUtils.elementType(ownerClass) : ArrayTypeUtils.elementType(ownerClass, (arrayDimension - arguments.length));
return Array.newInstance(arrayType, sizeArray);
}
} else if (ownerClass != Class.class) {
// not "new"; maybe it's a reference to a Class method
try {
return InvokerHelper.getMetaClass(owner).invokeMethod(Class.class, owner, methodName, arguments, false, false);
} catch (MissingMethodExceptionNoStack nope) {
}
}
}
// otherwise re-throw the exception
if (!(ownerIsClass && (Boolean) mc.getProperty(MethodClosure.ANY_INSTANCE_METHOD_EXISTS))) {
throw e;
}
if (arguments.length < 1 || !ownerClass.isAssignableFrom(arguments[0].getClass())) {
return invokeMissingMethod(object, methodName, arguments);
}
Object newReceiver = arguments[0];
Object[] newArguments = Arrays.copyOfRange(arguments, 1, arguments.length);
return ownerMetaClass.invokeMethod(ownerClass, newReceiver, methodName, newArguments, false, false);
}
}
use of org.codehaus.groovy.runtime.MethodClosure in project groovy by apache.
the class ScriptTest method testInvokeMethodFallsThroughToMethodClosureInBinding.
/**
* When a method is not found in the current script, checks that it's possible to call a method closure from the binding.
*
* @throws IOException
* @throws CompilationFailedException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public void testInvokeMethodFallsThroughToMethodClosureInBinding() throws IOException, CompilationFailedException, IllegalAccessException, InstantiationException {
String text = "if (method() == 3) { println 'succeeded' }";
GroovyCodeSource codeSource = new GroovyCodeSource(text, "groovy.script", "groovy.script");
GroovyClassLoader loader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader());
Class clazz = loader.parseClass(codeSource);
Script script = ((Script) clazz.newInstance());
Binding binding = new Binding();
binding.setVariable("method", new MethodClosure(new Dummy(), "method"));
script.setBinding(binding);
script.run();
}
use of org.codehaus.groovy.runtime.MethodClosure in project groovy by apache.
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;
}
Aggregations