diff --git a/cmd/tools/vvet.v b/cmd/tools/vvet.v new file mode 100644 index 0000000000..72a62751a6 --- /dev/null +++ b/cmd/tools/vvet.v @@ -0,0 +1,38 @@ +// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license that can be found in the LICENSE file. +module main + +import v.vet +import v.ast +import v.pref +import v.parser +import v.util +import v.table +import os + +fn main() { + mut prefs := pref.new_preferences() + prefs.is_vet = true + table := table.new_table() + args := util.join_env_vflags_and_os_args() + if args.len < 3 { + return + } + path := args[2] + if path.ends_with('.v') { + vet_file(path, table, prefs) + } else if os.is_dir(path) { + println("vet'ing directory '$path'...") + files := os.walk_ext(path, '.v') + for file in files { + vet_file(file, table, prefs) + } + } +} + +fn vet_file(path string, table &table.Table, prefs &pref.Preferences) { + file_ast := parser.parse_file(path, table, .parse_comments, prefs, &ast.Scope{ + parent: 0 + }) + vet.vet(file_ast, table, true) +} diff --git a/cmd/v/v.v b/cmd/v/v.v index fc7d598cf1..bd21a5d051 100644 --- a/cmd/v/v.v +++ b/cmd/v/v.v @@ -11,7 +11,7 @@ import v.builder const ( simple_cmd = [ - 'fmt', 'up', + 'fmt', 'up', 'vet', 'self', 'symlink', 'bin2v', 'test', 'test-fmt', 'test-compiler', 'test-fixed', 'repl', diff --git a/vlib/v/parser/if.v b/vlib/v/parser/if.v index fdbaeb3ce7..b10cd29410 100644 --- a/vlib/v/parser/if.v +++ b/vlib/v/parser/if.v @@ -116,19 +116,20 @@ fn (mut p Parser) match_expr() ast.MatchExpr { if p.tok.kind == .key_else { is_else = true p.next() - } else if p.tok.kind == .name && !(p.tok.lit == 'C' && p.peek_tok.kind == .dot) && - (p.tok.lit in table.builtin_type_names || (p.tok.lit[0].is_capital() && !p.tok.lit.is_upper()) || - (p.peek_tok.kind == .dot && p.peek_tok2.lit[0].is_capital() ) ) { + } else if p.tok.kind == .name && !(p.tok.lit == 'C' && + p.peek_tok.kind == .dot) && (p.tok.lit in table.builtin_type_names || + (p.tok.lit[0].is_capital() && !p.tok.lit.is_upper()) || + (p.peek_tok.kind == .dot && p.peek_tok2.lit[0].is_capital())) { if var_name.len == 0 { match cond { ast.Ident { // shadow match cond variable - var_name = it.name + var_name = cond.name } - // ast.SelectorExpr { - // p.error('expecting `as` (eg. `match user.attribute as user_attr`) when matching struct fields') - // } else { + // ast.SelectorExpr { + // p.error('expecting `as` (eg. `match user.attribute as user_attr`) when matching struct fields') + // } // p.error('only variables can be used in sum types matches') } } @@ -161,7 +162,6 @@ fn (mut p Parser) match_expr() ast.MatchExpr { p.parse_type() } is_sum_type = true - } else { // Expression match for { @@ -204,7 +204,7 @@ fn (mut p Parser) match_expr() ast.MatchExpr { len: match_last_pos.pos - match_first_pos.pos + match_last_pos.len } p.check(.rcbr) - //return ast.StructInit{} + // return ast.StructInit{} return ast.MatchExpr{ branches: branches cond: cond diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 6272817da8..e10830cdbb 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -114,6 +114,12 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme warnings: []errors.Warning{} global_scope: global_scope } + if pref.is_vet && p.scanner.text.contains('\n ') { + // TODO make this smarter + println(p.scanner.file_path) + println('Looks like you are using spaces for indentation.\n' + 'You can run `v fmt -w file.v` to fix that automatically') + exit(1) + } return p.parse() } @@ -850,8 +856,7 @@ pub fn (mut p Parser) name_expr() ast.Expr { } } if p.peek_tok.kind == .dot && !known_var && - (language != .v || p.known_import(p.tok.lit) || - p.mod.all_after_last('.') == p.tok.lit) { + (language != .v || p.known_import(p.tok.lit) || p.mod.all_after_last('.') == p.tok.lit) { if language == .c { mod = 'C' } else if language == .js { @@ -870,8 +875,7 @@ pub fn (mut p Parser) name_expr() ast.Expr { // p.warn('name expr $p.tok.lit $p.peek_tok.str()') // fn call or type cast if p.peek_tok.kind == .lpar || - (p.peek_tok.kind == .lt && p.peek_tok2.kind == .name && - p.peek_tok3.kind == .gt) { + (p.peek_tok.kind == .lt && p.peek_tok2.kind == .name && p.peek_tok3.kind == .gt) { // foo() or foo() mut name := p.tok.lit if mod.len > 0 { @@ -1486,7 +1490,7 @@ $pubfn (mut e $name) set(flag $name) { unsafe{ *e = int(*e) | (1 << int(f $pubfn (mut e $name) clear(flag $name) { unsafe{ *e = int(*e) & ~(1 << int(flag)) } } $pubfn (mut e $name) toggle(flag $name) { unsafe{ *e = int(*e) ^ (1 << int(flag)) } } // - ') +') } p.table.register_type_symbol(table.TypeSymbol{ kind: .enum_ diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index b5b65b9f89..951674383e 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -97,6 +97,7 @@ pub mut: fast bool // use tcc/x64 codegen enable_globals bool // allow __global for low level code is_fmt bool + is_vet bool is_bare bool no_preludes bool // Prevents V from generating preludes in resulting .c files custom_prelude string // Contents of custom V prelude that will be prepended before code in resulting .c files diff --git a/vlib/v/vet/vet.v b/vlib/v/vet/vet.v new file mode 100644 index 0000000000..2a7bf36dc2 --- /dev/null +++ b/vlib/v/vet/vet.v @@ -0,0 +1,9 @@ +// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved. +// 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 + +pub fn vet(file ast.File, table &table.Table, is_debug bool) { +}