From 8f315d226b98001184aed5136fbb64ba2f9116a8 Mon Sep 17 00:00:00 2001 From: Larpon Date: Sat, 9 Jan 2021 15:11:49 +0100 Subject: [PATCH] vvet: move to own subdir, prepare richer suggestions (#7989) --- cmd/tools/vbuild-tools.v | 2 +- cmd/tools/vtest-cleancode.v | 3 ++- cmd/tools/vvet/tests/array_init_one_val.out | 2 ++ .../tools/vvet}/tests/array_init_one_val.vv | 0 cmd/tools/vvet/tests/indent_with_space.out | 2 ++ .../tools/vvet}/tests/indent_with_space.vv | 0 cmd/tools/vvet/tests/parens_space_a.out | 2 ++ .../tools/vvet}/tests/parens_space_a.vv | 0 cmd/tools/vvet/tests/parens_space_b.out | 2 ++ .../tools/vvet}/tests/parens_space_b.vv | 0 {vlib/v/vet => cmd/tools/vvet}/vet_test.v | 2 +- cmd/tools/{ => vvet}/vvet.v | 16 +++++++++---- vlib/v/parser/parser.v | 21 +++++++++++++---- vlib/v/parser/pratt.v | 3 ++- vlib/v/scanner/scanner.v | 20 ++++++++++++---- vlib/v/vet/tests/array_init_one_val.out | 2 -- vlib/v/vet/tests/indent_with_space.out | 2 -- vlib/v/vet/tests/parens_space_a.out | 2 -- vlib/v/vet/tests/parens_space_b.out | 2 -- vlib/v/vet/vet.v | 23 ++++++++++++++++--- 20 files changed, 76 insertions(+), 30 deletions(-) create mode 100644 cmd/tools/vvet/tests/array_init_one_val.out rename {vlib/v/vet => cmd/tools/vvet}/tests/array_init_one_val.vv (100%) create mode 100644 cmd/tools/vvet/tests/indent_with_space.out rename {vlib/v/vet => cmd/tools/vvet}/tests/indent_with_space.vv (100%) create mode 100644 cmd/tools/vvet/tests/parens_space_a.out rename {vlib/v/vet => cmd/tools/vvet}/tests/parens_space_a.vv (100%) create mode 100644 cmd/tools/vvet/tests/parens_space_b.out rename {vlib/v/vet => cmd/tools/vvet}/tests/parens_space_b.vv (100%) rename {vlib/v/vet => cmd/tools/vvet}/vet_test.v (97%) rename cmd/tools/{ => vvet}/vvet.v (79%) delete mode 100644 vlib/v/vet/tests/array_init_one_val.out delete mode 100644 vlib/v/vet/tests/indent_with_space.out delete mode 100644 vlib/v/vet/tests/parens_space_a.out delete mode 100644 vlib/v/vet/tests/parens_space_b.out diff --git a/cmd/tools/vbuild-tools.v b/cmd/tools/vbuild-tools.v index 8c487cfd0a..ded3eb18f4 100644 --- a/cmd/tools/vbuild-tools.v +++ b/cmd/tools/vbuild-tools.v @@ -11,7 +11,7 @@ import v.util // should be compiled (v folder). // To implement that, these folders are initially skipped, then added // as a whole *after the testing.prepare_test_session call*. -const tools_in_subfolders = ['vdoc'] +const tools_in_subfolders = ['vdoc', 'vvet'] // non_packaged_tools are tools that should not be packaged with // prebuild versions of V, to keep the size smaller. diff --git a/cmd/tools/vtest-cleancode.v b/cmd/tools/vtest-cleancode.v index d50c9443f9..630506c0d7 100644 --- a/cmd/tools/vtest-cleancode.v +++ b/cmd/tools/vtest-cleancode.v @@ -20,6 +20,7 @@ const ( vfmt_verify_list = [ 'cmd/v/v.v', 'cmd/tools/vdoc/', + 'cmd/tools/vvet/', 'vlib/arrays/', 'vlib/benchmark/', 'vlib/bitfield/', @@ -92,7 +93,7 @@ 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', 'v vet', 'vet', vet_folders, vet_known_failing_exceptions) + vet_session := tsession(vargs, 'vvet', 'v vet', 'vet', vet_folders, vet_known_failing_exceptions) verify_session := tsession(vargs, 'vfmt.v', 'v fmt -verify', 'fmt -verify', vfmt_verify_list, verify_known_failing_exceptions) // diff --git a/cmd/tools/vvet/tests/array_init_one_val.out b/cmd/tools/vvet/tests/array_init_one_val.out new file mode 100644 index 0000000000..4b9c552af6 --- /dev/null +++ b/cmd/tools/vvet/tests/array_init_one_val.out @@ -0,0 +1,2 @@ +cmd/tools/vvet/tests/array_init_one_val.vv:2: Use `var == value` instead of `var in [value]` +NB: You can run `v fmt -w file.v` to fix these automatically diff --git a/vlib/v/vet/tests/array_init_one_val.vv b/cmd/tools/vvet/tests/array_init_one_val.vv similarity index 100% rename from vlib/v/vet/tests/array_init_one_val.vv rename to cmd/tools/vvet/tests/array_init_one_val.vv diff --git a/cmd/tools/vvet/tests/indent_with_space.out b/cmd/tools/vvet/tests/indent_with_space.out new file mode 100644 index 0000000000..782d40773c --- /dev/null +++ b/cmd/tools/vvet/tests/indent_with_space.out @@ -0,0 +1,2 @@ +cmd/tools/vvet/tests/indent_with_space.vv:2: Looks like you are using spaces for indentation. +NB: You can run `v fmt -w file.v` to fix these automatically diff --git a/vlib/v/vet/tests/indent_with_space.vv b/cmd/tools/vvet/tests/indent_with_space.vv similarity index 100% rename from vlib/v/vet/tests/indent_with_space.vv rename to cmd/tools/vvet/tests/indent_with_space.vv diff --git a/cmd/tools/vvet/tests/parens_space_a.out b/cmd/tools/vvet/tests/parens_space_a.out new file mode 100644 index 0000000000..6ae9fed8e1 --- /dev/null +++ b/cmd/tools/vvet/tests/parens_space_a.out @@ -0,0 +1,2 @@ +cmd/tools/vvet/tests/parens_space_a.vv:1: Looks like you are adding a space after `(` +NB: You can run `v fmt -w file.v` to fix these automatically diff --git a/vlib/v/vet/tests/parens_space_a.vv b/cmd/tools/vvet/tests/parens_space_a.vv similarity index 100% rename from vlib/v/vet/tests/parens_space_a.vv rename to cmd/tools/vvet/tests/parens_space_a.vv diff --git a/cmd/tools/vvet/tests/parens_space_b.out b/cmd/tools/vvet/tests/parens_space_b.out new file mode 100644 index 0000000000..c9a5194a5c --- /dev/null +++ b/cmd/tools/vvet/tests/parens_space_b.out @@ -0,0 +1,2 @@ +cmd/tools/vvet/tests/parens_space_b.vv:1: Looks like you are adding a space before `)` +NB: You can run `v fmt -w file.v` to fix these automatically diff --git a/vlib/v/vet/tests/parens_space_b.vv b/cmd/tools/vvet/tests/parens_space_b.vv similarity index 100% rename from vlib/v/vet/tests/parens_space_b.vv rename to cmd/tools/vvet/tests/parens_space_b.vv diff --git a/vlib/v/vet/vet_test.v b/cmd/tools/vvet/vet_test.v similarity index 97% rename from vlib/v/vet/vet_test.v rename to cmd/tools/vvet/vet_test.v index b5caf1203d..c4da78a07a 100644 --- a/vlib/v/vet/vet_test.v +++ b/cmd/tools/vvet/vet_test.v @@ -6,7 +6,7 @@ fn test_vet() { vexe := os.getenv('VEXE') vroot := os.dir(vexe) os.chdir(vroot) - test_dir := 'vlib/v/vet/tests' + test_dir := 'cmd/tools/vvet/tests' tests := get_tests_in_dir(test_dir) fails := check_path(vexe, test_dir, tests) assert fails == 0 diff --git a/cmd/tools/vvet.v b/cmd/tools/vvet/vvet.v similarity index 79% rename from cmd/tools/vvet.v rename to cmd/tools/vvet/vvet.v index 2edea73fd5..8c4a92017b 100644 --- a/cmd/tools/vvet.v +++ b/cmd/tools/vvet/vvet.v @@ -13,7 +13,7 @@ import os.cmdline struct VetOptions { is_verbose bool mut: - errors []string + errors []vet.Error } fn (vet_options &VetOptions) vprintln(s string) { @@ -34,7 +34,8 @@ fn main() { eprintln('File/folder $path does not exist') continue } - if path.ends_with('_test.v') || (path.contains('/tests/') && !path.contains('vlib/v/vet/')) { + if path.ends_with('_test.v') || + (path.contains('/tests/') && !path.contains('cmd/tools/vvet/tests/')) { eprintln('skipping $path') continue } @@ -56,10 +57,15 @@ fn main() { } } if vet_options.errors.len > 0 { - for err in vet_options.errors { - eprintln(err) + for err in vet_options.errors.filter(it.kind == .error) { + eprintln('$err.file_path:$err.pos.line_nr: $err.message') } eprintln('NB: You can run `v fmt -w file.v` to fix these automatically') + /* + for err in vet_options.errors.filter(it.kind == .warning) { + eprintln('$err.file_path:$err.pos.line_nr: err.message') + } + */ exit(1) } } @@ -70,6 +76,6 @@ fn (mut vet_options VetOptions) vet_file(path string) { table := table.new_table() vet_options.vprintln("vetting file '$path'...") file_ast, errors := parser.parse_vet_file(path, table, prefs) + // Transfer errors from scanner and parser vet_options.errors << errors - vet.vet(file_ast, table, true) } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index da599e440e..4ca3acc6e9 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -9,6 +9,7 @@ import v.token import v.table import v.pref import v.util +import v.vet import v.errors import os import runtime @@ -66,7 +67,7 @@ mut: expecting_type bool // `is Type`, expecting type errors []errors.Error warnings []errors.Warning - vet_errors []string + vet_errors []vet.Error cur_fn_name string in_generic_params bool // indicates if parsing between `<` and `>` of a method/function name_error bool // indicates if the token is not a name or the name is on another line @@ -160,7 +161,7 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment return p.parse() } -pub fn parse_vet_file(path string, table_ &table.Table, pref &pref.Preferences) (ast.File, []string) { +pub fn parse_vet_file(path string, table_ &table.Table, pref &pref.Preferences) (ast.File, []vet.Error) { global_scope := &ast.Scope{ parent: 0 } @@ -182,7 +183,8 @@ pub fn parse_vet_file(path string, table_ &table.Table, pref &pref.Preferences) 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) + p.vet_error('Looks like you are using spaces for indentation.', lnumber, + .vfmt) } } } @@ -953,8 +955,17 @@ pub fn (mut p Parser) warn_with_pos(s string, pos token.Position) { } } -pub fn (mut p Parser) vet_error(s string, line int) { - p.vet_errors << '$p.scanner.file_path:${line + 1}: $s' +pub fn (mut p Parser) vet_error(msg string, line int, fix vet.FixKind) { + pos := token.Position{ + line_nr: line + 1 + } + p.vet_errors << vet.Error{ + message: msg + file_path: p.scanner.file_path + pos: pos + kind: .error + fix: fix + } } fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt { diff --git a/vlib/v/parser/pratt.v b/vlib/v/parser/pratt.v index 5592b8f6e9..56873f8901 100644 --- a/vlib/v/parser/pratt.v +++ b/vlib/v/parser/pratt.v @@ -4,6 +4,7 @@ module parser import v.ast +import v.vet import v.table import v.token @@ -381,7 +382,7 @@ 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) + p.vet_error('Use `var == value` instead of `var in [value]`', pos.line_nr, vet.FixKind.vfmt) } 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 1e01d9bcbd..6c145e0a01 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -7,6 +7,7 @@ import os import v.token import v.pref import v.util +import v.vet import v.errors const ( @@ -46,9 +47,9 @@ pub mut: tidx int eofs int pref &pref.Preferences - vet_errors []string errors []errors.Error warnings []errors.Warning + vet_errors []vet.Error } /* @@ -690,14 +691,14 @@ fn (mut s Scanner) text_scan() token.Token { `(` { // TODO `$if vet {` for performance if s.pref.is_vet && s.text[s.pos + 1] == ` ` { - s.vet_error('Looks like you are adding a space after `(`') + s.vet_error('Looks like you are adding a space after `(`', .vfmt) } return s.new_token(.lpar, '', 1) } `)` { // TODO `$if vet {` for performance if s.pref.is_vet && s.text[s.pos - 1] == ` ` { - s.vet_error('Looks like you are adding a space before `)`') + s.vet_error('Looks like you are adding a space before `)`', .vfmt) } return s.new_token(.rpar, '', 1) } @@ -1259,8 +1260,17 @@ pub fn (mut s Scanner) error(msg string) { } } -fn (mut s Scanner) vet_error(msg string) { - s.vet_errors << '$s.file_path:$s.line_nr: $msg' +fn (mut s Scanner) vet_error(msg string, fix vet.FixKind) { + ve := vet.Error{ + message: msg + file_path: s.file_path + pos: token.Position{ + line_nr: s.line_nr + } + kind: .error + fix: fix + } + s.vet_errors << ve } pub fn verror(s string) { diff --git a/vlib/v/vet/tests/array_init_one_val.out b/vlib/v/vet/tests/array_init_one_val.out deleted file mode 100644 index e04de3162f..0000000000 --- a/vlib/v/vet/tests/array_init_one_val.out +++ /dev/null @@ -1,2 +0,0 @@ -vlib/v/vet/tests/array_init_one_val.vv:2: Use `var == value` instead of `var in [value]` -NB: You can run `v fmt -w file.v` to fix these automatically diff --git a/vlib/v/vet/tests/indent_with_space.out b/vlib/v/vet/tests/indent_with_space.out deleted file mode 100644 index 2087bcbe99..0000000000 --- a/vlib/v/vet/tests/indent_with_space.out +++ /dev/null @@ -1,2 +0,0 @@ -vlib/v/vet/tests/indent_with_space.vv:2: Looks like you are using spaces for indentation. -NB: You can run `v fmt -w file.v` to fix these automatically diff --git a/vlib/v/vet/tests/parens_space_a.out b/vlib/v/vet/tests/parens_space_a.out deleted file mode 100644 index 213a41e460..0000000000 --- a/vlib/v/vet/tests/parens_space_a.out +++ /dev/null @@ -1,2 +0,0 @@ -vlib/v/vet/tests/parens_space_a.vv:1: Looks like you are adding a space after `(` -NB: You can run `v fmt -w file.v` to fix these automatically diff --git a/vlib/v/vet/tests/parens_space_b.out b/vlib/v/vet/tests/parens_space_b.out deleted file mode 100644 index d96fbffd13..0000000000 --- a/vlib/v/vet/tests/parens_space_b.out +++ /dev/null @@ -1,2 +0,0 @@ -vlib/v/vet/tests/parens_space_b.vv:1: Looks like you are adding a space before `)` -NB: You can run `v fmt -w file.v` to fix these automatically diff --git a/vlib/v/vet/vet.v b/vlib/v/vet/vet.v index 2a7bf36dc2..7176379d19 100644 --- a/vlib/v/vet/vet.v +++ b/vlib/v/vet/vet.v @@ -2,8 +2,25 @@ // Use of this source code is governed by an MIT license that can be found in the LICENSE file. module vet -import v.ast -import v.table +import v.token -pub fn vet(file ast.File, table &table.Table, is_debug bool) { +pub enum ErrorKind { + error + warning +} + +pub enum FixKind { + unknown + vfmt +} + +pub struct Error { +pub: + // General message + message string [required] + details string // Details about how to resolve or fix the situation + file_path string // file where the error have origin + pos token.Position // position in the file + kind ErrorKind [required] + fix FixKind [required] }