Search in sources :

Example 36 with CachedClass

use of org.codehaus.groovy.reflection.CachedClass 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 37 with CachedClass

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

the class MetaClassImpl method invokeMissingProperty.

/**
     * Invoke a missing property on the given object with the given arguments.
     *
     * @param instance The object the method should be invoked on.
     * @param propertyName The name of the property to invoke.
     * @param optionalValue The (optional) new value for the property
     * @param isGetter Wether the method is a getter
     *
     * @return The result of the method invocation.
     */
public Object invokeMissingProperty(Object instance, String propertyName, Object optionalValue, boolean isGetter) {
    Class theClass = instance instanceof Class ? (Class) instance : instance.getClass();
    CachedClass superClass = theCachedClass;
    while (superClass != null && superClass != ReflectionCache.OBJECT_CLASS) {
        final MetaBeanProperty property = findPropertyInClassHierarchy(propertyName, superClass);
        if (property != null) {
            onSuperPropertyFoundInHierarchy(property);
            if (!isGetter) {
                property.setProperty(instance, optionalValue);
                return null;
            } else {
                return property.getProperty(instance);
            }
        }
        superClass = superClass.getCachedSuperClass();
    }
    // got here to property not found, look for getProperty or setProperty overrides
    if (isGetter) {
        final Class[] getPropertyArgs = { String.class };
        final MetaMethod method = findMethodInClassHierarchy(instance.getClass(), GET_PROPERTY_METHOD, getPropertyArgs, this);
        if (method != null && method instanceof ClosureMetaMethod) {
            onGetPropertyFoundInHierarchy(method);
            return method.invoke(instance, new Object[] { propertyName });
        }
    } else {
        final Class[] setPropertyArgs = { String.class, Object.class };
        final MetaMethod method = findMethodInClassHierarchy(instance.getClass(), SET_PROPERTY_METHOD, setPropertyArgs, this);
        if (method != null && method instanceof ClosureMetaMethod) {
            onSetPropertyFoundInHierarchy(method);
            return method.invoke(instance, new Object[] { propertyName, optionalValue });
        }
    }
    try {
        if (!(instance instanceof Class)) {
            if (isGetter) {
                if (propertyMissingGet != null) {
                    return propertyMissingGet.invoke(instance, new Object[] { propertyName });
                }
            } else {
                if (propertyMissingSet != null) {
                    return propertyMissingSet.invoke(instance, new Object[] { propertyName, optionalValue });
                }
            }
        }
    } catch (InvokerInvocationException iie) {
        boolean shouldHandle = isGetter && propertyMissingGet != null;
        if (!shouldHandle)
            shouldHandle = !isGetter && propertyMissingSet != null;
        if (shouldHandle && iie.getCause() instanceof MissingPropertyException) {
            throw (MissingPropertyException) iie.getCause();
        }
        throw iie;
    }
    if (instance instanceof Class && theClass != Class.class) {
        final MetaProperty metaProperty = InvokerHelper.getMetaClass(Class.class).hasProperty(instance, propertyName);
        if (metaProperty != null)
            if (isGetter)
                return metaProperty.getProperty(instance);
            else {
                metaProperty.setProperty(instance, optionalValue);
                return null;
            }
    }
    throw new MissingPropertyExceptionNoStack(propertyName, theClass);
}
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) MissingPropertyExceptionNoStack(org.codehaus.groovy.runtime.metaclass.MissingPropertyExceptionNoStack) InvokerInvocationException(org.codehaus.groovy.runtime.InvokerInvocationException) CachedClass(org.codehaus.groovy.reflection.CachedClass) CachedClass(org.codehaus.groovy.reflection.CachedClass) GetMethodMetaProperty(org.codehaus.groovy.runtime.metaclass.MethodMetaProperty.GetMethodMetaProperty) GetBeanMethodMetaProperty(org.codehaus.groovy.runtime.metaclass.MethodMetaProperty.GetBeanMethodMetaProperty)

