checker: move more checks from parser

pull/4440/head
Daniel Däschle 2020-04-16 12:17:15 +02:00 committed by GitHub
parent 554d87f5b0
commit 19723c927b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 9 deletions

View File

@ -670,8 +670,13 @@ pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) {
c.expected_type = table.none_type // TODO a hack to make `x := if ... work` c.expected_type = table.none_type // TODO a hack to make `x := if ... work`
// check variablename for beginning with capital letter 'Abc' // check variablename for beginning with capital letter 'Abc'
for ident in assign_stmt.left { for ident in assign_stmt.left {
if assign_stmt.op == .decl_assign && scanner.contains_capital(ident.name) { is_decl := assign_stmt.op == .decl_assign
if is_decl && scanner.contains_capital(ident.name) {
c.error('variable names cannot contain uppercase letters, use snake_case instead', ident.pos) c.error('variable names cannot contain uppercase letters, use snake_case instead', ident.pos)
} else if is_decl && ident.kind != .blank_ident {
if ident.name.starts_with('__') {
c.error('variable names cannot start with `__`', ident.pos)
}
} }
} }
if assign_stmt.left.len > assign_stmt.right.len { if assign_stmt.left.len > assign_stmt.right.len {
@ -998,6 +1003,9 @@ fn (c mut Checker) stmt(node ast.Stmt) {
c.in_for_count-- c.in_for_count--
} }
ast.GoStmt { ast.GoStmt {
if !is_call_expr(it.call_expr) {
c.error('expression in `go` must be a function call', expr_pos(it.call_expr))1
}
c.expr(it.call_expr) c.expr(it.call_expr)
} }
// ast.HashStmt {} // ast.HashStmt {}
@ -1020,6 +1028,13 @@ fn (c mut Checker) stmt(node ast.Stmt) {
} }
} }
fn is_call_expr(expr ast.Expr) bool {
return match expr {
ast.CallExpr { true }
else { false }
}
}
fn (c mut Checker) stmts(stmts []ast.Stmt) { fn (c mut Checker) stmts(stmts []ast.Stmt) {
c.expected_type = table.void_type c.expected_type = table.void_type
for stmt in stmts { for stmt in stmts {

View File

@ -0,0 +1,5 @@
vlib/v/checker/tests/inout/decl_underscore.v:2:2: error: variable names cannot start with `__`
1| fn main() {
2| __abc := 1
~~~~~
3| }

View File

@ -0,0 +1,3 @@
fn main() {
__abc := 1
}

View File

@ -0,0 +1,5 @@
vlib/v/checker/tests/inout/go_expr.v:2:5: error: expression in `go` must be a function call
1| fn main() {
2| go 1
^
3| }

View File

@ -0,0 +1,3 @@
fn main() {
go 1
}

View File

@ -242,8 +242,7 @@ fn (p mut Parser) check(expected token.Kind) {
// p.next() // p.next()
// } // }
if p.tok.kind != expected { if p.tok.kind != expected {
s := 'unexpected `${p.tok.kind.str()}`, expecting `${expected.str()}`' p.error('unexpected `${p.tok.kind.str()}`, expecting `${expected.str()}`')
p.error(s)
} }
p.next() p.next()
} }
@ -420,9 +419,7 @@ pub fn (p mut Parser) stmt() ast.Stmt {
ast.CallExpr { ast.CallExpr {
// call_expr = it // call_expr = it
} }
else { else {}
p.error('expression in `go` must be a function call')
}
} }
return ast.GoStmt{ return ast.GoStmt{
call_expr: expr call_expr: expr
@ -1808,9 +1805,6 @@ fn (p mut Parser) assign_stmt() ast.Stmt {
p.error('unknown variable `$ident.name`') p.error('unknown variable `$ident.name`')
} }
if is_decl && ident.kind != .blank_ident { if is_decl && ident.kind != .blank_ident {
if ident.name.starts_with('__') {
p.error('variable names cannot start with `__`')
}
if p.scope.known_var(ident.name) { if p.scope.known_var(ident.name) {
p.error('redefinition of `$ident.name`') p.error('redefinition of `$ident.name`')
} }