Search in sources :

Example 1 with CachedMethod

use of org.codehaus.groovy.reflection.CachedMethod in project groovy by apache.

the class MetaClassImpl method populateMethods.

private void populateMethods(LinkedList<CachedClass> superClasses, CachedClass firstGroovySuper) {
    MetaMethodIndex.Header header = metaMethodIndex.getHeader(firstGroovySuper.getTheClass());
    CachedClass c;
    Iterator<CachedClass> iter = superClasses.iterator();
    for (; iter.hasNext(); ) {
        c = iter.next();
        CachedMethod[] cachedMethods = c.getMethods();
        for (CachedMethod metaMethod : cachedMethods) {
            addToAllMethodsIfPublic(metaMethod);
            if (!metaMethod.isPrivate() || c == firstGroovySuper)
                addMetaMethodToIndex(metaMethod, header);
        }
        MetaMethod[] cachedMethods1 = getNewMetaMethods(c);
        for (final MetaMethod method : cachedMethods1) {
            if (!newGroovyMethodsSet.contains(method)) {
                newGroovyMethodsSet.add(method);
                addMetaMethodToIndex(method, header);
            }
        }
        if (c == firstGroovySuper)
            break;
    }
    MetaMethodIndex.Header last = header;
    for (; iter.hasNext(); ) {
        c = iter.next();
        header = metaMethodIndex.getHeader(c.getTheClass());
        if (last != null) {
            metaMethodIndex.copyNonPrivateMethods(last, header);
        }
        last = header;
        for (CachedMethod metaMethod : c.getMethods()) {
            addToAllMethodsIfPublic(metaMethod);
            addMetaMethodToIndex(metaMethod, header);
        }
        for (final MetaMethod method : getNewMetaMethods(c)) {
            if (method.getName().equals("<init>") && !method.getDeclaringClass().equals(theCachedClass))
                continue;
            if (!newGroovyMethodsSet.contains(method)) {
                newGroovyMethodsSet.add(method);
                addMetaMethodToIndex(method, header);
            }
        }
    }
}
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) MetaMethodIndex(org.codehaus.groovy.runtime.metaclass.MetaMethodIndex) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) CachedClass(org.codehaus.groovy.reflection.CachedClass)

Example 2 with CachedMethod

use of org.codehaus.groovy.reflection.CachedMethod in project groovy by apache.

the class MetaClassImpl method addNewStaticMethod.

/**
     *Adds a static method to this metaclass.
     *
     * @param method The method to be added
     */
public void addNewStaticMethod(Method method) {
    final CachedMethod cachedMethod = CachedMethod.find(method);
    NewStaticMetaMethod newMethod = new NewStaticMetaMethod(cachedMethod);
    final CachedClass declaringClass = newMethod.getDeclaringClass();
    addNewStaticMethodToIndex(newMethod, metaMethodIndex.getHeader(declaringClass.getTheClass()));
}
Also used : NewStaticMetaMethod(org.codehaus.groovy.runtime.metaclass.NewStaticMetaMethod) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) CachedClass(org.codehaus.groovy.reflection.CachedClass)

Example 3 with CachedMethod

use of org.codehaus.groovy.reflection.CachedMethod in project groovy by apache.

the class MetaClassImpl method applyPropertyDescriptors.

protected void applyPropertyDescriptors(PropertyDescriptor[] propertyDescriptors) {
    // MetaBeanProperty objects
    for (PropertyDescriptor pd : propertyDescriptors) {
        // which is not a valid property)
        if (pd.getPropertyType() == null)
            continue;
        // get the getter method
        Method method = pd.getReadMethod();
        MetaMethod getter;
        if (method != null) {
            CachedMethod cachedGetter = CachedMethod.find(method);
            getter = cachedGetter == null ? null : findMethod(cachedGetter);
        } else {
            getter = null;
        }
        // get the setter method
        MetaMethod setter;
        method = pd.getWriteMethod();
        if (method != null) {
            CachedMethod cachedSetter = CachedMethod.find(method);
            setter = cachedSetter == null ? null : findMethod(cachedSetter);
        } else {
            setter = null;
        }
        // now create the MetaProperty object
        MetaBeanProperty mp = new MetaBeanProperty(pd.getName(), pd.getPropertyType(), getter, setter);
        addMetaBeanProperty(mp);
    }
}
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) PropertyDescriptor(java.beans.PropertyDescriptor) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) NewInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod) Method(java.lang.reflect.Method) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) 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)

