Search in sources :

Example 26 with MethodClosure

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);
    }
}
Also used : MissingMethodExceptionNoStack(org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack) InvokerInvocationException(org.codehaus.groovy.runtime.InvokerInvocationException) CachedClass(org.codehaus.groovy.reflection.CachedClass) MethodClosure(org.codehaus.groovy.runtime.MethodClosure)

Example 27 with MethodClosure

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();
}
Also used : MethodClosure(org.codehaus.groovy.runtime.MethodClosure)

Example 28 with MethodClosure

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;
}
Also used : MetaMethod(groovy.lang.MetaMethod) ArrayList(java.util.ArrayList) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) CachedClass(org.codehaus.groovy.reflection.CachedClass) MethodClosure(org.codehaus.groovy.runtime.MethodClosure) GeneratedClosure(org.codehaus.groovy.runtime.GeneratedClosure)

Aggregations

MethodClosure (org.codehaus.groovy.runtime.MethodClosure)28 IOException (java.io.IOException)5 CachedClass (org.codehaus.groovy.reflection.CachedClass)5 GeneratedClosure (org.codehaus.groovy.runtime.GeneratedClosure)4 Test (org.junit.Test)4 Binding (groovy.lang.Binding)3 Closure (groovy.lang.Closure)3 DelegatingMetaClass (groovy.lang.DelegatingMetaClass)3 MetaClass (groovy.lang.MetaClass)3 MissingMethodException (groovy.lang.MissingMethodException)3 MissingPropertyException (groovy.lang.MissingPropertyException)3 Script (groovy.lang.Script)3 Tuple (groovy.lang.Tuple)3 PrintWriter (java.io.PrintWriter)3 Method (java.lang.reflect.Method)3 ArrayList (java.util.ArrayList)3 CompiledScript (javax.script.CompiledScript)3 ScriptException (javax.script.ScriptException)3 CompilationFailedException (org.codehaus.groovy.control.CompilationFailedException)3 InvokerInvocationException (org.codehaus.groovy.runtime.InvokerInvocationException)3