From b0b3c51658ca8e46277511d091962d1f71e6d7c3 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 12 Apr 2021 05:57:00 +0800 Subject: [PATCH] checker: minor cleanup in fn_call (#9681) --- vlib/v/checker/checker.v | 103 ++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index eeddd227c6..3445ac4163 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1968,7 +1968,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { return ret_type } // look for function in format `mod.fn` or `fn` (builtin) - mut f := ast.Fn{} + mut func := ast.Fn{} mut found := false mut found_in_args := false // anon fn direct call @@ -1977,16 +1977,16 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { call_expr.name = '' c.expr(call_expr.left) anon_fn_sym := c.table.get_type_symbol(call_expr.left.typ) - f = (anon_fn_sym.info as ast.FnType).func + func = (anon_fn_sym.info as ast.FnType).func found = true } // try prefix with current module as it would have never gotten prefixed if !found && !fn_name.contains('.') && call_expr.mod != 'builtin' { name_prefixed := '${call_expr.mod}.$fn_name' - if f1 := c.table.find_fn(name_prefixed) { + if f := c.table.find_fn(name_prefixed) { call_expr.name = name_prefixed found = true - f = f1 + func = f c.table.fns[name_prefixed].usages++ } } @@ -2018,21 +2018,21 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { } // already prefixed (mod.fn) or C/builtin/main if !found { - if f1 := c.table.find_fn(fn_name) { + if f := c.table.find_fn(fn_name) { found = true - f = f1 + func = f c.table.fns[fn_name].usages++ } } if c.pref.is_script && !found { os_name := 'os.$fn_name' - if f1 := c.table.find_fn(os_name) { - if f1.generic_names.len == call_expr.generic_types.len { + if f := c.table.find_fn(os_name) { + if f.generic_names.len == call_expr.generic_types.len { c.table.fn_gen_types[os_name] = c.table.fn_gen_types['${call_expr.mod}.$call_expr.name'] } call_expr.name = os_name found = true - f = f1 + func = f c.table.fns[os_name].usages++ } } @@ -2043,7 +2043,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { vts := c.table.get_type_symbol(v.typ) if vts.kind == .function { info := vts.info as ast.FnType - f = info.func + func = info.func found = true found_in_args = true } @@ -2060,44 +2060,47 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { call_expr.pos) } } - if !f.is_pub && f.language == .v && f.name.len > 0 && f.mod.len > 0 && f.mod != c.mod { - c.error('function `$f.name` is private', call_expr.pos) + if !func.is_pub && func.language == .v && func.name.len > 0 && func.mod.len > 0 + && func.mod != c.mod { + c.error('function `$func.name` is private', call_expr.pos) } - if !c.cur_fn.is_deprecated && f.is_deprecated { - c.deprecate_fnmethod('function', f.name, f, call_expr) + if !c.cur_fn.is_deprecated && func.is_deprecated { + c.deprecate_fnmethod('function', func.name, func, call_expr) } - if f.is_unsafe && !c.inside_unsafe - && (f.language != .c || (f.name[2] in [`m`, `s`] && f.mod == 'builtin')) { + if func.is_unsafe && !c.inside_unsafe + && (func.language != .c || (func.name[2] in [`m`, `s`] && func.mod == 'builtin')) { // builtin C.m*, C.s* only - temp - c.warn('function `$f.name` must be called from an `unsafe` block', call_expr.pos) + c.warn('function `$func.name` must be called from an `unsafe` block', call_expr.pos) } - call_expr.is_keep_alive = f.is_keep_alive - if f.mod != 'builtin' && f.language == .v && f.no_body && !c.pref.translated && !f.is_unsafe { + call_expr.is_keep_alive = func.is_keep_alive + if func.mod != 'builtin' && func.language == .v && func.no_body && !c.pref.translated + && !func.is_unsafe { c.error('cannot call a function that does not have a body', call_expr.pos) } for generic_type in call_expr.generic_types { c.ensure_type_exists(generic_type, call_expr.generic_list_pos) or {} } - if f.generic_names.len > 0 && f.return_type.has_flag(.generic) { - c.check_return_generics_struct(f.return_type, mut call_expr, generic_types) + if func.generic_names.len > 0 && func.return_type.has_flag(.generic) { + c.check_return_generics_struct(func.return_type, mut call_expr, generic_types) } else { - call_expr.return_type = f.return_type + call_expr.return_type = func.return_type } - if f.return_type == ast.void_type && f.ctdefine.len > 0 && f.ctdefine !in c.pref.compile_defines { + if func.return_type == ast.void_type && func.ctdefine.len > 0 + && func.ctdefine !in c.pref.compile_defines { call_expr.should_be_skipped = true } // dont check number of args for JS functions since arguments are not required if call_expr.language != .js { - min_required_args := if f.is_variadic { f.params.len - 1 } else { f.params.len } + min_required_args := if func.is_variadic { func.params.len - 1 } else { func.params.len } if call_expr.args.len < min_required_args { c.error('expected $min_required_args arguments, but got $call_expr.args.len', call_expr.pos) - } else if !f.is_variadic && call_expr.args.len > f.params.len { + } else if !func.is_variadic && call_expr.args.len > func.params.len { unexpected_arguments := call_expr.args[min_required_args..] unexpected_arguments_pos := unexpected_arguments[0].pos.extend(unexpected_arguments.last().pos) c.error('expected $min_required_args arguments, but got $call_expr.args.len', unexpected_arguments_pos) - return f.return_type + return func.return_type } } // println / eprintln / panic can print anything @@ -2123,7 +2126,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { prhas_str, prexpects_ptr, prnr_args := prtyp_sym.str_method_info() eprintln('>>> println hack typ: ${prtyp} | sym.name: ${prtyp_sym.name} | is_ptr: $prtyp_is_ptr | has_str: $prhas_str | expects_ptr: $prexpects_ptr | nr_args: $prnr_args | expr: ${prexpr.str()} ') */ - return f.return_type + return func.return_type } // `return error(err)` -> `return err` if fn_name == 'error' { @@ -2135,19 +2138,19 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { } // TODO: typ optimize.. this node can get processed more than once if call_expr.expected_arg_types.len == 0 { - for param in f.params { + for param in func.params { call_expr.expected_arg_types << param.typ } } for i, call_arg in call_expr.args { - param := if f.is_variadic && i >= f.params.len - 1 { - f.params[f.params.len - 1] + param := if func.is_variadic && i >= func.params.len - 1 { + func.params[func.params.len - 1] } else { - f.params[i] + func.params[i] } - if f.is_variadic && call_arg.expr is ast.ArrayDecompose { - if i > f.params.len - 1 { - c.error('too many arguments in call to `$f.name`', call_expr.pos) + if func.is_variadic && call_arg.expr is ast.ArrayDecompose { + if i > func.params.len - 1 { + c.error('too many arguments in call to `$func.name`', call_expr.pos) } } c.expected_type = param.typ @@ -2155,7 +2158,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { call_expr.args[i].typ = typ typ_sym := c.table.get_type_symbol(typ) arg_typ_sym := c.table.get_type_symbol(param.typ) - if f.is_variadic && typ.has_flag(.variadic) && call_expr.args.len - 1 > i { + if func.is_variadic && typ.has_flag(.variadic) && call_expr.args.len - 1 > i { c.error('when forwarding a variadic variable, it must be the final argument', call_arg.pos) } @@ -2164,7 +2167,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { c.error('function with `shared` arguments cannot be called inside `lock`/`rlock` block', call_arg.pos) } - if call_arg.is_mut && f.language == .v { + if call_arg.is_mut && func.language == .v { to_lock, pos := c.fail_if_immutable(call_arg.expr) if !param.is_mut { tok := call_arg.share.str() @@ -2203,10 +2206,10 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { if typ_sym.kind == .void && arg_typ_sym.kind == .string { continue } - if f.generic_names.len > 0 { + if func.generic_names.len > 0 { if param.typ.has_flag(.generic) - && f.generic_names.len == call_expr.generic_types.len { - if unwrap_typ := c.table.resolve_generic_by_names(param.typ, f.generic_names, + && func.generic_names.len == call_expr.generic_types.len { + if unwrap_typ := c.table.resolve_generic_by_names(param.typ, func.generic_names, call_expr.generic_types) { if (unwrap_typ.idx() == typ.idx()) @@ -2228,7 +2231,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { c.error('$err.msg in argument ${i + 1} to `$fn_name`', call_arg.pos) } // Warn about automatic (de)referencing, which will be removed soon. - if f.language != .c && !c.inside_unsafe && typ.nr_muls() != param.typ.nr_muls() + if func.language != .c && !c.inside_unsafe && typ.nr_muls() != param.typ.nr_muls() && !(call_arg.is_mut && param.is_mut) && !(!call_arg.is_mut && !param.is_mut) && param.typ !in [ast.byteptr_type, ast.charptr_type, ast.voidptr_type] { // sym := c.table.get_type_symbol(typ) @@ -2236,28 +2239,30 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { call_arg.pos) } } - if f.generic_names.len != call_expr.generic_types.len { + if func.generic_names.len != call_expr.generic_types.len { // no type arguments given in call, attempt implicit instantiation - c.infer_fn_types(f, mut call_expr) + c.infer_fn_types(func, mut call_expr) } - if call_expr.generic_types.len > 0 && f.return_type != 0 { - if typ := c.table.resolve_generic_by_names(f.return_type, f.generic_names, call_expr.generic_types) { + if call_expr.generic_types.len > 0 && func.return_type != 0 { + if typ := c.table.resolve_generic_by_names(func.return_type, func.generic_names, + call_expr.generic_types) + { call_expr.return_type = typ return typ } } - if call_expr.generic_types.len > 0 && f.generic_names.len == 0 { + if call_expr.generic_types.len > 0 && func.generic_names.len == 0 { c.error('a non generic function called like a generic one', call_expr.generic_list_pos) } - if call_expr.generic_types.len > f.generic_names.len { - c.error('too many generic parameters got $call_expr.generic_types.len, expected $f.generic_names.len', + if call_expr.generic_types.len > func.generic_names.len { + c.error('too many generic parameters got $call_expr.generic_types.len, expected $func.generic_names.len', call_expr.generic_list_pos) } - if f.generic_names.len > 0 { + if func.generic_names.len > 0 { return call_expr.return_type } - return f.return_type + return func.return_type } fn (mut c Checker) deprecate_fnmethod(kind string, name string, the_fn ast.Fn, call_expr ast.CallExpr) {