Search in sources :

Example 6 with CachedMethod

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

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)

Example 7 with CachedMethod

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

the class DgmConverter method main.

public static void main(String[] args) throws IOException, ClassNotFoundException {
    String targetDirectory = "target/classes/";
    boolean info = (args.length == 1 && args[0].equals("--info")) || (args.length == 2 && args[0].equals("--info"));
    if (info && args.length == 2) {
        targetDirectory = args[1];
        if (!targetDirectory.endsWith("/"))
            targetDirectory += "/";
    }
    List<CachedMethod> cachedMethodsList = new ArrayList<CachedMethod>();
    for (Class aClass : DefaultGroovyMethods.DGM_LIKE_CLASSES) {
        Collections.addAll(cachedMethodsList, ReflectionCache.getCachedClass(aClass).getMethods());
    }
    final CachedMethod[] cachedMethods = cachedMethodsList.toArray(new CachedMethod[cachedMethodsList.size()]);
    List<GeneratedMetaMethod.DgmMethodRecord> records = new ArrayList<GeneratedMetaMethod.DgmMethodRecord>();
    int cur = 0;
    for (CachedMethod method : cachedMethods) {
        if (!method.isStatic() || !method.isPublic())
            continue;
        if (method.getCachedMethod().getAnnotation(Deprecated.class) != null)
            continue;
        if (method.getParameterTypes().length == 0)
            continue;
        final Class returnType = method.getReturnType();
        final String className = "org/codehaus/groovy/runtime/dgm$" + cur++;
        GeneratedMetaMethod.DgmMethodRecord record = new GeneratedMetaMethod.DgmMethodRecord();
        records.add(record);
        record.methodName = method.getName();
        record.returnType = method.getReturnType();
        record.parameters = method.getNativeParameterTypes();
        record.className = className;
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cw.visit(V1_3, ACC_PUBLIC, className, null, "org/codehaus/groovy/reflection/GeneratedMetaMethod", null);
        createConstructor(cw);
        final String methodDescriptor = BytecodeHelper.getMethodDescriptor(returnType, method.getNativeParameterTypes());
        createInvokeMethod(method, cw, returnType, methodDescriptor);
        createDoMethodInvokeMethod(method, cw, className, returnType, methodDescriptor);
        createIsValidMethodMethod(method, cw, className);
        cw.visitEnd();
        final byte[] bytes = cw.toByteArray();
        final FileOutputStream fileOutputStream = new FileOutputStream(targetDirectory + className + ".class");
        fileOutputStream.write(bytes);
        fileOutputStream.flush();
        fileOutputStream.close();
    }
    GeneratedMetaMethod.DgmMethodRecord.saveDgmInfo(records, targetDirectory + "/META-INF/dgminfo");
    if (info)
        System.out.println("Saved " + cur + " dgm records to: " + targetDirectory + "/META-INF/dgminfo");
}
Also used : ArrayList(java.util.ArrayList) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) ClassWriter(org.objectweb.asm.ClassWriter) FileOutputStream(java.io.FileOutputStream) CachedClass(org.codehaus.groovy.reflection.CachedClass) GeneratedMetaMethod(org.codehaus.groovy.reflection.GeneratedMetaMethod)

Example 8 with CachedMethod

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

the class SimpleExtensionModule method createMetaMethods.

private void createMetaMethods(final Class extensionClass, final List<MetaMethod> metaMethods, final boolean isStatic) {
    CachedClass cachedClass = ReflectionCache.getCachedClass(extensionClass);
    CachedMethod[] methods = cachedClass.getMethods();
    for (CachedMethod method : methods) {
        if (method.isStatic() && method.isPublic() && method.getParamsCount() > 0) {
            // an extension method is found
            metaMethods.add(isStatic ? new NewStaticMetaMethod(method) : new NewInstanceMetaMethod(method));
        }
    }
}
Also used : NewInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod) NewStaticMetaMethod(org.codehaus.groovy.runtime.metaclass.NewStaticMetaMethod) CachedMethod(org.codehaus.groovy.reflection.CachedMethod) CachedClass(org.codehaus.groovy.reflection.CachedClass)

Example 9 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 10 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)

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