Search in sources :

Example 1 with MissingMethodExceptionNoStack

use of org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack in project groovy-core by groovy.

the class MetaClassImpl method invokeMissingMethod.

private Object invokeMissingMethod(Object instance, String methodName, Object[] arguments, RuntimeException original, boolean isCallToSuper) {
    if (!isCallToSuper) {
        Class instanceKlazz = instance.getClass();
        if (theClass != instanceKlazz && theClass.isAssignableFrom(instanceKlazz))
            instanceKlazz = theClass;
        Class[] argClasses = MetaClassHelper.castArgumentsToClassArray(arguments);
        MetaMethod method = findMixinMethod(methodName, argClasses);
        if (method != null) {
            onMixinMethodFound(method);
            return method.invoke(instance, arguments);
        }
        method = findMethodInClassHierarchy(instanceKlazz, methodName, argClasses, this);
        if (method != null) {
            onSuperMethodFoundInHierarchy(method);
            return method.invoke(instance, arguments);
        }
        // still not method here, so see if there is an invokeMethod method up the hierarchy
        final Class[] invokeMethodArgs = { String.class, Object[].class };
        method = findMethodInClassHierarchy(instanceKlazz, INVOKE_METHOD_METHOD, invokeMethodArgs, this);
        if (method != null && method instanceof ClosureMetaMethod) {
            onInvokeMethodFoundInHierarchy(method);
            return method.invoke(instance, invokeMethodArgs);
        }
    }
    if (methodMissing != null) {
        try {
            return methodMissing.invoke(instance, new Object[] { methodName, arguments });
        } catch (InvokerInvocationException iie) {
            if (methodMissing instanceof ClosureMetaMethod && iie.getCause() instanceof MissingMethodException) {
                MissingMethodException mme = (MissingMethodException) iie.getCause();
                throw new MissingMethodExecutionFailed(mme.getMethod(), mme.getClass(), mme.getArguments(), mme.isStatic(), mme);
            }
            throw iie;
        } catch (MissingMethodException mme) {
            if (methodMissing instanceof ClosureMetaMethod)
                throw new MissingMethodExecutionFailed(mme.getMethod(), mme.getClass(), mme.getArguments(), mme.isStatic(), mme);
            else
                throw mme;
        }
    } else if (original != null)
        throw original;
    else
        throw new MissingMethodExceptionNoStack(methodName, theClass, arguments, false);
}
Also used : NewInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod) NewMetaMethod(org.codehaus.groovy.runtime.metaclass.NewMetaMethod) MixinInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod) NewStaticMetaMethod(org.codehaus.groovy.runtime.metaclass.NewStaticMetaMethod) GeneratedMetaMethod(org.codehaus.groovy.reflection.GeneratedMetaMethod) ClosureMetaMethod(org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod) TransformMetaMethod(org.codehaus.groovy.runtime.metaclass.TransformMetaMethod) ClosureMetaMethod(org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod) MissingMethodExceptionNoStack(org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack) InvokerInvocationException(org.codehaus.groovy.runtime.InvokerInvocationException) CachedClass(org.codehaus.groovy.reflection.CachedClass) MissingMethodExecutionFailed(org.codehaus.groovy.runtime.metaclass.MissingMethodExecutionFailed)

Example 2 with MissingMethodExceptionNoStack

use of org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack in project groovy by apache.

the class MetaClassImpl method invokeMissingMethod.