Example 4 with CachedMethod

use of org.codehaus.groovy.reflection.CachedMethod in project groovy by apache.

the class CallSiteGenerator method writeMethod.

private static MethodVisitor writeMethod(ClassWriter cw, String name, int argumentCount, final String superClass, CachedMethod cachedMethod, String receiverType, String parameterDescription, boolean useArray) {
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "call" + name, "(L" + receiverType + ";" + parameterDescription + ")Ljava/lang/Object;", null, null);
    mv.visitCode();
    final Label tryStart = new Label();
    mv.visitLabel(tryStart);
    // call for checking if method is still valid
    for (int i = 0; i < argumentCount; ++i) mv.visitVarInsn(Opcodes.ALOAD, i);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, superClass, "checkCall", "(Ljava/lang/Object;" + parameterDescription + ")Z", false);
    Label l0 = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, l0);
    // valid method branch
    Class callClass = cachedMethod.getDeclaringClass().getTheClass();
    boolean useInterface = callClass.isInterface();
    String type = BytecodeHelper.getClassInternalName(callClass.getName());
    String descriptor = BytecodeHelper.getMethodDescriptor(cachedMethod.getReturnType(), cachedMethod.getNativeParameterTypes());
    // prepare call
    int invokeMethodCode = Opcodes.INVOKEVIRTUAL;
    if (cachedMethod.isStatic()) {
        invokeMethodCode = Opcodes.INVOKESTATIC;
    } else {
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        BytecodeHelper.doCast(mv, callClass);
        if (useInterface)
            invokeMethodCode = Opcodes.INVOKEINTERFACE;
    }
    Method method = cachedMethod.setAccessible();
    Class<?>[] parameters = method.getParameterTypes();
    int size = parameters.length;
    for (int i = 0; i < size; i++) {
        if (useArray) {
            // unpack argument from Object[]
            mv.visitVarInsn(Opcodes.ALOAD, 2);
            BytecodeHelper.pushConstant(mv, i);
            mv.visitInsn(Opcodes.AALOAD);
        } else {
            mv.visitVarInsn(Opcodes.ALOAD, i + 2);
        }
        // cast argument to parameter class, inclusive unboxing
        // for methods with primitive types
        BytecodeHelper.doCast(mv, parameters[i]);
    }
    // make call
    mv.visitMethodInsn(invokeMethodCode, type, cachedMethod.getName(), descriptor, invokeMethodCode == Opcodes.INVOKEINTERFACE);
    // produce result
    BytecodeHelper.box(mv, cachedMethod.getReturnType());
    if (cachedMethod.getReturnType() == void.class) {
        mv.visitInsn(Opcodes.ACONST_NULL);
    }
    // return
    mv.visitInsn(Opcodes.ARETURN);
    // fall back after method change
    mv.visitLabel(l0);
    for (int i = 0; i < argumentCount; ++i) mv.visitVarInsn(Opcodes.ALOAD, i);
    if (!useArray) {
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/ArrayUtil", "createArray", "(" + parameterDescription + ")[Ljava/lang/Object;", false);
    }
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/callsite/CallSiteArray", "defaultCall" + name, "(Lorg/codehaus/groovy/runtime/callsite/CallSite;L" + receiverType + ";[Ljava/lang/Object;)Ljava/lang/Object;", false);
    mv.visitInsn(Opcodes.ARETURN);
    // exception unwrapping for stackless exceptions
    final Label tryEnd = new Label();
    mv.visitLabel(tryEnd);
    final Label catchStart = new Label();
    mv.visitLabel(catchStart);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/ScriptBytecodeAdapter", "unwrap", "(Lgroovy/lang/GroovyRuntimeException;)Ljava/lang/Throwable;", false);
    mv.visitInsn(Opcodes.ATHROW);
    mv.visitTryCatchBlock(tryStart, tryEnd, catchStart, GRE);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
    return mv;
}
Also used : Label(org.objectweb.asm.Label) CachedClass(org.codehaus.groovy.reflection.CachedClass) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) Method(java.lang.reflect.Method) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 5 with CachedMethod

