in lib/semantic.js [1590:1634]
visitStaticCall(ast, env) {
assert.equal(ast.left.type, 'static_call');
const moduleId = ast.left.id;
const moduleName = moduleId.lexeme;
const checker = this.dependencies.get(moduleName) || builtin.get(moduleName);
const method = ast.left.propertyPath[0];
const methodName = method.lexeme;
const def = checker.methods.get(methodName);
if (!def) {
this.error(`the static function "${methodName}" is undefined in ${moduleName}`, method);
}
if (!def.isStatic) {
this.error(`the "${methodName}" is not static function`, method);
}
const expected = this.getParameterTypes(def, moduleName);
const actual = [];
for (let i = 0; i < ast.args.length; i++) {
const arg = ast.args[i];
this.visitExpr(arg, env);
const type = this.getExprType(arg, env);
actual.push(type);
}
if (!eql(expected, actual)) {
this.error(`the parameter` +
` types are mismatched. expected ` +
`${moduleName}.${methodName}(${expected.map((item) => display(item)).join(', ')}), but ` +
`${moduleName}.${methodName}(${actual.map((item) => display(item)).join(', ')})`, method);
}
for (let i = 0; i < ast.args.length; i++) {
const arg = ast.args[i];
arg.expectedType = expected[i];
arg.needCast = isNeedToMap(expected[i], arg.inferred);
}
ast.isAsync = def.isAsync;
ast.isStatic = def.isStatic;
ast.hasThrow = def.isAsync || def.hasThrow;
ast.inferred = this.getType(def.returnType, moduleName);
}