From ca36284612b59b36969cad8fc8d9e987ec7208fd Mon Sep 17 00:00:00 2001 From: shove Date: Fri, 9 Sep 2022 19:44:49 +0800 Subject: [PATCH] fmt: fix anonymous struct in parameter with invalid type name. fix #15696 (#15711) --- vlib/v/ast/str.v | 47 ++++++++++++------- vlib/v/fmt/struct.v | 4 +- .../tests/anon_struct_as_param_expected.vv | 9 ++++ .../v/fmt/tests/anon_struct_as_param_input.vv | 8 ++++ 4 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 vlib/v/fmt/tests/anon_struct_as_param_expected.vv create mode 100644 vlib/v/fmt/tests/anon_struct_as_param_input.vv diff --git a/vlib/v/ast/str.v b/vlib/v/ast/str.v index 3434e1424..9dd9c9ee3 100644 --- a/vlib/v/ast/str.v +++ b/vlib/v/ast/str.v @@ -137,26 +137,41 @@ fn stringify_fn_after_name(node &FnDecl, mut f strings.Builder, t &Table, cur_mo f.write_string(arg.typ.share().str() + ' ') } f.write_string(arg.name) - mut s := t.type_to_str(arg.typ.clear_flag(.shared_f)) - if arg.is_mut { - arg_sym := t.sym(arg.typ) - if s.starts_with('&') && ((!arg_sym.is_number() && arg_sym.kind != .bool) - || node.language != .v) { - s = s[1..] + arg_sym := t.sym(arg.typ) + if arg_sym.kind == .struct_ && (arg_sym.info as Struct).is_anon { + f.write_string(' struct {') + struct_ := arg_sym.info as Struct + for field in struct_.fields { + f.write_string(' $field.name ${t.type_to_str(field.typ)}') + if field.has_default_expr { + f.write_string(' = $field.default_expr') + } } - } - s = util.no_cur_mod(s, cur_mod) - for mod, alias in m2a { - s = s.replace(mod, alias) - } - if should_add_type { - if !is_type_only { + if struct_.fields.len > 0 { f.write_string(' ') } - if node.is_variadic && is_last_arg { - f.write_string('...') + f.write_string('}') + } else { + mut s := t.type_to_str(arg.typ.clear_flag(.shared_f)) + if arg.is_mut { + if s.starts_with('&') && ((!arg_sym.is_number() && arg_sym.kind != .bool) + || node.language != .v) { + s = s[1..] + } + } + s = util.no_cur_mod(s, cur_mod) + for mod, alias in m2a { + s = s.replace(mod, alias) + } + if should_add_type { + if !is_type_only { + f.write_string(' ') + } + if node.is_variadic && is_last_arg { + f.write_string('...') + } + f.write_string(s) } - f.write_string(s) } if !is_last_arg { f.write_string(', ') diff --git a/vlib/v/fmt/struct.v b/vlib/v/fmt/struct.v index d73afb00d..52e5fa1a5 100644 --- a/vlib/v/fmt/struct.v +++ b/vlib/v/fmt/struct.v @@ -253,7 +253,7 @@ pub fn (mut f Fmt) struct_init(node ast.StructInit) { if node.pos.line_nr < node.pos.last_line || node.pre_comments.len > 0 { single_line_fields = false } - if !use_short_args { + if !use_short_args || node.is_anon { f.write('$name{') f.mark_import_as_used(name) if single_line_fields { @@ -315,7 +315,7 @@ pub fn (mut f Fmt) struct_init(node ast.StructInit) { if !single_line_fields { f.indent-- } - if !use_short_args { + if !use_short_args || node.is_anon { if single_line_fields { f.write(' ') } diff --git a/vlib/v/fmt/tests/anon_struct_as_param_expected.vv b/vlib/v/fmt/tests/anon_struct_as_param_expected.vv new file mode 100644 index 000000000..fcda3cd55 --- /dev/null +++ b/vlib/v/fmt/tests/anon_struct_as_param_expected.vv @@ -0,0 +1,9 @@ +fn func(arg struct { foo string = 'bar' }) { + println(arg.foo) +} + +fn main() { + func(struct { + foo: 'foo' + }) +} diff --git a/vlib/v/fmt/tests/anon_struct_as_param_input.vv b/vlib/v/fmt/tests/anon_struct_as_param_input.vv new file mode 100644 index 000000000..8980348c8 --- /dev/null +++ b/vlib/v/fmt/tests/anon_struct_as_param_input.vv @@ -0,0 +1,8 @@ +fn func(arg struct{foo string='bar'}) { + println(arg.foo) +} + +fn main() { + func(struct {foo: 'foo' + }) +} -- 2.39.5