From 9f6ddb4c219a369d7518514ffd7d3ece2896f900 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Fri, 18 Jun 2021 15:47:26 +0300 Subject: [PATCH] v.fmt: add an independent Comment.is_inline flag. Use it for fixing `[ .. //x ]` => `[ .. //x, ]` --- cmd/tools/vast/vast.v | 2 +- cmd/tools/vtest-cleancode.v | 1 - vlib/net/http/cookie_test.v | 2 +- vlib/v/ast/ast.v | 8 +++--- vlib/v/fmt/fmt.v | 28 ++++++++++++++----- .../tests/array_init_comment_ending_keep.vv | 23 +++++++++++++++ vlib/v/parser/parser.v | 9 ++++-- 7 files changed, 56 insertions(+), 17 deletions(-) create mode 100644 vlib/v/fmt/tests/array_init_comment_ending_keep.vv diff --git a/cmd/tools/vast/vast.v b/cmd/tools/vast/vast.v index f630fff808..b67b4328b0 100644 --- a/cmd/tools/vast/vast.v +++ b/cmd/tools/vast/vast.v @@ -438,7 +438,7 @@ fn (t Tree) comment(node ast.Comment) &Node { obj.add('ast_type', t.string_node('Comment')) obj.add('text', t.string_node(node.text)) obj.add('is_multi', t.bool_node(node.is_multi)) - obj.add('line_nr', t.number_node(node.line_nr)) + obj.add('is_inline', t.bool_node(node.is_inline)) obj.add('pos', t.position(node.pos)) return obj } diff --git a/cmd/tools/vtest-cleancode.v b/cmd/tools/vtest-cleancode.v index 4387bf40ba..1770b8dc66 100644 --- a/cmd/tools/vtest-cleancode.v +++ b/cmd/tools/vtest-cleancode.v @@ -44,7 +44,6 @@ const ( ] vfmt_known_failing_exceptions = arrays.merge(verify_known_failing_exceptions, [ 'vlib/strconv/' /* prevent conflicts, till the new pure V string interpolation is merged */, - 'vlib/net/http/cookie_test.v' /* a very weird bug where `,` keeps on being added in comments */, 'vlib/term/ui/input.v' /* comment after a struct embed is removed */, 'vlib/regex/regex_test.v' /* contains meaningfull formatting of the test case data */, 'vlib/readline/readline_test.v' /* vfmt eats `{ Readline }` from `import readline { Readline }` */, diff --git a/vlib/net/http/cookie_test.v b/vlib/net/http/cookie_test.v index 5fd3da2dfb..3806618fb8 100644 --- a/vlib/net/http/cookie_test.v +++ b/vlib/net/http/cookie_test.v @@ -443,7 +443,7 @@ const ( }, ] } - // TODO(bradfitz): users have reported seeing this in the,, + // TODO(bradfitz): users have reported seeing this in the // wild, but do browsers handle it? RFC 6265 just says "don't // do that" (section 3) and then never mentions header folding // again. diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 3d50dcdfd1..9cf2daa0d9 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1382,10 +1382,10 @@ pub mut: pub struct Comment { pub: - text string - is_multi bool - line_nr int - pos token.Position + text string + is_multi bool // true only for /* comment */, that use many lines + is_inline bool // true for all /* comment */ comments + pos token.Position } pub struct ConcatExpr { diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 8b9f8e0e6c..15fbd0a08d 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -26,7 +26,7 @@ pub mut: buffering bool // disables line wrapping for exprs that will be analyzed later par_level int // how many parentheses are put around the current expression array_init_break []bool // line breaks after elements in hierarchy level of multi dimensional array - array_init_depth int // current level of hierarchie in array init + array_init_depth int // current level of hierarchy in array init single_line_if bool cur_mod string file ast.File @@ -1500,12 +1500,21 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) { } f.expr(expr) } - if i < node.ecmnts.len && node.ecmnts[i].len > 0 { + mut last_comment_was_inline := false + mut has_comments := node.ecmnts[i].len > 0 + if i < node.ecmnts.len && has_comments { expr_pos := expr.position() - for cmt in node.ecmnts[i] { + for icmt, cmt in node.ecmnts[i] { if !set_comma && cmt.pos.pos > expr_pos.pos + expr_pos.len + 2 { - f.write(',') - set_comma = true + if icmt > 0 { + if last_comment_was_inline { + f.write(',') + set_comma = true + } + } else { + f.write(',') // first comment needs a comma + set_comma = true + } } if cmt.pos.line_nr > expr_pos.last_line { embed := i + 1 < node.exprs.len @@ -1516,16 +1525,21 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) { f.write(' ') f.comment(cmt, iembed: true) } + last_comment_was_inline = cmt.is_inline } } + mut put_comma := !set_comma + if has_comments && !last_comment_was_inline { + put_comma = false + } if i == node.exprs.len - 1 { if is_new_line { - if !set_comma { + if put_comma { f.write(',') } f.writeln('') } - } else if !set_comma { + } else if put_comma { f.write(',') } last_line_nr = pos.last_line diff --git a/vlib/v/fmt/tests/array_init_comment_ending_keep.vv b/vlib/v/fmt/tests/array_init_comment_ending_keep.vv new file mode 100644 index 0000000000..a3932a503f --- /dev/null +++ b/vlib/v/fmt/tests/array_init_comment_ending_keep.vv @@ -0,0 +1,23 @@ +import net.http + +const ( + write_set_cookie_tests = [ + ReadSetCookiesTestCase{ + header: map{ + 'Set-Cookie': ['special-7=","'] + } + cookies: [ + &http.Cookie{ + name: 'special-7' + value: ',' + raw: 'special-8=","' + }, + ] + } + // TODO(bradfitz): users have reported seeing this in the + // wild, but do browsers handle it? RFC 6265 just says "don't + // do that" (section 3) and then never mentions header folding + // again. + // Header{"Set-Cookie": ["ASP.NET_SessionId=foo; path=/; HttpOnly, .ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"]}, + ] +) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 8cb46be4d0..34a9069bf2 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -605,17 +605,20 @@ pub fn (mut p Parser) check_comment() ast.Comment { pub fn (mut p Parser) comment() ast.Comment { mut pos := p.tok.position() text := p.tok.lit - pos.last_line = pos.line_nr + text.count('\n') + num_newlines := text.count('\n') + is_multi := num_newlines > 0 + is_inline := text.len + 4 == p.tok.len // 4: `/` `*` `*` `/` + pos.last_line = pos.line_nr + num_newlines p.next() - is_multi := text.contains('\n') // Filter out false positive space indent vet errors inside comments if p.vet_errors.len > 0 && is_multi { p.vet_errors = p.vet_errors.filter(it.typ != .space_indent || it.pos.line_nr - 1 > pos.last_line || it.pos.line_nr - 1 <= pos.line_nr) } return ast.Comment{ - is_multi: is_multi text: text + is_multi: is_multi + is_inline: is_inline pos: pos } }