mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parser,checker,builder: make the checker more robust with -check over files with syntax/parsing errors
This commit is contained in:
@@ -582,10 +582,10 @@ fn (mut c Checker) fail_if_immutable(expr_ ast.Expr) (string, token.Pos) {
|
||||
match mut expr {
|
||||
ast.CastExpr {
|
||||
// TODO
|
||||
return '', pos
|
||||
return '', expr.pos
|
||||
}
|
||||
ast.ComptimeSelector {
|
||||
return '', pos
|
||||
return '', expr.pos
|
||||
}
|
||||
ast.Ident {
|
||||
if mut expr.obj is ast.Var {
|
||||
@@ -619,6 +619,9 @@ fn (mut c Checker) fail_if_immutable(expr_ ast.Expr) (string, token.Pos) {
|
||||
}
|
||||
}
|
||||
ast.IndexExpr {
|
||||
if expr.left_type == 0 {
|
||||
return to_lock, pos
|
||||
}
|
||||
left_sym := c.table.sym(expr.left_type)
|
||||
mut elem_type := ast.Type(0)
|
||||
mut kind := ''
|
||||
@@ -651,10 +654,10 @@ fn (mut c Checker) fail_if_immutable(expr_ ast.Expr) (string, token.Pos) {
|
||||
}
|
||||
ast.SelectorExpr {
|
||||
if expr.expr_type == 0 {
|
||||
return '', pos
|
||||
return '', expr.pos
|
||||
}
|
||||
// retrieve ast.Field
|
||||
c.ensure_type_exists(expr.expr_type, expr.pos) or { return '', pos }
|
||||
c.ensure_type_exists(expr.expr_type, expr.pos) or { return '', expr.pos }
|
||||
mut typ_sym := c.table.final_sym(c.unwrap_generic(expr.expr_type))
|
||||
match typ_sym.kind {
|
||||
.struct_ {
|
||||
@@ -666,7 +669,7 @@ fn (mut c Checker) fail_if_immutable(expr_ ast.Expr) (string, token.Pos) {
|
||||
if !has_field {
|
||||
type_str := c.table.type_to_str(expr.expr_type)
|
||||
c.error('unknown field `${type_str}.$expr.field_name`', expr.pos)
|
||||
return '', pos
|
||||
return '', expr.pos
|
||||
}
|
||||
if field_info.typ.has_flag(.shared_f) {
|
||||
expr_name := '${expr.expr}.$expr.field_name'
|
||||
@@ -702,7 +705,7 @@ fn (mut c Checker) fail_if_immutable(expr_ ast.Expr) (string, token.Pos) {
|
||||
mut field_info := interface_info.find_field(expr.field_name) or {
|
||||
type_str := c.table.type_to_str(expr.expr_type)
|
||||
c.error('unknown field `${type_str}.$expr.field_name`', expr.pos)
|
||||
return '', pos
|
||||
return '', expr.pos
|
||||
}
|
||||
if !field_info.is_mut {
|
||||
type_str := c.table.type_to_str(expr.expr_type)
|
||||
@@ -717,7 +720,7 @@ fn (mut c Checker) fail_if_immutable(expr_ ast.Expr) (string, token.Pos) {
|
||||
mut field_info := sumtype_info.find_field(expr.field_name) or {
|
||||
type_str := c.table.type_to_str(expr.expr_type)
|
||||
c.error('unknown field `${type_str}.$expr.field_name`', expr.pos)
|
||||
return '', pos
|
||||
return '', expr.pos
|
||||
}
|
||||
if !field_info.is_mut {
|
||||
type_str := c.table.type_to_str(expr.expr_type)
|
||||
@@ -756,18 +759,18 @@ fn (mut c Checker) fail_if_immutable(expr_ ast.Expr) (string, token.Pos) {
|
||||
}
|
||||
ast.ArrayInit {
|
||||
c.error('array literal can not be modified', expr.pos)
|
||||
return '', pos
|
||||
return '', expr.pos
|
||||
}
|
||||
ast.StructInit {
|
||||
return '', pos
|
||||
return '', expr.pos
|
||||
}
|
||||
ast.InfixExpr {
|
||||
return '', pos
|
||||
return '', expr.pos
|
||||
}
|
||||
else {
|
||||
if !expr.is_pure_literal() {
|
||||
c.error('unexpected expression `$expr.type_name()`', expr.pos())
|
||||
return '', pos
|
||||
return '', expr.pos()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3495,6 +3498,10 @@ fn (mut c Checker) check_index(typ_sym &ast.TypeSymbol, index ast.Expr, index_ty
|
||||
|
||||
pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
||||
mut typ := c.expr(node.left)
|
||||
if typ == 0 {
|
||||
c.error('unknown type for expression `$node.left`', node.pos)
|
||||
return typ
|
||||
}
|
||||
mut typ_sym := c.table.final_sym(typ)
|
||||
node.left_type = typ
|
||||
match typ_sym.kind {
|
||||
|
||||
@@ -39,8 +39,12 @@ pub fn (mut c Checker) return_stmt(mut node ast.Return) {
|
||||
mut expr_idxs := []int{}
|
||||
for i, expr in node.exprs {
|
||||
mut typ := c.expr(expr)
|
||||
if typ == 0 {
|
||||
return
|
||||
}
|
||||
if typ == ast.void_type {
|
||||
c.error('`$expr` used as value', node.pos)
|
||||
return
|
||||
}
|
||||
// Unpack multi return types
|
||||
sym := c.table.sym(typ)
|
||||
|
||||
7
vlib/v/checker/tests/with_check_option/v_tictactoe.out
Normal file
7
vlib/v/checker/tests/with_check_option/v_tictactoe.out
Normal file
@@ -0,0 +1,7 @@
|
||||
vlib/v/checker/tests/with_check_option/v_tictactoe.vv:4:31: error: expected `init:`, not `len`
|
||||
2 |
|
||||
3 | fn new_board() [][]string {
|
||||
4 | mut board := [3][]string{ len: 3, init: []string{ len: 3, init: '' } }
|
||||
| ~~~
|
||||
5 | for i in 0..9 {
|
||||
6 | board[i / 3][i % 3] = (i + 1).str()
|
||||
27
vlib/v/checker/tests/with_check_option/v_tictactoe.vv
Normal file
27
vlib/v/checker/tests/with_check_option/v_tictactoe.vv
Normal file
@@ -0,0 +1,27 @@
|
||||
module main
|
||||
|
||||
fn new_board() [][]string {
|
||||
mut board := [3][]string{ len: 3, init: []string{ len: 3, init: '' } }
|
||||
for i in 0..9 {
|
||||
board[i / 3][i % 3] = (i + 1).str()
|
||||
}
|
||||
return board
|
||||
}
|
||||
|
||||
fn (mut b [][]string) place(player string, y int, x int) ? {
|
||||
if b[y][x] in ['a'] {
|
||||
error("position is already occupied")
|
||||
}
|
||||
b[y][x] = player
|
||||
}
|
||||
|
||||
fn prompt(player string) (int, int) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mut board := new_board()
|
||||
mut player := 'X'
|
||||
println(board)
|
||||
println(player)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
vlib/v/checker/tests/with_check_option/v_tictactoe_fixed_syntax_error.vv:8:9: error: cannot use `[3][]string` as type `[][]string` in return argument
|
||||
6 | board[i / 3][i % 3] = (i + 1).str()
|
||||
7 | }
|
||||
8 | return board
|
||||
| ~~~~~
|
||||
9 | }
|
||||
10 |
|
||||
@@ -0,0 +1,27 @@
|
||||
module main
|
||||
|
||||
fn new_board() [][]string {
|
||||
mut board := [3][]string{init: []string{len: 3, init: ''}}
|
||||
for i in 0 .. 9 {
|
||||
board[i / 3][i % 3] = (i + 1).str()
|
||||
}
|
||||
return board
|
||||
}
|
||||
|
||||
fn (mut b [][]string) place(player string, y int, x int) ? {
|
||||
if b[y][x] == 'a' {
|
||||
error('position is already occupied')
|
||||
}
|
||||
b[y][x] = player
|
||||
}
|
||||
|
||||
fn prompt(player string) (int, int) {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mut board := new_board()
|
||||
mut player := 'X'
|
||||
println(board)
|
||||
println(player)
|
||||
}
|
||||
Reference in New Issue
Block a user