use of org.codehaus.groovy.reflection.CachedMethod in project grails-core by grails.

the class BaseApiProvider method addApi.

@SuppressWarnings("unchecked")
public void addApi(final Object apiInstance) {
    if (apiInstance == null) {
        return;
    }
    Class<?> currentClass = apiInstance.getClass();
    while (currentClass != Object.class) {
        final Method[] declaredMethods = currentClass.getDeclaredMethods();
        for (final Method javaMethod : declaredMethods) {
            final int modifiers = javaMethod.getModifiers();
            if (!isNotExcluded(javaMethod, modifiers)) {
                continue;
            }
            if (Modifier.isStatic(modifiers)) {
                if (isConstructorCallMethod(javaMethod)) {
                    constructors.add(javaMethod);
                } else {
                    staticMethods.add(javaMethod);
                }
            } else {
                instanceMethods.add(new ReflectionMetaMethod(new CachedMethod(javaMethod)) {

                    {
                        CachedClass[] paramTypes = super.getParameterTypes();
                        if (paramTypes.length > 0) {
                            setParametersTypes((CachedClass[]) GrailsArrayUtils.subarray(paramTypes, 1, paramTypes.length));
                        }
                    }

                    @Override
                    public String getName() {
                        String methodName = super.getName();
                        if (isConstructorCallMethod(javaMethod)) {
                            return CTOR_GROOVY_METHOD;
                        }
                        return methodName;
                    }

                    @Override
                    public Object invoke(Object object, Object[] arguments) {
                        if (arguments.length == 0) {
                            return super.invoke(apiInstance, new Object[] { object });
                        }
                        return super.invoke(apiInstance, (Object[]) GrailsArrayUtils.add(checkForGStrings(arguments), 0, object));
                    }

                    private Object[] checkForGStrings(Object[] arguments) {
                        for (int i = 0; i < arguments.length; i++) {
                            if (arguments[i] instanceof GString) {
                                arguments[i] = arguments[i].toString();
                            }
                        }
                        return arguments;
                    }

                    @Override
                    public CachedClass[] getParameterTypes() {
                        final CachedClass[] paramTypes = method.getParameterTypes();
                        if (paramTypes.length > 0) {
                            return (CachedClass[]) GrailsArrayUtils.subarray(paramTypes, 1, paramTypes.length);
                        }
                        return paramTypes;
                    }
                });
            }
        }
        currentClass = currentClass.getSuperclass();
    }
}
Also used : CachedMethod(org.codehaus.groovy.reflection.CachedMethod) CachedClass(org.codehaus.groovy.reflection.CachedClass) ReflectionMetaMethod(org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod) Method(java.lang.reflect.Method) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) GString(groovy.lang.GString) GString(groovy.lang.GString) ReflectionMetaMethod(org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod)

Aggregations

CachedMethod (org.codehaus.groovy.reflection.CachedMethod)23 CachedClass (org.codehaus.groovy.reflection.CachedClass)19 NewInstanceMetaMethod (org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod)10 NewStaticMetaMethod (org.codehaus.groovy.runtime.metaclass.NewStaticMetaMethod)10 GeneratedMetaMethod (org.codehaus.groovy.reflection.GeneratedMetaMethod)8 ClosureMetaMethod (org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod)6 MixinInstanceMetaMethod (org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod)6 NewMetaMethod (org.codehaus.groovy.runtime.metaclass.NewMetaMethod)6 TransformMetaMethod (org.codehaus.groovy.runtime.metaclass.TransformMetaMethod)6 Method (java.lang.reflect.Method)5 ArrayList (java.util.ArrayList)4 MetaMethodIndex (org.codehaus.groovy.runtime.metaclass.MetaMethodIndex)4 MetaMethod (groovy.lang.MetaMethod)2 PropertyDescriptor (java.beans.PropertyDescriptor)2 FileOutputStream (java.io.FileOutputStream)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 GeneratedClosure (org.codehaus.groovy.runtime.GeneratedClosure)2 MethodClosure (org.codehaus.groovy.runtime.MethodClosure)2 ClassWriter (org.objectweb.asm.ClassWriter)2 Label (org.objectweb.asm.Label)2