Search in sources :

Example 16 with FastArray

use of org.codehaus.groovy.util.FastArray in project groovy-core by groovy.

the class MetaClassImpl method replaceWithMOPCalls.

private void replaceWithMOPCalls(final CachedMethod[] mopMethods) {
    // no MOP methods if not a child of GroovyObject
    if (!isGroovyObject)
        return;
    class MOPIter extends MethodIndexAction {

        boolean useThis;

        public boolean skipClass(CachedClass clazz) {
            return !useThis && clazz == theCachedClass;
        }

        public void methodNameAction(Class clazz, MetaMethodIndex.Entry e) {
            if (useThis) {
                if (e.methods == null)
                    return;
                if (e.methods instanceof FastArray) {
                    FastArray methods = (FastArray) e.methods;
                    processFastArray(methods);
                } else {
                    MetaMethod method = (MetaMethod) e.methods;
                    if (method instanceof NewMetaMethod)
                        return;
                    if (useThis ^ Modifier.isPrivate(method.getModifiers()))
                        return;
                    String mopName = method.getMopName();
                    int index = Arrays.binarySearch(mopMethods, mopName, CachedClass.CachedMethodComparatorWithString.INSTANCE);
                    if (index >= 0) {
                        int from = index;
                        while (from > 0 && mopMethods[from - 1].getName().equals(mopName)) from--;
                        int to = index;
                        while (to < mopMethods.length - 1 && mopMethods[to + 1].getName().equals(mopName)) to++;
                        int matchingMethod = findMatchingMethod(mopMethods, from, to, method);
                        if (matchingMethod != -1) {
                            e.methods = mopMethods[matchingMethod];
                        }
                    }
                }
            } else {
                if (e.methodsForSuper == null)
                    return;
                if (e.methodsForSuper instanceof FastArray) {
                    FastArray methods = (FastArray) e.methodsForSuper;
                    processFastArray(methods);
                } else {
                    MetaMethod method = (MetaMethod) e.methodsForSuper;
                    if (method instanceof NewMetaMethod)
                        return;
                    if (useThis ^ Modifier.isPrivate(method.getModifiers()))
                        return;
                    String mopName = method.getMopName();
                    // GROOVY-4922: Due to a numbering scheme change, we must find the super$X$method which exists
                    // with the highest number. If we don't, no method may be found, leading to a stack overflow
                    String[] decomposedMopName = decomposeMopName(mopName);
                    int distance = Integer.parseInt(decomposedMopName[1]);
                    while (distance > 0) {
                        String fixedMopName = decomposedMopName[0] + distance + decomposedMopName[2];
                        int index = Arrays.binarySearch(mopMethods, fixedMopName, CachedClass.CachedMethodComparatorWithString.INSTANCE);
                        if (index >= 0) {
                            int from = index;
                            while (from > 0 && mopMethods[from - 1].getName().equals(fixedMopName)) from--;
                            int to = index;
                            while (to < mopMethods.length - 1 && mopMethods[to + 1].getName().equals(fixedMopName)) to++;
                            int matchingMethod = findMatchingMethod(mopMethods, from, to, method);
                            if (matchingMethod != -1) {
                                e.methodsForSuper = mopMethods[matchingMethod];
                                distance = 0;
                            }
                        }
                        distance--;
                    }
                }
            }
        }

        private String[] decomposeMopName(final String mopName) {
            int idx = mopName.indexOf("$");
            if (idx > 0) {
                int eidx = mopName.indexOf("$", idx + 1);
                if (eidx > 0) {
                    return new String[] { mopName.substring(0, idx + 1), mopName.substring(idx + 1, eidx), mopName.substring(eidx) };
                }
            }
            return new String[] { "", "0", mopName };
        }

        private void processFastArray(FastArray methods) {
            final int len = methods.size();
            final Object[] data = methods.getArray();
            for (int i = 0; i != len; ++i) {
                MetaMethod method = (MetaMethod) data[i];
                if (method instanceof NewMetaMethod)
                    continue;
                boolean isPrivate = Modifier.isPrivate(method.getModifiers());
                if (useThis ^ isPrivate)
                    continue;
                String mopName = method.getMopName();
                int index = Arrays.binarySearch(mopMethods, mopName, CachedClass.CachedMethodComparatorWithString.INSTANCE);
                if (index >= 0) {
                    int from = index;
                    while (from > 0 && mopMethods[from - 1].getName().equals(mopName)) from--;
                    int to = index;
                    while (to < mopMethods.length - 1 && mopMethods[to + 1].getName().equals(mopName)) to++;
                    int matchingMethod = findMatchingMethod(mopMethods, from, to, method);
                    if (matchingMethod != -1) {
                        methods.set(i, mopMethods[matchingMethod]);
                    }
                }
            }
        }
    }
    MOPIter iter = new MOPIter();
    // replace all calls for super with the correct MOP method
    iter.useThis = false;
    iter.iterate();
    // replace all calls for this with the correct MOP method
    iter.useThis = true;
    iter.iterate();
}
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) FastArray(org.codehaus.groovy.util.FastArray) NewMetaMethod(org.codehaus.groovy.runtime.metaclass.NewMetaMethod) CachedClass(org.codehaus.groovy.reflection.CachedClass)

Example 17 with FastArray

use of org.codehaus.groovy.util.FastArray in project groovy-core by groovy.

the class MetaClassImpl method getMethods.

/**
     * Gets all instance methods available on this class for the given name
     *
     * @return all the normal instance methods available on this class for the
     *         given name
     */
