Skip to content

Commit

Permalink
Improved method resolution logic.
Browse files Browse the repository at this point in the history
  • Loading branch information
Johann Beleites committed Jan 24, 2019
1 parent 2af8221 commit eb7bdb7
Showing 1 changed file with 48 additions and 35 deletions.
Expand Up @@ -442,54 +442,67 @@ protected static boolean isExactMatch(ResolvedMethodLikeDeclaration method, List
return true; return true;
} }


private static ResolvedType getMethodsExplicitAndVariadicParameterType(ResolvedMethodDeclaration method, int i) {
int numberOfParams = method.getNumberOfParams();

if (i < numberOfParams) {
return method.getParam(i).getType();
} else if (method.hasVariadicParameter()) {
return method.getParam(numberOfParams - 1).getType();
} else {
return null;
}
}

private static boolean isMoreSpecific(ResolvedMethodDeclaration methodA, ResolvedMethodDeclaration methodB, private static boolean isMoreSpecific(ResolvedMethodDeclaration methodA, ResolvedMethodDeclaration methodB,
List<ResolvedType> argumentTypes) { List<ResolvedType> argumentTypes) {
boolean oneMoreSpecificFound = false;
if (methodA.getNumberOfParams() < methodB.getNumberOfParams()) { boolean aVariadic = methodA.hasVariadicParameter();
boolean bVariadic = methodB.hasVariadicParameter();
int aNumberOfParams = methodA.getNumberOfParams();
int bNumberOfParams = methodB.getNumberOfParams();
int numberOfArgs = argumentTypes.size();

if (!aVariadic && aNumberOfParams == numberOfArgs && (bVariadic || bNumberOfParams != numberOfArgs)) {
return true; return true;
} } else if (!bVariadic && bNumberOfParams == numberOfArgs && (aVariadic || aNumberOfParams != numberOfArgs)) {
if (methodA.getNumberOfParams() > methodB.getNumberOfParams()) {
return false; return false;
} }
for (int i = 0; i < methodA.getNumberOfParams(); i++) {
ResolvedType tdA = methodA.getParam(i).getType();
ResolvedType tdB = methodB.getParam(i).getType();
// B is more specific
if (tdB.isAssignableBy(tdA) && !tdA.isAssignableBy(tdB)) {
oneMoreSpecificFound = true;
}
// A is more specific
if (tdA.isAssignableBy(tdB) && !tdB.isAssignableBy(tdA)) {
return false;
}
}


if (!oneMoreSpecificFound) { for (int i = 0 ; i < numberOfArgs ; i++) {
int lastIndex = argumentTypes.size() - 1; ResolvedType paramTypeA = getMethodsExplicitAndVariadicParameterType(methodA, i);
ResolvedType paramTypeB = getMethodsExplicitAndVariadicParameterType(methodB, i);


if (methodA.hasVariadicParameter() && !methodB.hasVariadicParameter()) { if (paramTypeA == null) {
// if the last argument is an array then m1 is more specific return false;
if (argumentTypes.get(lastIndex).isArray()) { } else if (paramTypeB == null) {
return true; return true;
} } else {
boolean aAssignableFromB = paramTypeA.isAssignableBy(paramTypeB);
boolean bAssignableFromA = paramTypeB.isAssignableBy(paramTypeA);


if (!argumentTypes.get(lastIndex).isArray()) { if (bAssignableFromA && !aAssignableFromB){
// A's parameter is more specific
return true;
} else if (aAssignableFromB && !bAssignableFromA) {
// B's parameter is more specific
return false; return false;
} }
} }
if (!methodA.hasVariadicParameter() && methodB.hasVariadicParameter()) { }
// if the last argument is an array and m1 is not variadic then
// it is not more specific
if (argumentTypes.get(lastIndex).isArray()) {
return false;
}


if (!argumentTypes.get(lastIndex).isArray()) { int lastIndex = numberOfArgs - 1;
return true;
} if (aVariadic && !bVariadic) {
} // if the last argument is an array then m1 is more specific
return argumentTypes.get(lastIndex).isArray();
} else if (!aVariadic && bVariadic) {
// if the last argument is an array and m1 is not variadic then
// it is not more specific
return !argumentTypes.get(lastIndex).isArray();
} }
return oneMoreSpecificFound;
return false;
} }


private static boolean isMoreSpecific(MethodUsage methodA, MethodUsage methodB) { private static boolean isMoreSpecific(MethodUsage methodA, MethodUsage methodB) {
Expand Down

0 comments on commit eb7bdb7

Please sign in to comment.