Example 38 with CachedClass

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

the class ExpandoMetaClass method findMixinMethod.

public MetaMethod findMixinMethod(String methodName, Class[] arguments) {
    for (MixinInMetaClass mixin : mixinClasses) {
        final CachedClass mixinClass = mixin.getMixinClass();
        MetaClass metaClass = mixinClass.classInfo.getMetaClassForClass();
        if (metaClass == null) {
            metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(mixinClass.getTheClass());
        }
        MetaMethod metaMethod = metaClass.pickMethod(methodName, arguments);
        if (metaMethod == null && metaClass instanceof MetaClassImpl) {
            MetaClassImpl mc = (MetaClassImpl) metaClass;
            for (CachedClass cl = mc.getTheCachedClass().getCachedSuperClass(); cl != null; cl = cl.getCachedSuperClass()) {
                metaMethod = mc.getMethodWithoutCaching(cl.getTheClass(), methodName, arguments, false);
                if (metaMethod != null)
                    break;
            }
        }
        if (metaMethod != null) {
            MetaMethod method = new MixinInstanceMetaMethod(metaMethod, mixin);
            if (method.getParameterTypes().length == 1 && !method.getParameterTypes()[0].isPrimitive) {
                MetaMethod noParam = pickMethod(methodName, EMPTY_CLASS_ARRAY);
                // if the current call itself is with empty arg class array, no need to recurse with 'new Class[0]'
                if (noParam == null && arguments.length != 0) {
                    try {
                        findMixinMethod(methodName, EMPTY_CLASS_ARRAY);
                    } catch (MethodSelectionException msex) {
                    /*
                             * Here we just additionally tried to find another no-arg mixin method of the same name and register that as well, if found.
                             * Safe to ignore a MethodSelectionException in this additional exercise. (GROOVY-4999)
                             */
                    }
                }
            }
            registerInstanceMethod(method);
            return method;
        }
    }
    return null;
}
Also used : ClosureStaticMetaMethod(org.codehaus.groovy.runtime.metaclass.ClosureStaticMetaMethod) MixinInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod) ClosureMetaMethod(org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod) MethodSelectionException(org.codehaus.groovy.runtime.metaclass.MethodSelectionException) OwnedMetaClass(org.codehaus.groovy.runtime.metaclass.OwnedMetaClass) MixedInMetaClass(org.codehaus.groovy.runtime.metaclass.MixedInMetaClass) MixinInMetaClass(org.codehaus.groovy.reflection.MixinInMetaClass) MixinInMetaClass(org.codehaus.groovy.reflection.MixinInMetaClass) CachedClass(org.codehaus.groovy.reflection.CachedClass) MixinInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod)

Example 39 with CachedClass

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

the class MetaMethod method getMopName.

public String getMopName() {
    if (mopName == null) {
        String name = getName();
        CachedClass declaringClass = getDeclaringClass();
        if (Modifier.isPrivate(getModifiers()))
            mopName = new StringBuffer().append("this$").append(declaringClass.getSuperClassDistance()).append("$").append(name).toString();
        else
            mopName = new StringBuffer().append("super$").append(declaringClass.getSuperClassDistance()).append("$").append(name).toString();
    }
    return mopName;
}
Also used : CachedClass(org.codehaus.groovy.reflection.CachedClass)

Example 40 with CachedClass

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

the class MetaClassImpl method setupProperties.

/**
     * This will build up the property map (Map of MetaProperty objects, keyed on
     * property name).
     *
     * @param propertyDescriptors
     */