private Object getMethods(Class sender, String name, boolean isCallToSuper) {
    Object answer;
    final MetaMethodIndex.Entry entry = metaMethodIndex.getMethods(sender, name);
    if (entry == null)
        answer = FastArray.EMPTY_LIST;
    else if (isCallToSuper) {
        answer = entry.methodsForSuper;
    } else {
        answer = entry.methods;
    }
    if (answer == null)
        answer = FastArray.EMPTY_LIST;
    if (!isCallToSuper) {
        List used = GroovyCategorySupport.getCategoryMethods(name);
        if (used != null) {
            FastArray arr;
            if (answer instanceof MetaMethod) {
                arr = new FastArray();
                arr.add(answer);
            } else
                arr = ((FastArray) answer).copy();
            for (Iterator iter = used.iterator(); iter.hasNext(); ) {
                MetaMethod element = (MetaMethod) iter.next();
                if (!element.getDeclaringClass().getTheClass().isAssignableFrom(sender))
                    continue;
                filterMatchingMethodForCategory(arr, element);
            }
            answer = arr;
        }
    }
    return answer;
}
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) FastArray(org.codehaus.groovy.util.FastArray)

Example 18 with FastArray

use of org.codehaus.groovy.util.FastArray in project groovy-core by groovy.

the class ExpandoMetaClass method registerSubclassInstanceMethod.

public void registerSubclassInstanceMethod(MetaMethod metaMethod) {
    modified = true;
    final String name = metaMethod.getName();
    Object methodOrList = expandoSubclassMethods.get(name);
    if (methodOrList == null) {
        expandoSubclassMethods.put(name, metaMethod);
    } else {
        if (methodOrList instanceof MetaMethod) {
            FastArray arr = new FastArray(2);
            arr.add(methodOrList);
            arr.add(metaMethod);
            expandoSubclassMethods.put(name, arr);
        } else {
            ((FastArray) methodOrList).add(metaMethod);
        }
    }
}
Also used : ClosureStaticMetaMethod(org.codehaus.groovy.runtime.metaclass.ClosureStaticMetaMethod) MixinInstanceMetaMethod(org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod) ClosureMetaMethod(org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod) FastArray(org.codehaus.groovy.util.FastArray)

Example 19 with FastArray

use of org.codehaus.groovy.util.FastArray in project groovy-core by groovy.

the class MetaClassImpl method findMethod.

/**
     * @return the matching method which should be found
     */
private MetaMethod findMethod(CachedMethod aMethod) {
    Object methods = getMethods(theClass, aMethod.getName(), false);
    if (methods instanceof FastArray) {
        FastArray m = (FastArray) methods;
        final int len = m.size;
        final Object[] data = m.getArray();
        for (int i = 0; i != len; ++i) {
            MetaMethod method = (MetaMethod) data[i];
            if (method.isMethod(aMethod)) {
                return method;
            }
        }
    } else {
        MetaMethod method = (MetaMethod) methods;
        if (method.getName().equals(aMethod.getName()) && //                    && method.getModifiers() == aMethod.getModifiers()
        method.getReturnType().equals(aMethod.getReturnType()) && MetaMethod.equal(method.getParameterTypes(), aMethod.getParameterTypes())) {
            return method;
        }
    }
    //log.warning("Creating reflection based dispatcher for: " + aMethod);
    synchronized (aMethod.cachedClass) {
        return aMethod;
    }
}
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) FastArray(org.codehaus.groovy.util.FastArray)

Example 20 with FastArray

use of org.codehaus.groovy.util.FastArray in project groovy-core by groovy.

the class MetaMethodIndex method copyAllMethodsToSuper.

private void copyAllMethodsToSuper(Entry from, Header to) {
    Object oldListOrMethod = from.methods;
    if (oldListOrMethod instanceof FastArray) {
        FastArray oldList = (FastArray) oldListOrMethod;
        Entry e = null;
        int len1 = oldList.size();
        Object[] list = oldList.getArray();
        for (int j = 0; j != len1; ++j) {
            MetaMethod method = (MetaMethod) list[j];
            if (e == null)
                e = getOrPutMethods(from.name, to);
            e.methodsForSuper = addMethodToList(e.methodsForSuper, method);
        }
    } else {
        MetaMethod method = (MetaMethod) oldListOrMethod;
        Entry e = getOrPutMethods(from.name, to);
        e.methodsForSuper = addMethodToList(e.methodsForSuper, method);
    }
}
Also used : MetaMethod(groovy.lang.MetaMethod) GeneratedMetaMethod(org.codehaus.groovy.reflection.GeneratedMetaMethod) FastArray(org.codehaus.groovy.util.FastArray)

Aggregations

FastArray (org.codehaus.groovy.util.FastArray)28 GeneratedMetaMethod (org.codehaus.groovy.reflection.GeneratedMetaMethod)26 ClosureMetaMethod (org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod)16 MixinInstanceMetaMethod (org.codehaus.groovy.runtime.metaclass.MixinInstanceMetaMethod)16 NewInstanceMetaMethod (org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod)14 NewMetaMethod (org.codehaus.groovy.runtime.metaclass.NewMetaMethod)14 NewStaticMetaMethod (org.codehaus.groovy.runtime.metaclass.NewStaticMetaMethod)14 TransformMetaMethod (org.codehaus.groovy.runtime.metaclass.TransformMetaMethod)14 MetaMethod (groovy.lang.MetaMethod)12 CachedClass (org.codehaus.groovy.reflection.CachedClass)10 MethodSelectionException (org.codehaus.groovy.runtime.metaclass.MethodSelectionException)4 ParameterTypes (org.codehaus.groovy.reflection.ParameterTypes)2 ClosureStaticMetaMethod (org.codehaus.groovy.runtime.metaclass.ClosureStaticMetaMethod)2 MetaMethodIndex (org.codehaus.groovy.runtime.metaclass.MetaMethodIndex)2