public static int scoreMethods( final MetaClass[] arguments, final MetaParameter[] parmTypes, final boolean isVarArgs) { int score = 0; for (int i = 0; i != arguments.length; i++) { final MetaClass actualParamType; if (isVarArgs && !arguments[arguments.length - 1].isArray() && i >= parmTypes.length - 1) actualParamType = parmTypes[parmTypes.length - 1].getType().getComponentType(); else actualParamType = parmTypes[i].getType(); if (arguments[i] == null) { if (!actualParamType.isPrimitive()) { score += 6; } else { score = 0; break; } } else if (actualParamType.equals(arguments[i])) { score += 7; } else if (actualParamType.isPrimitive() && actualParamType.asBoxed().equals(arguments[i])) { score += 6; } else if (arguments[i].isPrimitive() && arguments[i].asUnboxed().equals(actualParamType)) { score += 6; } else if (actualParamType.isAssignableFrom(arguments[i])) { score += 5; } else if (isNumericallyCoercible(arguments[i], actualParamType)) { score += 4; } else if (actualParamType.asBoxed().isAssignableFrom(arguments[i].asBoxed()) && !Object_MetaClass.equals(arguments[i])) { score += 3 + scoreInterface(actualParamType, arguments[i]); } else if (canConvert(actualParamType, arguments[i])) { if (actualParamType.isArray() && arguments[i].isArray()) { final MetaClass outerComponentTypeActual = actualParamType.getOuterComponentType(); final MetaClass outerComponentTypeArg = arguments[i].getOuterComponentType(); if (canConvert(outerComponentTypeActual, outerComponentTypeArg)) { score += 1; } else { continue; } } else if (actualParamType.equals(char_MetaClass) && arguments[i].equals(String_MetaClass)) { score += 1; } score += 1; } else if (actualParamType.equals(Object_MetaClass) || arguments[i].equals(NullType_MetaClass)) { score += 1; } else { score = 0; break; } } return score; }
public static MetaMethod getBestCandidate( final MetaClass[] arguments, final String method, final MetaClass decl, MetaMethod[] methods, final boolean classTarget) { if (methods == null || methods.length == 0) { return null; } MetaParameter[] parmTypes; MetaMethod bestCandidate = null; int bestScore = 0; int score; boolean retry = false; do { for (final MetaMethod meth : methods) { if (classTarget && (meth.isStatic())) continue; if (method.equals(meth.getName())) { final boolean isVarArgs = meth.isVarArgs(); if ((parmTypes = meth.getParameters()).length != arguments.length && !isVarArgs) { continue; } else if (arguments.length == 0 && parmTypes.length == 0) { bestCandidate = meth; break; } score = scoreMethods(arguments, parmTypes, isVarArgs); if (score != 0 && score > bestScore) { bestCandidate = meth; bestScore = score; } } } if (!retry && bestCandidate == null && decl.isInterface()) { final MetaMethod[] objMethods = Object_MetaClass.getMethods(); final MetaMethod[] nMethods = new MetaMethod[methods.length + objMethods.length]; System.arraycopy(methods, 0, nMethods, 0, methods.length); System.arraycopy(objMethods, 0, nMethods, methods.length, objMethods.length); methods = nMethods; retry = true; } else { break; } } while (true); return bestCandidate; }