use of org.codehaus.groovy.reflection.ParameterTypes 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.reflection.ParameterTypes in project groovy by apache.
the class MetaClassImpl method chooseMostSpecificParams.
private Object chooseMostSpecificParams(String name, List matchingMethods, Class[] arguments) {
long matchesDistance = -1;
LinkedList matches = new LinkedList();
for (Object method : matchingMethods) {
ParameterTypes paramTypes = (ParameterTypes) method;
long dist = MetaClassHelper.calculateParameterDistance(arguments, paramTypes);
if (dist == 0)
return method;
if (matches.isEmpty()) {
matches.add(method);
matchesDistance = dist;
} else if (dist < matchesDistance) {
matchesDistance = dist;
matches.clear();
matches.add(method);
} else if (dist == matchesDistance) {
matches.add(method);
}
}
if (matches.size() == 1) {
return matches.getFirst();
}
if (matches.isEmpty()) {
return null;
}
//more than one matching method found --> ambiguous!
StringBuilder msg = new StringBuilder("Ambiguous method overloading for method ");
msg.append(theClass.getName()).append("#").append(name).append(".\nCannot resolve which method to invoke for ").append(InvokerHelper.toString(arguments)).append(" due to overlapping prototypes between:");
for (final Object matche : matches) {
Class[] types = ((ParameterTypes) matche).getNativeParameterTypes();
msg.append("\n\t").append(InvokerHelper.toString(types));
}
throw new GroovyRuntimeException(msg.toString());
}
use of org.codehaus.groovy.reflection.ParameterTypes in project groovy by apache.
the class MetaClassHelper method chooseEmptyMethodParams.
/**
* @param methods the methods to choose from
* @return the method with 1 parameter which takes the most general type of
* object (e.g. Object)
*/
public static Object chooseEmptyMethodParams(FastArray methods) {
Object vargsMethod = null;
final int len = methods.size();
final Object[] data = methods.getArray();
for (int i = 0; i != len; ++i) {
Object method = data[i];
final ParameterTypes pt = (ParameterTypes) method;
CachedClass[] paramTypes = pt.getParameterTypes();
int paramLength = paramTypes.length;
if (paramLength == 0) {
return method;
} else if (paramLength == 1 && pt.isVargsMethod(EMPTY_ARRAY)) {
vargsMethod = method;
}
}
return vargsMethod;
}
use of org.codehaus.groovy.reflection.ParameterTypes in project groovy by apache.
the class MetaClassHelper method chooseMostGeneralMethodWith1NullParam.
/**
* Warning: this method does not choose properly if multiple methods with
* the same distance are encountered
* @param methods the methods to choose from
* @return the method with 1 parameter which takes the most general type of
* object (e.g. Object) ignoring primitive types
* @deprecated
*/
@Deprecated
public static Object chooseMostGeneralMethodWith1NullParam(FastArray methods) {
// let's look for methods with 1 argument which matches the type of the
// arguments
CachedClass closestClass = null;
CachedClass closestVargsClass = null;
Object answer = null;
int closestDist = -1;
final int len = methods.size();
for (int i = 0; i != len; ++i) {
final Object[] data = methods.getArray();
Object method = data[i];
final ParameterTypes pt = (ParameterTypes) method;
CachedClass[] paramTypes = pt.getParameterTypes();
int paramLength = paramTypes.length;
if (paramLength == 0 || paramLength > 2)
continue;
CachedClass theType = paramTypes[0];
if (theType.isPrimitive)
continue;
if (paramLength == 2) {
if (!pt.isVargsMethod(ARRAY_WITH_NULL))
continue;
if (closestClass == null) {
closestVargsClass = paramTypes[1];
closestClass = theType;
answer = method;
} else if (closestClass.getTheClass() == theType.getTheClass()) {
if (closestVargsClass == null)
continue;
CachedClass newVargsClass = paramTypes[1];
if (isAssignableFrom(newVargsClass.getTheClass(), closestVargsClass.getTheClass())) {
closestVargsClass = newVargsClass;
answer = method;
}
} else if (isAssignableFrom(theType.getTheClass(), closestClass.getTheClass())) {
closestVargsClass = paramTypes[1];
closestClass = theType;
answer = method;
}
} else {
if (closestClass == null || isAssignableFrom(theType.getTheClass(), closestClass.getTheClass())) {
closestVargsClass = null;
closestClass = theType;
answer = method;
closestDist = -1;
} else {
// to check the distance to Object
if (closestDist == -1)
closestDist = closestClass.getSuperClassDistance();
int newDist = theType.getSuperClassDistance();
if (newDist < closestDist) {
closestDist = newDist;
closestVargsClass = null;
closestClass = theType;
answer = method;
}
}
}
}
return answer;
}
use of org.codehaus.groovy.reflection.ParameterTypes in project groovy-core by groovy.
the class MetaClassHelper method chooseMostGeneralMethodWith1NullParam.
/**
* Warning: this method does not choose properly if multiple methods with
* the same distance are encountered
* @param methods the methods to choose from
* @return the method with 1 parameter which takes the most general type of
* object (e.g. Object) ignoring primitive types
* @deprecated
*/
public static Object chooseMostGeneralMethodWith1NullParam(FastArray methods) {
// let's look for methods with 1 argument which matches the type of the
// arguments
CachedClass closestClass = null;
CachedClass closestVargsClass = null;
Object answer = null;
int closestDist = -1;
final int len = methods.size();
for (int i = 0; i != len; ++i) {
final Object[] data = methods.getArray();
Object method = data[i];
final ParameterTypes pt = (ParameterTypes) method;
CachedClass[] paramTypes = pt.getParameterTypes();
int paramLength = paramTypes.length;
if (paramLength == 0 || paramLength > 2)
continue;
CachedClass theType = paramTypes[0];
if (theType.isPrimitive)
continue;
if (paramLength == 2) {
if (!pt.isVargsMethod(ARRAY_WITH_NULL))
continue;
if (closestClass == null) {
closestVargsClass = paramTypes[1];
closestClass = theType;
answer = method;
} else if (closestClass.getTheClass() == theType.getTheClass()) {
if (closestVargsClass == null)
continue;
CachedClass newVargsClass = paramTypes[1];
if (isAssignableFrom(newVargsClass.getTheClass(), closestVargsClass.getTheClass())) {
closestVargsClass = newVargsClass;
answer = method;
}
} else if (isAssignableFrom(theType.getTheClass(), closestClass.getTheClass())) {
closestVargsClass = paramTypes[1];
closestClass = theType;
answer = method;
}
} else {
if (closestClass == null || isAssignableFrom(theType.getTheClass(), closestClass.getTheClass())) {
closestVargsClass = null;
closestClass = theType;
answer = method;
closestDist = -1;
} else {
// to check the distance to Object
if (closestDist == -1)
closestDist = closestClass.getSuperClassDistance();
int newDist = theType.getSuperClassDistance();
if (newDist < closestDist) {
closestDist = newDist;
closestVargsClass = null;
closestClass = theType;
answer = method;
}
}
}
}
return answer;
}
Aggregations