Search in sources :

Example 1 with ClassInfo

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

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() {

        public void visit(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.replaceAll("\\/", "\\$"), "()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 : MetaClass(groovy.lang.MetaClass) Label(org.objectweb.asm.Label) ClassInfo(org.codehaus.groovy.reflection.ClassInfo) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 2 with ClassInfo

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

the class MethodRankHelper method getPropertySuggestionString.

/**
 * Returns a string detailing possible solutions to a missing field or property
 * if no good solutions can be found a empty string is returned.
 *
 * @param fieldName the missing field
 * @param type the class on which the field is sought
 * @return a string with probable solutions to the exception
 */
public static String getPropertySuggestionString(String fieldName, Class type) {
    ClassInfo ci = ClassInfo.getClassInfo(type);
    List<MetaProperty> fi = ci.getMetaClass().getProperties();
    List<RankableField> rf = new ArrayList<RankableField>(fi.size());
    StringBuilder sb = new StringBuilder();
    sb.append("\nPossible solutions: ");
    for (MetaProperty mp : fi) rf.add(new RankableField(fieldName, mp));
    Collections.sort(rf);
    int i = 0;
    for (RankableField f : rf) {
        if (i > MAX_RECOMENDATIONS)
            break;
        if (f.score > MAX_FIELD_SCORE)
            break;
        if (i > 0)
            sb.append(", ");
        sb.append(f.f.getName());
        i++;
    }
    return i > 0 ? sb.toString() : "";
}
Also used : ArrayList(java.util.ArrayList) MetaProperty(groovy.lang.MetaProperty) ClassInfo(org.codehaus.groovy.reflection.ClassInfo)

Example 3 with ClassInfo

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

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 4 with ClassInfo

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

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 5 with ClassInfo

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

the class MetaClassImpl method findMethodInClassHierarchy.

protected static MetaMethod findMethodInClassHierarchy(Class instanceKlazz, String methodName, Class[] arguments, MetaClass metaClass) {
    if (metaClass instanceof MetaClassImpl) {
        boolean check = false;
        for (ClassInfo ci : ((MetaClassImpl) metaClass).theCachedClass.getHierarchy()) {
            final MetaClass aClass = ci.getStrongMetaClass();
            if (aClass instanceof MutableMetaClass && ((MutableMetaClass) aClass).isModified()) {
                check = true;
                break;
            }
        }
        if (!check)
            return null;
    }
    MetaMethod method = null;
    Class superClass;
    if (metaClass.getTheClass().isArray() && !metaClass.getTheClass().getComponentType().isPrimitive() && metaClass.getTheClass().getComponentType() != Object.class) {
        superClass = Object[].class;
    } else {
        superClass = metaClass.getTheClass().getSuperclass();
    }
    if (superClass != null) {
        MetaClass superMetaClass = GroovySystem.getMetaClassRegistry().getMetaClass(superClass);
        method = findMethodInClassHierarchy(instanceKlazz, methodName, arguments, superMetaClass);
    } else {
        if (metaClass.getTheClass().isInterface()) {
            MetaClass superMetaClass = GroovySystem.getMetaClassRegistry().getMetaClass(Object.class);
            method = findMethodInClassHierarchy(instanceKlazz, methodName, arguments, superMetaClass);
        }
    }
    method = findSubClassMethod(instanceKlazz, methodName, arguments, metaClass, method);
    MetaMethod infMethod = searchInterfacesForMetaMethod(instanceKlazz, methodName, arguments, metaClass);
    if (infMethod != null) {
        if (method == null)
            method = infMethod;
        else
            method = mostSpecific(method, infMethod, instanceKlazz);
    }
    method = findOwnMethod(instanceKlazz, methodName, arguments, metaClass, method);
    return method;
}
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) CachedClass(org.codehaus.groovy.reflection.CachedClass) 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