@SuppressWarnings("unchecked")
private void setupProperties(PropertyDescriptor[] propertyDescriptors) {
    if (theCachedClass.isInterface) {
        LinkedList<CachedClass> superClasses = new LinkedList<CachedClass>();
        superClasses.add(ReflectionCache.OBJECT_CLASS);
        Set interfaces = theCachedClass.getInterfaces();
        LinkedList<CachedClass> superInterfaces = new LinkedList<CachedClass>(interfaces);
        // ambiguous fields (class implementing two interfaces using the same field)
        if (superInterfaces.size() > 1) {
            Collections.sort(superInterfaces, CACHED_CLASS_NAME_COMPARATOR);
        }
        SingleKeyHashMap iPropertyIndex = classPropertyIndex.getNotNull(theCachedClass);
        for (CachedClass iclass : superInterfaces) {
            SingleKeyHashMap sPropertyIndex = classPropertyIndex.getNotNull(iclass);
            copyNonPrivateFields(sPropertyIndex, iPropertyIndex);
            addFields(iclass, iPropertyIndex);
        }
        addFields(theCachedClass, iPropertyIndex);
        applyPropertyDescriptors(propertyDescriptors);
        applyStrayPropertyMethods(superClasses, classPropertyIndex, true);
        makeStaticPropertyIndex();
    } else {
        LinkedList<CachedClass> superClasses = getSuperClasses();
        LinkedList<CachedClass> interfaces = new LinkedList<CachedClass>(theCachedClass.getInterfaces());
        // ambiguous fields (class implementing two interfaces using the same field)
        if (interfaces.size() > 1) {
            Collections.sort(interfaces, CACHED_CLASS_NAME_COMPARATOR);
        }
        // if this an Array, then add the special read-only "length" property
        if (theCachedClass.isArray) {
            SingleKeyHashMap map = new SingleKeyHashMap();
            map.put("length", arrayLengthProperty);
            classPropertyIndex.put(theCachedClass, map);
        }
        inheritStaticInterfaceFields(superClasses, new LinkedHashSet(interfaces));
        inheritFields(superClasses);
        applyPropertyDescriptors(propertyDescriptors);
        applyStrayPropertyMethods(superClasses, classPropertyIndex, true);
        applyStrayPropertyMethods(superClasses, classPropertyIndexForSuper, false);
        copyClassPropertyIndexForSuper(classPropertyIndexForSuper);
        makeStaticPropertyIndex();
    }
}
Also used : SingleKeyHashMap(org.codehaus.groovy.util.SingleKeyHashMap) CachedClass(org.codehaus.groovy.reflection.CachedClass)

Aggregations

CachedClass (org.codehaus.groovy.reflection.CachedClass)68 NewInstanceMetaMethod (org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod)17 NewStaticMetaMethod (org.codehaus.groovy.runtime.metaclass.NewStaticMetaMethod)17 GeneratedMetaMethod (org.codehaus.groovy.reflection.GeneratedMetaMethod)15 ClosureMetaMethod (org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod)15 MixinInstanceMetaMethod (org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod)15 CachedMethod (org.codehaus.groovy.reflection.CachedMethod)13 NewMetaMethod (org.codehaus.groovy.runtime.metaclass.NewMetaMethod)13 TransformMetaMethod (org.codehaus.groovy.runtime.metaclass.TransformMetaMethod)13 SingleKeyHashMap (org.codehaus.groovy.util.SingleKeyHashMap)10 MetaMethodIndex (org.codehaus.groovy.runtime.metaclass.MetaMethodIndex)8 ClassWriter (org.objectweb.asm.ClassWriter)6 ParameterTypes (org.codehaus.groovy.reflection.ParameterTypes)4 GetBeanMethodMetaProperty (org.codehaus.groovy.runtime.metaclass.MethodMetaProperty.GetBeanMethodMetaProperty)4 GetMethodMetaProperty (org.codehaus.groovy.runtime.metaclass.MethodMetaProperty.GetMethodMetaProperty)4 MetaMethod (groovy.lang.MetaMethod)3 FastArray (org.codehaus.groovy.util.FastArray)3 MixinInMetaClass (org.codehaus.groovy.reflection.MixinInMetaClass)2 ConvertedClosure (org.codehaus.groovy.runtime.ConvertedClosure)2 CurriedClosure (org.codehaus.groovy.runtime.CurriedClosure)2