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);
}
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();
}
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();
}
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);
}
}
}
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);
}
}
}
Aggregations