From f879368466401e206d9153dd7dca235748fcd539 Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 15 Aug 2024 13:51:06 +0800 Subject: [PATCH] fmt: fix interface fields or methods with empty newlines (#22046) --- ...=> interface_with_empty_newline_1_keep.vv} | 0 .../interface_with_empty_newline_2_keep.vv | 18 +++++++++++++++ vlib/v/parser/parser.v | 22 ++++++++++++++++++- vlib/v/parser/struct.v | 12 +++++----- 4 files changed, 45 insertions(+), 7 deletions(-) rename vlib/v/fmt/tests/{interface_with_empty_newline_keep.vv => interface_with_empty_newline_1_keep.vv} (100%) create mode 100644 vlib/v/fmt/tests/interface_with_empty_newline_2_keep.vv diff --git a/vlib/v/fmt/tests/interface_with_empty_newline_keep.vv b/vlib/v/fmt/tests/interface_with_empty_newline_1_keep.vv similarity index 100% rename from vlib/v/fmt/tests/interface_with_empty_newline_keep.vv rename to vlib/v/fmt/tests/interface_with_empty_newline_1_keep.vv diff --git a/vlib/v/fmt/tests/interface_with_empty_newline_2_keep.vv b/vlib/v/fmt/tests/interface_with_empty_newline_2_keep.vv new file mode 100644 index 000000000..e4798dba6 --- /dev/null +++ b/vlib/v/fmt/tests/interface_with_empty_newline_2_keep.vv @@ -0,0 +1,18 @@ +interface Foo { + // a + a string + + bb int + ccc bool + + // m1, m2 + m1() string + m2() int + + // m3.1 + // m3.2 + m3() bool +} + +fn main() { +} diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 5af9e4ede..6f168df22 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -501,6 +501,26 @@ fn (p &Parser) is_fn_type_decl() bool { return true } +fn (p &Parser) has_prev_newline() bool { + mut tok := p.tok + mut prev_tok := p.prev_tok + mut idx := -1 + + for { + if tok.line_nr - prev_tok.line_nr - prev_tok.lit.count('\n') > 1 { + return true + } + if prev_tok.kind == .comment { + idx-- + tok = prev_tok + prev_tok = p.peek_token(idx) + continue + } + break + } + return false +} + fn (p &Parser) is_array_type() bool { mut i := 1 mut tok := p.tok @@ -4103,7 +4123,7 @@ fn (mut p Parser) enum_decl() ast.EnumDecl { mut enum_attrs := map[string][]ast.Attr{} for p.tok.kind != .eof && p.tok.kind != .rcbr { pos := p.tok.pos() - has_prev_newline := p.tok.line_nr - p.prev_tok.line_nr - p.prev_tok.lit.count('\n') > 1 + has_prev_newline := p.has_prev_newline() val := p.check_name() vals << val mut expr := ast.empty_expr diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 1fb8280d2..f1d676778 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -186,7 +186,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { && (p.peek_tok.kind != .lsbr || p.peek_token(2).kind != .rsbr)) || p.peek_tok.kind == .dot) && language == .v && p.peek_tok.kind != .key_fn is_on_top := ast_fields.len == 0 && !(is_field_pub || is_field_mut || is_field_global) - has_prev_newline := p.tok.line_nr - p.prev_tok.line_nr - p.prev_tok.lit.count('\n') > 1 + has_prev_newline := p.has_prev_newline() mut field_name := '' mut typ := ast.Type(0) mut type_pos := token.Pos{} @@ -447,7 +447,7 @@ fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option has_update_expr = true } else { first_field_pos = p.tok.pos() - has_prev_newline = p.tok.line_nr - p.prev_tok.line_nr - p.prev_tok.lit.count('\n') > 1 + has_prev_newline = p.has_prev_newline() field_name = p.check_name() p.check(.colon) expr = p.expr(0) @@ -654,7 +654,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { mut comments := p.eat_comments() if p.peek_tok.kind == .lpar { method_start_pos := p.tok.pos() - has_prev_newline := p.tok.line_nr - p.prev_tok.line_nr - p.prev_tok.lit.count('\n') > 1 + has_prev_newline := p.has_prev_newline() line_nr := p.tok.line_nr name := p.check_name() @@ -696,7 +696,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { method.pos = method.pos.extend(method.return_type_pos) } comments << p.eat_comments(same_line: true) - mnext_comments := p.eat_comments() + mnext_comments := p.eat_comments(follow_up: true) method.comments = comments method.next_comments = mnext_comments methods << method @@ -715,12 +715,12 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { } else { // interface fields field_pos := p.tok.pos() - has_prev_newline := p.tok.line_nr - p.prev_tok.line_nr - p.prev_tok.lit.count('\n') > 1 + has_prev_newline := p.has_prev_newline() field_name := p.check_name() mut type_pos := p.tok.pos() field_typ := p.parse_type() type_pos = type_pos.extend(p.prev_tok.pos()) - comments << p.eat_comments() + comments << p.eat_comments(follow_up: true) fields << ast.StructField{ name: field_name pos: field_pos -- 2.39.5