From b2c16ced5758a5c0c30a45f65fbafebfe33374e8 Mon Sep 17 00:00:00 2001 From: Lukas Neubert Date: Mon, 12 Apr 2021 15:03:22 +0200 Subject: [PATCH] parser: filter out vet space indent errors inside StringInterLiterals (#9695) --- cmd/tools/vvet/tests/indent_with_space.out | 5 +++-- cmd/tools/vvet/tests/indent_with_space.vv | 4 ++++ vlib/v/parser/parser.v | 24 ++++++++++++++-------- vlib/v/scanner/scanner.v | 7 +++++-- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/cmd/tools/vvet/tests/indent_with_space.out b/cmd/tools/vvet/tests/indent_with_space.out index 7db901faca..b307e208f2 100644 --- a/cmd/tools/vvet/tests/indent_with_space.out +++ b/cmd/tools/vvet/tests/indent_with_space.out @@ -1,5 +1,6 @@ cmd/tools/vvet/tests/indent_with_space.vv:2: error: Looks like you are using spaces for indentation. cmd/tools/vvet/tests/indent_with_space.vv:10: error: Looks like you are using spaces for indentation. -cmd/tools/vvet/tests/indent_with_space.vv:16: error: Looks like you are using spaces for indentation. -cmd/tools/vvet/tests/indent_with_space.vv:19: error: Looks like you are using spaces for indentation. +cmd/tools/vvet/tests/indent_with_space.vv:17: error: Looks like you are using spaces for indentation. +cmd/tools/vvet/tests/indent_with_space.vv:20: error: Looks like you are using spaces for indentation. +cmd/tools/vvet/tests/indent_with_space.vv:22: error: Looks like you are using spaces for indentation. NB: You can run `v fmt -w file.v` to fix these errors automatically diff --git a/cmd/tools/vvet/tests/indent_with_space.vv b/cmd/tools/vvet/tests/indent_with_space.vv index c392568e49..9b466ef4b8 100644 --- a/cmd/tools/vvet/tests/indent_with_space.vv +++ b/cmd/tools/vvet/tests/indent_with_space.vv @@ -13,8 +13,12 @@ fn block_comments() { } fn space_inside_strings() { + // Plain strings str := "Bad space usage for variable indentation. Here it's fine. Here too." str2 := 'linebreak and space\n inside' + // String interpolation + si1 := 'Error here $foo + and not here' } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 08955a3905..642a5586db 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -2322,6 +2322,17 @@ fn (mut p Parser) enum_val() ast.EnumVal { } } +fn (mut p Parser) filter_string_vet_errors(pos token.Position) { + if p.vet_errors.len == 0 { + return + } + p.vet_errors = p.vet_errors.filter( + (it.typ == .trailing_space && it.pos.line_nr - 1 >= pos.last_line) + || (it.typ != .trailing_space && it.pos.line_nr - 1 > pos.last_line) + || (it.typ == .space_indent && it.pos.line_nr - 1 <= pos.line_nr) + || (it.typ != .space_indent && it.pos.line_nr - 1 < pos.line_nr)) +} + fn (mut p Parser) string_expr() ast.Expr { is_raw := p.tok.kind == .name && p.tok.lit == 'r' is_cstr := p.tok.kind == .name && p.tok.lit == 'c' @@ -2334,14 +2345,7 @@ fn (mut p Parser) string_expr() ast.Expr { pos.last_line = pos.line_nr + val.count('\n') if p.peek_tok.kind != .str_dollar { p.next() - // Filter out false positive vet errors inside strings - if p.vet_errors.len > 0 { - p.vet_errors = p.vet_errors.filter( - (it.typ == .trailing_space && it.pos.line_nr - 1 >= pos.last_line) - || (it.typ != .trailing_space && it.pos.line_nr - 1 > pos.last_line) - || (it.typ == .space_indent && it.pos.line_nr - 1 <= pos.line_nr) - || (it.typ != .space_indent && it.pos.line_nr - 1 < pos.line_nr)) - } + p.filter_string_vet_errors(pos) node = ast.StringLiteral{ val: val is_raw: is_raw @@ -2420,6 +2424,8 @@ fn (mut p Parser) string_expr() ast.Expr { fills << fill fposs << p.prev_tok.position() } + pos = pos.extend(p.prev_tok.position()) + p.filter_string_vet_errors(pos) node = ast.StringInterLiteral{ vals: vals exprs: exprs @@ -2430,7 +2436,7 @@ fn (mut p Parser) string_expr() ast.Expr { fills: fills fmts: fmts fmt_poss: fposs - pos: pos.extend(p.prev_tok.position()) + pos: pos } // need_fmts: prelimery - until checker finds out if really needed p.inside_str_interp = false diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 0426e3e405..3affa24830 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -1094,9 +1094,12 @@ fn (mut s Scanner) ident_string() string { // } mut n_cr_chars := 0 mut start := s.pos - if s.text[start] == s.quote - || (s.text[start] == s.inter_quote && (s.is_inter_start || s.is_enclosed_inter)) { + start_char := s.text[start] + if start_char == s.quote + || (start_char == s.inter_quote && (s.is_inter_start || s.is_enclosed_inter)) { start++ + } else if start_char == `\n` { + s.inc_line_number() } s.is_inside_string = false mut u_escapes_pos := []int{} // pos list of \uXXXX