From 2f2dde8ad05ec767888dba01f2ad17084a682109 Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 28 Jul 2023 20:30:15 +0800 Subject: [PATCH] ast, parser, fmt: fix formatting struct declaration with comments (fix #18982) (#18992) --- vlib/v/ast/ast.v | 1 + vlib/v/fmt/struct.v | 11 ++++++++--- vlib/v/fmt/tests/struct_decl_with_comments_keep.vv | 13 +++++++++++++ vlib/v/fmt/tests/structs_expected.vv | 2 +- vlib/v/parser/struct.v | 8 ++++++-- 5 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 vlib/v/fmt/tests/struct_decl_with_comments_keep.vv diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 5afaf2c04d..886761b958 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -381,6 +381,7 @@ pub: language Language is_union bool attrs []Attr + pre_comments []Comment end_comments []Comment embeds []Embed pub mut: diff --git a/vlib/v/fmt/struct.v b/vlib/v/fmt/struct.v index 9469419624..ca16cb999f 100644 --- a/vlib/v/fmt/struct.v +++ b/vlib/v/fmt/struct.v @@ -60,6 +60,9 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) { } } f.writeln(' {') + if node.pre_comments.len > 0 { + f.comments_before_field(node.pre_comments) + } for embed in node.embeds { f.mark_types_import_as_used(embed.typ) styp := f.table.type_to_str_using_aliases(embed.typ, f.mod2alias) @@ -188,11 +191,13 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) { f.writeln('') } } - f.comments_after_last_field(node.end_comments) - if is_anon { + if is_anon || node.end_comments.len > 0 { f.write('}') } else { - f.writeln('}\n') + f.writeln('}') + } + if node.end_comments.len > 0 { + f.comments(node.end_comments, inline: true) } } diff --git a/vlib/v/fmt/tests/struct_decl_with_comments_keep.vv b/vlib/v/fmt/tests/struct_decl_with_comments_keep.vv new file mode 100644 index 0000000000..963bc7ad6d --- /dev/null +++ b/vlib/v/fmt/tests/struct_decl_with_comments_keep.vv @@ -0,0 +1,13 @@ +module main + +fn main() { +} + +pub struct OperateInfo { // implements IperateInfo +pub mut: + title string // title + // msg + msg string + // id + id string +} // operate info diff --git a/vlib/v/fmt/tests/structs_expected.vv b/vlib/v/fmt/tests/structs_expected.vv index ca3fb0cab9..b3d7339d96 100644 --- a/vlib/v/fmt/tests/structs_expected.vv +++ b/vlib/v/fmt/tests/structs_expected.vv @@ -37,8 +37,8 @@ fn new_user() User { } struct SomeStruct { -mut: // 1 +mut: // 2 // 3 somefield /* 4 */ /* 5 */ int // 6 diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 86291a7b06..6620636bf5 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -105,9 +105,11 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { mut is_field_pub := false mut is_field_global := false mut last_line := p.prev_tok.pos().line_nr + 1 + mut pre_comments := []ast.Comment{} mut end_comments := []ast.Comment{} if !no_body { p.check(.lcbr) + pre_comments = p.eat_comments() mut i := 0 for p.tok.kind != .rcbr { mut comments := []ast.Comment{} @@ -118,7 +120,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { } } if p.tok.kind == .rcbr { - end_comments = comments.clone() + end_comments = p.eat_comments(same_line: true) break } if p.tok.kind == .key_pub { @@ -265,7 +267,6 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { } } // Comments after type (same line) - comments << p.eat_comments() prev_attrs := p.attrs p.attrs = [] if p.tok.kind == .lsbr { @@ -279,6 +280,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { } p.inside_struct_attr_decl = false } + comments << p.eat_comments() mut default_expr := ast.empty_expr mut has_default_expr := false if !is_embed { @@ -338,6 +340,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { p.top_level_statement_end() last_line = p.tok.line_nr p.check(.rcbr) + end_comments = p.eat_comments(same_line: true) } is_minify := attrs.contains('minify') mut sym := ast.TypeSymbol{ @@ -388,6 +391,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { language: language is_union: is_union attrs: if is_anon { []ast.Attr{} } else { attrs } // anon structs can't have attributes + pre_comments: pre_comments end_comments: end_comments generic_types: generic_types embeds: embeds