Search in sources :

Example 6 with ClassInfo

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

the class DefaultGroovyMethods method hasPerInstanceMetaClass.

private static MetaClass hasPerInstanceMetaClass(Object object) {
    if (object instanceof GroovyObject) {
        MetaClass mc = ((GroovyObject) object).getMetaClass();
        if (mc == GroovySystem.getMetaClassRegistry().getMetaClass(object.getClass()) || mc.getClass() == MetaClassImpl.class)
            return null;
        else
            return mc;
    } else {
        ClassInfo info = ClassInfo.getClassInfo(object.getClass());
        info.lock();
        try {
            return info.getPerInstanceMetaClass(object);
        } finally {
            info.unlock();
        }
    }
}
Also used : MixinInMetaClass(org.codehaus.groovy.reflection.MixinInMetaClass) ClassInfo(org.codehaus.groovy.reflection.ClassInfo)

Example 7 with ClassInfo

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

the class Verifier method addStaticMetaClassField.

private void addStaticMetaClassField(final ClassNode node, final String classInternalName) {
    String _staticClassInfoFieldName = "$staticClassInfo";
    while (node.getDeclaredField(_staticClassInfoFieldName) != null) _staticClassInfoFieldName = _staticClassInfoFieldName + "$";
    final String staticMetaClassFieldName = _staticClassInfoFieldName;
    FieldNode staticMetaClassField = node.addField(staticMetaClassFieldName, ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, ClassHelper.make(ClassInfo.class, false), null);
    staticMetaClassField.setSynthetic(true);
    node.addSyntheticMethod("$getStaticMetaClass", ACC_PROTECTED, ClassHelper.make(MetaClass.class), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BytecodeSequence(new BytecodeInstruction() {

        @Override
        public void visit(final MethodVisitor mv) {
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
            if (BytecodeHelper.isClassLiteralPossible(node) || BytecodeHelper.isSameCompilationUnit(classNode, node)) {
                BytecodeHelper.visitClassLiteral(mv, node);
            } else {
                mv.visitMethodInsn(INVOKESTATIC, classInternalName, "$get$$class$" + classInternalName.replace('/', '$'), "()Ljava/lang/Class;", false);
            }
            Label l1 = new Label();
            mv.visitJumpInsn(IF_ACMPEQ, l1);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/ScriptBytecodeAdapter", "initMetaClass", "(Ljava/lang/Object;)Lgroovy/lang/MetaClass;", false);
            mv.visitInsn(ARETURN);
            mv.visitLabel(l1);
            mv.visitFieldInsn(GETSTATIC, classInternalName, staticMetaClassFieldName, "Lorg/codehaus/groovy/reflection/ClassInfo;");
            mv.visitVarInsn(ASTORE, 1);
            mv.visitVarInsn(ALOAD, 1);
            Label l0 = new Label();
            mv.visitJumpInsn(IFNONNULL, l0);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
            mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/reflection/ClassInfo", "getClassInfo", "(Ljava/lang/Class;)Lorg/codehaus/groovy/reflection/ClassInfo;", false);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ASTORE, 1);
            mv.visitFieldInsn(PUTSTATIC, classInternalName, staticMetaClassFieldName, "Lorg/codehaus/groovy/reflection/ClassInfo;");
            mv.visitLabel(l0);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKEVIRTUAL, "org/codehaus/groovy/reflection/ClassInfo", "getMetaClass", "()Lgroovy/lang/MetaClass;", false);
            mv.visitInsn(ARETURN);
        }
    }));
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode) MetaClass(groovy.lang.MetaClass) Label(org.objectweb.asm.Label) ClassInfo(org.codehaus.groovy.reflection.ClassInfo) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 8 with ClassInfo

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

the class MethodRankHelper method getMethodSuggestionString.

/**
 * Returns a string detailing possible solutions to a missing method
 * if no good solutions can be found a empty string is returned.
 *
 * @param methodName the name of the method that doesn't exist
 * @param type the class on which the method is invoked
 * @param arguments the arguments passed to the method
 * @return a string with probable solutions to the exception
 */
