vet: a basic version that just checks indentation for now
parent
58763ff299
commit
2bfe8e5153
|
@ -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)
|
||||||
|
}
|
|
@ -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',
|
||||||
|
|
|
@ -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.peek_tok.kind == .dot && p.peek_tok2.lit[0].is_capital() ) ) {
|
(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 {
|
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
|
||||||
}
|
}
|
||||||
// ast.SelectorExpr {
|
|
||||||
// p.error('expecting `as` (eg. `match user.attribute as user_attr`) when matching struct fields')
|
|
||||||
// }
|
|
||||||
else {
|
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')
|
// 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 {
|
||||||
|
@ -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
|
len: match_last_pos.pos - match_first_pos.pos + match_last_pos.len
|
||||||
}
|
}
|
||||||
p.check(.rcbr)
|
p.check(.rcbr)
|
||||||
//return ast.StructInit{}
|
// return ast.StructInit{}
|
||||||
return ast.MatchExpr{
|
return ast.MatchExpr{
|
||||||
branches: branches
|
branches: branches
|
||||||
cond: cond
|
cond: cond
|
||||||
|
|
|
@ -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 {
|
||||||
|
@ -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) clear(flag $name) { unsafe{ *e = int(*e) & ~(1 << int(flag)) } }
|
||||||
$pubfn (mut e $name) toggle(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{
|
p.table.register_type_symbol(table.TypeSymbol{
|
||||||
kind: .enum_
|
kind: .enum_
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
}
|
Loading…
Reference in New Issue