vet: a basic version that just checks indentation for now

pull/5532/head
Alexander Medvednikov 2020-06-27 14:50:04 +02:00
parent 58763ff299
commit 2bfe8e5153
6 changed files with 67 additions and 15 deletions

38
cmd/tools/vvet.v 100644
View File

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

View File

@ -11,7 +11,7 @@ import v.builder
const ( const (
simple_cmd = [ simple_cmd = [
'fmt', 'up', 'fmt', 'up', 'vet',
'self', 'symlink', 'bin2v', 'self', 'symlink', 'bin2v',
'test', 'test-fmt', 'test-compiler', 'test-fixed', 'test', 'test-fmt', 'test-compiler', 'test-fixed',
'repl', 'repl',

View File

@ -116,19 +116,20 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
if p.tok.kind == .key_else { if p.tok.kind == .key_else {
is_else = true is_else = true
p.next() p.next()
} else if p.tok.kind == .name && !(p.tok.lit == 'C' && p.peek_tok.kind == .dot) && } else if p.tok.kind == .name && !(p.tok.lit == 'C' &&
(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.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())) { (p.peek_tok.kind == .dot && p.peek_tok2.lit[0].is_capital())) {
if var_name.len == 0 { if var_name.len == 0 {
match cond { match cond {
ast.Ident { ast.Ident {
// shadow match cond variable // shadow match cond variable
var_name = it.name var_name = cond.name
} }
else {
// ast.SelectorExpr { // ast.SelectorExpr {
// p.error('expecting `as` (eg. `match user.attribute as user_attr`) when matching struct fields') // p.error('expecting `as` (eg. `match user.attribute as user_attr`) when matching struct fields')
// } // }
else {
// p.error('only variables can be used in sum types matches') // 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() p.parse_type()
} }
is_sum_type = true is_sum_type = true
} else { } else {
// Expression match // Expression match
for { for {

View File

@ -114,6 +114,12 @@ pub fn parse_file(path string, b_table &table.Table, comments_mode scanner.Comme
warnings: []errors.Warning{} warnings: []errors.Warning{}
global_scope: global_scope 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() return p.parse()
} }
@ -850,8 +856,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
} }
} }
if p.peek_tok.kind == .dot && !known_var && if p.peek_tok.kind == .dot && !known_var &&
(language != .v || p.known_import(p.tok.lit) || (language != .v || p.known_import(p.tok.lit) || p.mod.all_after_last('.') == p.tok.lit) {
p.mod.all_after_last('.') == p.tok.lit) {
if language == .c { if language == .c {
mod = 'C' mod = 'C'
} else if language == .js { } 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()') // p.warn('name expr $p.tok.lit $p.peek_tok.str()')
// fn call or type cast // fn call or type cast
if p.peek_tok.kind == .lpar || if p.peek_tok.kind == .lpar ||
(p.peek_tok.kind == .lt && p.peek_tok2.kind == .name && (p.peek_tok.kind == .lt && p.peek_tok2.kind == .name && p.peek_tok3.kind == .gt) {
p.peek_tok3.kind == .gt) {
// foo() or foo<int>() // foo() or foo<int>()
mut name := p.tok.lit mut name := p.tok.lit
if mod.len > 0 { if mod.len > 0 {

View File

@ -97,6 +97,7 @@ pub mut:
fast bool // use tcc/x64 codegen fast bool // use tcc/x64 codegen
enable_globals bool // allow __global for low level code enable_globals bool // allow __global for low level code
is_fmt bool is_fmt bool
is_vet bool
is_bare bool is_bare bool
no_preludes bool // Prevents V from generating preludes in resulting .c files 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 custom_prelude string // Contents of custom V prelude that will be prepended before code in resulting .c files

9
vlib/v/vet/vet.v 100644
View File

@ -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) {
}