public static String getMethodSuggestionString(String methodName, Class type, Object[] arguments) {
    ClassInfo ci = ClassInfo.getClassInfo(type);
    List<MetaMethod> methods = new ArrayList<MetaMethod>(ci.getMetaClass().getMethods());
    methods.addAll(ci.getMetaClass().getMetaMethods());
    List<MetaMethod> sugg = rankMethods(methodName, arguments, methods);
    StringBuilder sb = new StringBuilder();
    if (!sugg.isEmpty()) {
        sb.append("\nPossible solutions: ");
        for (int i = 0; i < sugg.size(); i++) {
            if (i != 0)
                sb.append(", ");
            sb.append(sugg.get(i).getName()).append("(");
            sb.append(listParameterNames(sugg.get(i).getParameterTypes()));
            sb.append(")");
        }
    }
    Class[] argumentClasses = getArgumentClasses(arguments);
    List<Pair<Class, Class>> conflictClasses = getConflictClasses(sugg, argumentClasses);
    if (!conflictClasses.isEmpty()) {
        sb.append("\nThe following classes appear as argument class and as parameter class, ");
        sb.append("but are defined by different class loader:\n");
        boolean first = true;
        for (Pair<Class, Class> pair : conflictClasses) {
            if (!first) {
                sb.append(", ");
            } else {
                first = false;
            }
            sb.append(pair.u.getName()).append(" (defined by '");
            sb.append(pair.u.getClassLoader());
            sb.append("' and '");
            sb.append(pair.v.getClassLoader());
            sb.append("')");
        }
        sb.append("\nIf one of the method suggestions matches the method you wanted to call, ");
        sb.append("\nthen check your class loader setup.");
    }
    return sb.toString();
}
Also used : MetaMethod(groovy.lang.MetaMethod) ArrayList(java.util.ArrayList) CachedClass(org.codehaus.groovy.reflection.CachedClass) ClassInfo(org.codehaus.groovy.reflection.ClassInfo)

Example 9 with ClassInfo

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

the class CallSiteArray method createPojoSite.

// for MetaClassImpl we try to pick meta method,
// otherwise or if method doesn't exist we make call via POJO meta class
private static CallSite createPojoSite(CallSite callSite, Object receiver, Object[] args) {
    final Class klazz = receiver.getClass();
    MetaClass metaClass = InvokerHelper.getMetaClass(receiver);
    if (!GroovyCategorySupport.hasCategoryInCurrentThread() && metaClass instanceof MetaClassImpl) {
        final MetaClassImpl mci = (MetaClassImpl) metaClass;
        final ClassInfo info = mci.getTheCachedClass().classInfo;
        if (info.hasPerInstanceMetaClasses()) {
            return new PerInstancePojoMetaClassSite(callSite, info);
        } else {
            return mci.createPojoCallSite(callSite, receiver, args);
        }
    }
    ClassInfo info = ClassInfo.getClassInfo(klazz);
    if (info.hasPerInstanceMetaClasses()) {
        return new PerInstancePojoMetaClassSite(callSite, info);
    } else {
        return new PojoMetaClassSite(callSite, metaClass);
    }
}
Also used : MetaClass(groovy.lang.MetaClass) MetaClass(groovy.lang.MetaClass) MetaClassImpl(groovy.lang.MetaClassImpl) ClassInfo(org.codehaus.groovy.reflection.ClassInfo)

Example 10 with ClassInfo

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

the class MetaClassRegistryImpl method setMetaClass.

/**
 * if oldMc is null, newMc will replace whatever meta class was used before.
 * if oldMc is not null, then newMc will be used only if the stored mc is
 * the same as oldMc
 */
private void setMetaClass(Class theClass, MetaClass oldMc, MetaClass newMc) {
    final ClassInfo info = ClassInfo.getClassInfo(theClass);
    MetaClass mc = null;
    info.lock();
    try {
        mc = info.getStrongMetaClass();
        info.setStrongMetaClass(newMc);
    } finally {
        info.unlock();
    }
    if ((oldMc == null && mc != newMc) || (oldMc != null && mc != newMc && mc != oldMc)) {
        fireConstantMetaClassUpdate(null, theClass, mc, newMc);
    }
}
Also used : ExpandoMetaClass(groovy.lang.ExpandoMetaClass) MetaClass(groovy.lang.MetaClass) ClassInfo(org.codehaus.groovy.reflection.ClassInfo)

Aggregations

ClassInfo (org.codehaus.groovy.reflection.ClassInfo)14 MetaClass (groovy.lang.MetaClass)7 CachedClass (org.codehaus.groovy.reflection.CachedClass)5 ArrayList (java.util.ArrayList)4 ExpandoMetaClass (groovy.lang.ExpandoMetaClass)3 MetaClassImpl (groovy.lang.MetaClassImpl)3 MetaMethod (groovy.lang.MetaMethod)2 MetaProperty (groovy.lang.MetaProperty)2 GeneratedMetaMethod (org.codehaus.groovy.reflection.GeneratedMetaMethod)2 MixinInMetaClass (org.codehaus.groovy.reflection.MixinInMetaClass)2 ClosureMetaMethod (org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod)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 Label (org.objectweb.asm.Label)2 MethodVisitor (org.objectweb.asm.MethodVisitor)2 DelegatingMetaClass (groovy.lang.DelegatingMetaClass)1 GroovyObject (groovy.lang.GroovyObject)1