static bool is_method_called(ast_t* ast) { ast_t* parent = ast_parent(ast); switch(ast_id(parent)) { case TK_QUALIFY: return is_method_called(parent); case TK_CALL: return true; default: {} } ast_error(ast, "can't reference a method without calling it"); return false; }
static bool is_method_called(pass_opt_t* opt, ast_t* ast) { ast_t* parent = ast_parent(ast); switch(ast_id(parent)) { case TK_QUALIFY: return is_method_called(opt, parent); case TK_CALL: case TK_ADDRESS: return true; default: {} } ast_error(opt->check.errors, ast, "can't reference a method without calling it"); return false; }
static bool method_access(pass_opt_t* opt, ast_t* ast, ast_t* method) { AST_GET_CHILDREN(method, cap, id, typeparams, params, result, can_error, body); switch(ast_id(method)) { case TK_NEW: { AST_GET_CHILDREN(ast, left, right); ast_t* type = ast_type(left); if(is_typecheck_error(type)) return false; if(!constructor_type(opt, ast, ast_id(cap), type, &result)) return false; break; } case TK_BE: ast_setid(ast, TK_BEREF); break; case TK_FUN: ast_setid(ast, TK_FUNREF); break; default: assert(0); return false; } ast_settype(ast, type_for_fun(method)); if(ast_id(can_error) == TK_QUESTION) ast_seterror(ast); return is_method_called(opt, ast); }