update isCallCompatible to handle variable arity calls

This commit is contained in:
Dave Holoway
2020-06-10 16:09:43 +01:00
parent dd9d23c64a
commit c9ab48031e

View File

@@ -1827,22 +1827,40 @@ function isCallCompatible(m, call_arguments) {
if (m instanceof AnyMethod) { if (m instanceof AnyMethod) {
return true; return true;
} }
if (m.parameterCount !== call_arguments.length) { const param_count = m.parameterCount;
// wrong parameter count - this needs updating to support varargs if (param_count !== call_arguments.length) {
// for variable arity methods, we must have at least n-1 formal parameters
if (!m.isVariableArity || call_arguments.length < param_count - 1) {
// wrong parameter count
return false; return false;
} }
const p = m.parameters; }
for (let i=0; i < p.length; i++) { const formal_params = m.parameters.slice();
const last_param = formal_params.pop();
for (let i = 0; i < call_arguments.length; i++) {
if (!call_arguments[i].variables[0]) { if (!call_arguments[i].variables[0]) {
// only variables can be passed - not types or methods // only variables can be passed - not types or methods
return false; return false;
} }
const param = formal_params[i] || last_param;
let param_type = param.type;
if (param.varargs && param_type instanceof ArrayType) {
// last varargs parameter
// - if the argument count matches the parameter count, the final argument can match the array or non-array version
// e.g void v(int... x) will match with v(), v(1) and v(new int[3]);
if (call_arguments.length === param_count) {
if (isAssignable(param_type, call_arguments[i].variables[0])) {
continue;
}
}
param_type = param_type.elementType;
}
// is the argument assignable to the parameter // is the argument assignable to the parameter
if (isAssignable(p[i].type, call_arguments[i].variables[0])) { if (isAssignable(param_type, call_arguments[i].variables[0])) {
continue; continue;
} }
// mismatch parameter type // mismatch parameter type
return; return false;
} }
return true; return true;
} }