Search in sources :

Example 1 with FastArray

use of org.codehaus.groovy.util.FastArray in project groovy by apache.

the class MetaClassImpl method chooseMethodInternal.

private Object chooseMethodInternal(String methodName, Object methodOrList, Class[] arguments) {
    if (methodOrList instanceof MetaMethod) {
        if (((ParameterTypes) methodOrList).isValidMethod(arguments)) {
            return methodOrList;
        }
        return null;
    }
    FastArray methods = (FastArray) methodOrList;
    if (methods == null)
        return null;
    int methodCount = methods.size();
    if (methodCount <= 0) {
        return null;
    } else if (methodCount == 1) {
        Object method = methods.get(0);
        if (((ParameterTypes) method).isValidMethod(arguments)) {
            return method;
        }
        return null;
    }
    Object answer;
    if (arguments == null || arguments.length == 0) {
        answer = MetaClassHelper.chooseEmptyMethodParams(methods);
    } else {
        Object matchingMethods = null;
        final int len = methods.size;
        Object[] data = methods.getArray();
        for (int i = 0; i != len; ++i) {
            Object method = data[i];
            // making this false helps find matches
            if (((ParameterTypes) method).isValidMethod(arguments)) {
                if (matchingMethods == null)
                    matchingMethods = method;
                else if (matchingMethods instanceof ArrayList)
                    ((ArrayList) matchingMethods).add(method);
                else {
                    List arr = new ArrayList(4);
                    arr.add(matchingMethods);
                    arr.add(method);
                    matchingMethods = arr;
                }
            }
        }
        if (matchingMethods == null) {
            return null;
        } else if (!(matchingMethods instanceof ArrayList)) {
            return matchingMethods;
        }
        return chooseMostSpecificParams(methodName, (List) matchingMethods, arguments);
    }
    if (answer != null) {
        return answer;
    }
    throw new MethodSelectionException(methodName, methods, arguments);
}
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) MethodSelectionException(org.codehaus.groovy.runtime.metaclass.MethodSelectionException) ParameterTypes(org.codehaus.groovy.reflection.ParameterTypes) FastArray(org.codehaus.groovy.util.FastArray)

Example 2 with FastArray

use of org.codehaus.groovy.util.FastArray in project groovy by apache.

the class MetaClassImpl method removeMultimethodsOverloadedWithPrivateMethods.

private void removeMultimethodsOverloadedWithPrivateMethods() {
    MethodIndexAction mia = new MethodIndexAction() {

        public boolean skipClass(Class clazz) {
            return clazz == theClass;
        }

        public void methodNameAction(Class clazz, MetaMethodIndex.Entry e) {
            if (e.methods == null)
                return;
            boolean hasPrivate = false;
            if (e.methods instanceof FastArray) {
                FastArray methods = (FastArray) e.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.isPrivate() && clazz == method.getDeclaringClass().getTheClass()) {
                        hasPrivate = true;
                        break;
                    }
                }
            } else {
                MetaMethod method = (MetaMethod) e.methods;
                if (method.isPrivate() && clazz == method.getDeclaringClass().getTheClass()) {
                    hasPrivate = true;
                }
            }
            if (!hasPrivate)
                return;
            // We have private methods for that name, so remove the
            // multimethods. That is the same as in our index for
            // super, so just copy the list from there. It is not
            // possible to use a pointer here, because the methods
            // in the index for super are replaced later by MOP
            // methods like super$5$foo
            final Object o = e.methodsForSuper;
            if (o instanceof FastArray)
                e.methods = ((FastArray) o).copy();
            else
                e.methods = o;
        }
    };
    mia.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)

Example 3 with FastArray

use of org.codehaus.groovy.util.FastArray in project groovy by apache.

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;

        @Override
        public boolean skipClass(Class clazz) {
            return !useThis && clazz == theClass;
        }

        @Override
        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) FastArray(org.codehaus.groovy.util.FastArray) NewMetaMethod(org.codehaus.groovy.runtime.metaclass.NewMetaMethod) CachedClass(org.codehaus.groovy.reflection.CachedClass)

Example 4 with FastArray

use of org.codehaus.groovy.util.FastArray in project groovy by apache.

the class MetaMethodIndex method copyNonPrivateMethodsFromSuper.

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

Example 5 with FastArray

use of org.codehaus.groovy.util.FastArray in project groovy by apache.

the class MetaMethodIndex method copyAllMethods.

private void copyAllMethods(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.methods = addMethodToList(e.methods, method);
        }
    } else {
        MetaMethod method = (MetaMethod) oldListOrMethod;
        if (!method.isPrivate()) {
            Entry e = getOrPutMethods(from.name, to);
            e.methods = addMethodToList(e.methods, 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