private Object invokeMissingMethod(final Object instance, final String methodName, final Object[] arguments, final RuntimeException original, final boolean isCallToSuper) {
    if (isCallToSuper) {
        MetaClass metaClass = InvokerHelper.getMetaClass(theClass.getSuperclass());
        return metaClass.invokeMissingMethod(instance, methodName, arguments);
    }
    Class<?> instanceKlazz = instance.getClass();
    if (theClass != instanceKlazz && theClass.isAssignableFrom(instanceKlazz))
        instanceKlazz = theClass;
    Class<?>[] argClasses = castArgumentsToClassArray(arguments);
    MetaMethod method = findMixinMethod(methodName, argClasses);
    if (method != null) {
        onMixinMethodFound(method);
        return method.invoke(instance, arguments);
    }
    method = findMethodInClassHierarchy(instanceKlazz, methodName, argClasses, this);
    if (method != null) {
        onSuperMethodFoundInHierarchy(method);
        return method.invoke(instance, arguments);
    }
    // still not method here, so see if there is an invokeMethod method up the hierarchy
    final Class<?>[] invokeMethodArgs = { String.class, Object[].class };
    method = findMethodInClassHierarchy(instanceKlazz, INVOKE_METHOD_METHOD, invokeMethodArgs, this);
    if (method instanceof ClosureMetaMethod) {
        onInvokeMethodFoundInHierarchy(method);
        return method.invoke(instance, invokeMethodArgs);
    }
    // last resort look in the category
    if (method == null && GroovyCategorySupport.hasCategoryInCurrentThread()) {
        method = getCategoryMethodMissing(instanceKlazz);
        if (method != null) {
            return method.invoke(instance, new Object[] { methodName, arguments });
        }
    }
    if (methodMissing != null) {
        try {
            return methodMissing.invoke(instance, new Object[] { methodName, arguments });
        } catch (InvokerInvocationException iie) {
            if (methodMissing instanceof ClosureMetaMethod && iie.getCause() instanceof MissingMethodException) {
                MissingMethodException mme = (MissingMethodException) iie.getCause();
                throw new MissingMethodExecutionFailed(mme.getMethod(), mme.getClass(), mme.getArguments(), mme.isStatic(), mme);
            }
            throw iie;
        } catch (MissingMethodException mme) {
            if (methodMissing instanceof ClosureMetaMethod) {
                throw new MissingMethodExecutionFailed(mme.getMethod(), mme.getClass(), mme.getArguments(), mme.isStatic(), mme);
            } else {
                throw mme;
            }
        }
    } else if (original != null) {
        throw original;
    } else {
        throw new MissingMethodExceptionNoStack(methodName, theClass, arguments, false);
    }
}
Also used : NewInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod) NewMetaMethod(org.codehaus.groovy.runtime.metaclass.NewMetaMethod) GeneratedMetaMethod(org.codehaus.groovy.reflection.GeneratedMetaMethod) ClosureMetaMethod(org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod) MixinInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod) NewStaticMetaMethod(org.codehaus.groovy.runtime.metaclass.NewStaticMetaMethod) TransformMetaMethod(org.codehaus.groovy.runtime.metaclass.TransformMetaMethod) ClosureMetaMethod(org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod) MissingMethodExceptionNoStack(org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack) InvokerInvocationException(org.codehaus.groovy.runtime.InvokerInvocationException) CachedClass(org.codehaus.groovy.reflection.CachedClass) MissingMethodExecutionFailed(org.codehaus.groovy.runtime.metaclass.MissingMethodExecutionFailed)

Example 3 with MissingMethodExceptionNoStack

use of org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack 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)

Aggregations

CachedClass (org.codehaus.groovy.reflection.CachedClass)3 InvokerInvocationException (org.codehaus.groovy.runtime.InvokerInvocationException)3 MissingMethodExceptionNoStack (org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack)3 GeneratedMetaMethod (org.codehaus.groovy.reflection.GeneratedMetaMethod)2 ClosureMetaMethod (org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod)2 MissingMethodExecutionFailed (org.codehaus.groovy.runtime.metaclass.MissingMethodExecutionFailed)2 MixinInstanceMetaMethod (org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod)2 NewInstanceMetaMethod (org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod)2 NewMetaMethod (org.codehaus.groovy.runtime.metaclass.NewMetaMethod)2 NewStaticMetaMethod (org.codehaus.groovy.runtime.metaclass.NewStaticMetaMethod)2 TransformMetaMethod (org.codehaus.groovy.runtime.metaclass.TransformMetaMethod)2 MethodClosure (org.codehaus.groovy.runtime.MethodClosure)1