From 46e7e27ba35f94e3038378051f69eb06e4c7d27a Mon Sep 17 00:00:00 2001 From: Lukas Neubert Date: Fri, 9 Apr 2021 12:22:14 +0200 Subject: [PATCH] v vet: give an error for trailing whitespace (#9574) --- cmd/tools/test_os_process.v | 2 +- cmd/tools/vtest-cleancode.v | 7 +++++-- cmd/tools/vvet/tests/trailing_space.out | 7 +++++++ cmd/tools/vvet/tests/trailing_space.vv | 16 +++++++++++++++ cmd/tools/vvet/vvet.v | 2 ++ vlib/v/gen/c/cheaders.v | 8 ++++---- vlib/v/parser/parser.v | 27 ++++++++++++++++--------- vlib/v/parser/pratt.v | 3 ++- vlib/v/scanner/scanner.v | 1 + vlib/v/vet/vet.v | 8 ++++++++ vlib/x/ttf/text_block.v | 2 +- vlib/x/ttf/ttf.v | 4 ++-- 12 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 cmd/tools/vvet/tests/trailing_space.out create mode 100644 cmd/tools/vvet/tests/trailing_space.vv diff --git a/cmd/tools/test_os_process.v b/cmd/tools/test_os_process.v index 31de3e0551..4fb446f47b 100644 --- a/cmd/tools/test_os_process.v +++ b/cmd/tools/test_os_process.v @@ -54,7 +54,7 @@ fn main() { if '-h' in args || '--help' in args { println("Usage: test_os_process [-v] [-h] [-target stderr/stdout/both/alternate] [-exitcode 0] [-timeout_ms 200] [-period_ms 50] - Prints lines periodically (-period_ms), to stdout/stderr (-target). + Prints lines periodically (-period_ms), to stdout/stderr (-target). After a while (-timeout_ms), exit with (-exitcode). This program is useful for platform independent testing of child process/standart input/output control. diff --git a/cmd/tools/vtest-cleancode.v b/cmd/tools/vtest-cleancode.v index 07cafa5e8d..92a0f646ec 100644 --- a/cmd/tools/vtest-cleancode.v +++ b/cmd/tools/vtest-cleancode.v @@ -5,7 +5,9 @@ import testing import v.util const ( - vet_known_failing_exceptions = []string{} + vet_known_failing_exceptions = [ + 'vlib/v/gen/js/js.v' /* trailing space */, + ] vet_folders = [ 'vlib/sqlite', 'vlib/v', @@ -115,7 +117,8 @@ fn tsession(vargs string, tool_source string, tool_cmd string, tool_args string, } fn v_test_vetting(vargs string) { - vet_session := tsession(vargs, 'vvet', 'v vet', 'vet', vet_folders, vet_known_failing_exceptions) + expanded_vet_list := util.find_all_v_files(vet_folders) or { return } + vet_session := tsession(vargs, 'vvet', 'v vet', 'vet', expanded_vet_list, vet_known_failing_exceptions) fmt_cmd, fmt_args := if is_fix { 'v fmt -w', 'fmt -w' } else { 'v fmt -verify', 'fmt -verify' } expanded_vfmt_list := util.find_all_v_files(vfmt_verify_list) or { return } verify_session := tsession(vargs, 'vfmt.v', fmt_cmd, fmt_args, expanded_vfmt_list, diff --git a/cmd/tools/vvet/tests/trailing_space.out b/cmd/tools/vvet/tests/trailing_space.out new file mode 100644 index 0000000000..1899a21459 --- /dev/null +++ b/cmd/tools/vvet/tests/trailing_space.out @@ -0,0 +1,7 @@ +cmd/tools/vvet/tests/trailing_space.vv:5: error: Looks like you have trailing whitespace. +cmd/tools/vvet/tests/trailing_space.vv:6: error: Looks like you have trailing whitespace. +cmd/tools/vvet/tests/trailing_space.vv:7: error: Looks like you have trailing whitespace. +cmd/tools/vvet/tests/trailing_space.vv:8: error: Looks like you have trailing whitespace. +cmd/tools/vvet/tests/trailing_space.vv:9: error: Looks like you have trailing whitespace. +cmd/tools/vvet/tests/trailing_space.vv:13: error: Looks like you have trailing whitespace. +cmd/tools/vvet/tests/trailing_space.vv:15: error: Looks like you have trailing whitespace. diff --git a/cmd/tools/vvet/tests/trailing_space.vv b/cmd/tools/vvet/tests/trailing_space.vv new file mode 100644 index 0000000000..4fe733ec56 --- /dev/null +++ b/cmd/tools/vvet/tests/trailing_space.vv @@ -0,0 +1,16 @@ +// NB: This file has and *should* have trailing spaces. +// When making changes, please ensure they are not removed. + +fn after_comments() { + // spaces after line comments give errors + /* + in block comments + too + */ +} + +fn main() { + var := 'error about the spaces right there' + no_err := "inside multi line strings it's fine. +but not after" +} diff --git a/cmd/tools/vvet/vvet.v b/cmd/tools/vvet/vvet.v index b01fa5c7d4..9841ed707d 100644 --- a/cmd/tools/vvet/vvet.v +++ b/cmd/tools/vvet/vvet.v @@ -229,6 +229,7 @@ fn (mut vt Vet) error(msg string, line int, fix vet.FixKind) { pos: pos kind: .error fix: fix + typ: .default } } @@ -242,6 +243,7 @@ fn (mut vt Vet) warn(msg string, line int, fix vet.FixKind) { pos: pos kind: .warning fix: fix + typ: .default } if vt.opt.is_werror { w.kind = .error diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index ab0c70c9bf..8699278523 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -352,13 +352,13 @@ void _vcleanup(); //protections that produce different results: //1: normal valid behavior //2: extra protection against entropy loss (probability=2^-63), aka. "blind multiplication" -#define WYHASH_CONDOM 1 +#define WYHASH_CONDOM 1 #endif #ifndef WYHASH_32BIT_MUM //0: normal version, slow on 32 bit systems //1: faster on 32 bit systems but produces different results, incompatible with wy2u0k function -#define WYHASH_32BIT_MUM 0 +#define WYHASH_32BIT_MUM 0 #endif //includes @@ -389,7 +389,7 @@ static inline void _wymum(uint64_t *A, uint64_t *B){ *A=_wyrot(hl)^hh; *B=_wyrot(lh)^ll; #endif #elif defined(__SIZEOF_INT128__) - __uint128_t r=*A; r*=*B; + __uint128_t r=*A; r*=*B; #if(WYHASH_CONDOM>1) *A^=(uint64_t)r; *B^=(uint64_t)(r>>64); #else @@ -461,7 +461,7 @@ static inline uint64_t wyhash(const void *key, size_t len, uint64_t seed, const else a=b=0; } else{ - size_t i=len; + size_t i=len; if(_unlikely_(i>48)){ uint64_t see1=seed, see2=seed; do{ diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 446f5fc3e5..3d860c0c86 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -207,12 +207,16 @@ pub fn parse_vet_file(path string, table_ &ast.Table, pref &pref.Preferences) (a global_scope: global_scope } p.set_path(path) - if p.scanner.text.contains('\n ') { + if p.scanner.text.contains_any_substr(['\n ', ' \n']) { source_lines := os.read_lines(path) or { []string{} } for lnumber, line in source_lines { if line.starts_with(' ') { p.vet_error('Looks like you are using spaces for indentation.', lnumber, - .vfmt) + .vfmt, .space_indent) + } + if line.ends_with(' ') { + p.vet_error('Looks like you have trailing whitespace.', lnumber, .unknown, + .trailing_space) } } } @@ -617,10 +621,10 @@ pub fn (mut p Parser) comment() ast.Comment { pos.last_line = pos.line_nr + text.count('\n') p.next() is_multi := text.contains('\n') - // Filter out space indentation vet errors inside block comments + // 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.pos.line_nr - 1 > pos.line_nr - && it.pos.line_nr - 1 <= pos.last_line)) + 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 @@ -1648,7 +1652,7 @@ pub fn (mut p Parser) note_with_pos(s string, pos token.Position) { } } -pub fn (mut p Parser) vet_error(msg string, line int, fix vet.FixKind) { +pub fn (mut p Parser) vet_error(msg string, line int, fix vet.FixKind, typ vet.ErrorType) { pos := token.Position{ line_nr: line + 1 } @@ -1658,6 +1662,7 @@ pub fn (mut p Parser) vet_error(msg string, line int, fix vet.FixKind) { pos: pos kind: .error fix: fix + typ: typ } } @@ -2339,9 +2344,13 @@ 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() - if p.vet_errors.len > 0 && val.contains('\n ') { - p.vet_errors = p.vet_errors.filter(!(it.pos.line_nr > pos.line_nr - 1 - && it.pos.line_nr <= pos.last_line - 1)) + // 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)) } node = ast.StringLiteral{ val: val diff --git a/vlib/v/parser/pratt.v b/vlib/v/parser/pratt.v index 268f232a61..f98e469d86 100644 --- a/vlib/v/parser/pratt.v +++ b/vlib/v/parser/pratt.v @@ -447,7 +447,8 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr { p.expecting_type = prev_expecting_type if p.pref.is_vet && op in [.key_in, .not_in] && right is ast.ArrayInit && (right as ast.ArrayInit).exprs.len == 1 { - p.vet_error('Use `var == value` instead of `var in [value]`', pos.line_nr, vet.FixKind.vfmt) + p.vet_error('Use `var == value` instead of `var in [value]`', pos.line_nr, vet.FixKind.vfmt, + .default) } mut or_stmts := []ast.Stmt{} mut or_kind := ast.OrKind.absent diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 3812ffef3b..0426e3e405 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -1376,6 +1376,7 @@ fn (mut s Scanner) vet_error(msg string, fix vet.FixKind) { } kind: .error fix: fix + typ: .default } s.vet_errors << ve } diff --git a/vlib/v/vet/vet.v b/vlib/v/vet/vet.v index 0c11132d13..7d16c18817 100644 --- a/vlib/v/vet/vet.v +++ b/vlib/v/vet/vet.v @@ -15,6 +15,13 @@ pub enum FixKind { vfmt } +// ErrorType is used to filter out false positive errors under specific conditions +pub enum ErrorType { + default + space_indent + trailing_space +} + pub struct Error { pub mut: kind ErrorKind [required] @@ -25,4 +32,5 @@ pub: file_path string // file where the error have origin pos token.Position // position in the file fix FixKind [required] + typ ErrorType [required] } diff --git a/vlib/x/ttf/text_block.v b/vlib/x/ttf/text_block.v index dce46ff62d..e43dde0ca0 100644 --- a/vlib/x/ttf/text_block.v +++ b/vlib/x/ttf/text_block.v @@ -10,7 +10,7 @@ module ttf * * Note: * -* TODO: +* TODO: **********************************************************************/ pub struct Text_block { x int // x postion of the left high corner diff --git a/vlib/x/ttf/ttf.v b/vlib/x/ttf/ttf.v index ed619c66db..5f88b38653 100644 --- a/vlib/x/ttf/ttf.v +++ b/vlib/x/ttf/ttf.v @@ -9,9 +9,9 @@ module ttf * that can be found in the LICENSE file. * * Note: -* - inspired by: http://stevehanov.ca/blog/?id=143 +* - inspired by: http://stevehanov.ca/blog/?id=143 * -* TODO: +* TODO: * - check for unicode > 0xFFFF if supported * - evaluate use a buffer for the points in the glyph **********************************************************************/