vvet: move to own subdir, prepare richer suggestions (#7989)

pull/7990/head
Larpon 2021-01-09 15:11:49 +01:00 committed by GitHub
parent 7545ed4121
commit 8f315d226b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 76 additions and 30 deletions

View File

@ -11,7 +11,7 @@ import v.util
// should be compiled (v folder). // should be compiled (v folder).
// To implement that, these folders are initially skipped, then added // To implement that, these folders are initially skipped, then added
// as a whole *after the testing.prepare_test_session call*. // 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 // non_packaged_tools are tools that should not be packaged with
// prebuild versions of V, to keep the size smaller. // prebuild versions of V, to keep the size smaller.

View File

@ -20,6 +20,7 @@ const (
vfmt_verify_list = [ vfmt_verify_list = [
'cmd/v/v.v', 'cmd/v/v.v',
'cmd/tools/vdoc/', 'cmd/tools/vdoc/',
'cmd/tools/vvet/',
'vlib/arrays/', 'vlib/arrays/',
'vlib/benchmark/', 'vlib/benchmark/',
'vlib/bitfield/', '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) { 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_session := tsession(vargs, 'vfmt.v', 'v fmt -verify', 'fmt -verify', vfmt_verify_list,
verify_known_failing_exceptions) verify_known_failing_exceptions)
// //

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -6,7 +6,7 @@ fn test_vet() {
vexe := os.getenv('VEXE') vexe := os.getenv('VEXE')
vroot := os.dir(vexe) vroot := os.dir(vexe)
os.chdir(vroot) os.chdir(vroot)
test_dir := 'vlib/v/vet/tests' test_dir := 'cmd/tools/vvet/tests'
tests := get_tests_in_dir(test_dir) tests := get_tests_in_dir(test_dir)
fails := check_path(vexe, test_dir, tests) fails := check_path(vexe, test_dir, tests)
assert fails == 0 assert fails == 0

View File

@ -13,7 +13,7 @@ import os.cmdline
struct VetOptions { struct VetOptions {
is_verbose bool is_verbose bool
mut: mut:
errors []string errors []vet.Error
} }
fn (vet_options &VetOptions) vprintln(s string) { fn (vet_options &VetOptions) vprintln(s string) {
@ -34,7 +34,8 @@ fn main() {
eprintln('File/folder $path does not exist') eprintln('File/folder $path does not exist')
continue 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') eprintln('skipping $path')
continue continue
} }
@ -56,10 +57,15 @@ fn main() {
} }
} }
if vet_options.errors.len > 0 { if vet_options.errors.len > 0 {
for err in vet_options.errors { for err in vet_options.errors.filter(it.kind == .error) {
eprintln(err) eprintln('$err.file_path:$err.pos.line_nr: $err.message')
} }
eprintln('NB: You can run `v fmt -w file.v` to fix these automatically') 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) exit(1)
} }
} }
@ -70,6 +76,6 @@ fn (mut vet_options VetOptions) vet_file(path string) {
table := table.new_table() table := table.new_table()
vet_options.vprintln("vetting file '$path'...") vet_options.vprintln("vetting file '$path'...")
file_ast, errors := parser.parse_vet_file(path, table, prefs) file_ast, errors := parser.parse_vet_file(path, table, prefs)
// Transfer errors from scanner and parser
vet_options.errors << errors vet_options.errors << errors
vet.vet(file_ast, table, true)
} }

View File

@ -9,6 +9,7 @@ import v.token
import v.table import v.table
import v.pref import v.pref
import v.util import v.util
import v.vet
import v.errors import v.errors
import os import os
import runtime import runtime
@ -66,7 +67,7 @@ mut:
expecting_type bool // `is Type`, expecting type expecting_type bool // `is Type`, expecting type
errors []errors.Error errors []errors.Error
warnings []errors.Warning warnings []errors.Warning
vet_errors []string vet_errors []vet.Error
cur_fn_name string cur_fn_name string
in_generic_params bool // indicates if parsing between `<` and `>` of a method/function 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 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() 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{ global_scope := &ast.Scope{
parent: 0 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{} } source_lines := os.read_lines(path) or { []string{} }
for lnumber, line in source_lines { for lnumber, line in source_lines {
if line.starts_with(' ') { 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) { pub fn (mut p Parser) vet_error(msg string, line int, fix vet.FixKind) {
p.vet_errors << '$p.scanner.file_path:${line + 1}: $s' 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 { fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {

View File

@ -4,6 +4,7 @@
module parser module parser
import v.ast import v.ast
import v.vet
import v.table import v.table
import v.token import v.token
@ -381,7 +382,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
p.expecting_type = prev_expecting_type 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 == if p.pref.is_vet && op in [.key_in, .not_in] && right is ast.ArrayInit && (right as ast.ArrayInit).exprs.len ==
1 { 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_stmts := []ast.Stmt{}
mut or_kind := ast.OrKind.absent mut or_kind := ast.OrKind.absent

View File

@ -7,6 +7,7 @@ import os
import v.token import v.token
import v.pref import v.pref
import v.util import v.util
import v.vet
import v.errors import v.errors
const ( const (
@ -46,9 +47,9 @@ pub mut:
tidx int tidx int
eofs int eofs int
pref &pref.Preferences pref &pref.Preferences
vet_errors []string
errors []errors.Error errors []errors.Error
warnings []errors.Warning warnings []errors.Warning
vet_errors []vet.Error
} }
/* /*
@ -690,14 +691,14 @@ fn (mut s Scanner) text_scan() token.Token {
`(` { `(` {
// TODO `$if vet {` for performance // TODO `$if vet {` for performance
if s.pref.is_vet && s.text[s.pos + 1] == ` ` { 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) return s.new_token(.lpar, '', 1)
} }
`)` { `)` {
// TODO `$if vet {` for performance // TODO `$if vet {` for performance
if s.pref.is_vet && s.text[s.pos - 1] == ` ` { 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) 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) { fn (mut s Scanner) vet_error(msg string, fix vet.FixKind) {
s.vet_errors << '$s.file_path:$s.line_nr: $msg' 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) { pub fn verror(s string) {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -2,8 +2,25 @@
// Use of this source code is governed by an MIT license that can be found in the LICENSE file. // Use of this source code is governed by an MIT license that can be found in the LICENSE file.
module vet module vet
import v.ast import v.token
import v.table
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]
} }