1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

parser: fixes or block position (#6736)

This commit is contained in:
Daniel Däschle 2020-11-04 15:02:01 +01:00 committed by GitHub
parent fff70368b7
commit a2fc19880a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 26 additions and 39 deletions

View File

@ -1618,10 +1618,10 @@ pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) t
return ret_type return ret_type
} else if expr.or_block.kind == .block { } else if expr.or_block.kind == .block {
c.error('unexpected `or` block, the function `$expr.name` does not return an optional', c.error('unexpected `or` block, the function `$expr.name` does not return an optional',
expr.pos) expr.or_block.pos)
} else if expr.or_block.kind == .propagate { } else if expr.or_block.kind == .propagate {
c.error('unexpected `?`, the function `$expr.name`, does not return an optional', c.error('unexpected `?`, the function `$expr.name`, does not return an optional',
expr.pos) expr.or_block.pos)
} }
} }
return ret_type return ret_type

View File

@ -1,8 +1,8 @@
vlib/v/checker/tests/or_err.vv:4:6: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope vlib/v/checker/tests/or_err.vv:4:10: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope
2 | return none 2 | return none
3 | } 3 | }
4 | a := f() or { 4 | a := f() or {
| ~~~ | ~~~~
5 | {} 5 | {}
6 | } 6 | }
vlib/v/checker/tests/or_err.vv:11:2: error: wrong return type `rune` in the `or {}` block, expected `&int` vlib/v/checker/tests/or_err.vv:11:2: error: wrong return type `rune` in the `or {}` block, expected `&int`

View File

@ -1,6 +1,6 @@
vlib/v/checker/tests/unexpected_or.vv:6:6: error: unexpected `or` block, the function `ret_zero` does not return an optional vlib/v/checker/tests/unexpected_or.vv:6:17: error: unexpected `or` block, the function `ret_zero` does not return an optional
4 | 4 |
5 | fn main() { 5 | fn main() {
6 | _ = ret_zero() or { 1 } 6 | _ = ret_zero() or { 1 }
| ~~~~~~~~~~ | ~~~~~~~~
7 | } 7 | }

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/unexpected_or_propagate.vv:6:7: error: unexpected `?`, the function `ret_zero`, does not return an optional vlib/v/checker/tests/unexpected_or_propagate.vv:6:17: error: unexpected `?`, the function `ret_zero`, does not return an optional
4 | 4 |
5 | fn opt_fn() ?int { 5 | fn opt_fn() ?int {
6 | a := ret_zero()? 6 | a := ret_zero()?
| ~~~~~~~~~~ | ^
7 | return a 7 | return a
8 | } 8 | }

View File

@ -1,7 +1,7 @@
vlib/v/checker/tests/wrong_propagate_ret_type.vv:6:7: error: to propagate the optional call, `opt_call` must itself return an optional vlib/v/checker/tests/wrong_propagate_ret_type.vv:6:17: error: to propagate the optional call, `opt_call` must itself return an optional
4 | 4 |
5 | fn opt_call() int { 5 | fn opt_call() int {
6 | a := ret_none()? 6 | a := ret_none()?
| ~~~~~~~~~~ | ^
7 | return a 7 | return a
8 | } 8 | }

View File

@ -54,6 +54,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
len: last_pos.pos - first_pos.pos + last_pos.len len: last_pos.pos - first_pos.pos + last_pos.len
} }
mut or_stmts := []ast.Stmt{} mut or_stmts := []ast.Stmt{}
mut or_pos := p.tok.position()
if p.tok.kind == .key_orelse { if p.tok.kind == .key_orelse {
// `foo() or {}`` // `foo() or {}``
was_inside_or_expr := p.inside_or_expr was_inside_or_expr := p.inside_or_expr
@ -74,6 +75,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
}) })
or_kind = .block or_kind = .block
or_stmts = p.parse_block_no_scope(false) or_stmts = p.parse_block_no_scope(false)
or_pos = or_pos.extend(p.prev_tok.position())
p.close_scope() p.close_scope()
p.inside_or_expr = was_inside_or_expr p.inside_or_expr = was_inside_or_expr
} }
@ -89,37 +91,18 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
fn_name = registered.name fn_name = registered.name
} }
} }
/*
call_expr := ast.CallExpr{
name: fn_name
args: args
mod: fn_mod
pos: pos
language: language
generic_type: generic_type
}
if or_kind != .absent {
return ast.OrExpr2{
call_expr: call_expr
stmts: or_stmts
kind: or_kind
pos: pos
}
}
return call_expr
*/
return ast.CallExpr{ return ast.CallExpr{
name: fn_name name: fn_name
args: args args: args
mod: fn_mod mod: fn_mod
pos: pos pos: pos
language: language language: language
generic_type: generic_type
or_block: ast.OrExpr{ or_block: ast.OrExpr{
stmts: or_stmts stmts: or_stmts
kind: or_kind kind: or_kind
pos: pos pos: or_pos
} }
generic_type: generic_type
} }
} }

View File

@ -1238,6 +1238,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
p.check(.rpar) p.check(.rpar)
mut or_stmts := []ast.Stmt{} mut or_stmts := []ast.Stmt{}
mut or_kind := ast.OrKind.absent mut or_kind := ast.OrKind.absent
mut or_pos := p.tok.position()
if p.tok.kind == .key_orelse { if p.tok.kind == .key_orelse {
p.next() p.next()
p.open_scope() p.open_scope()
@ -1255,6 +1256,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
}) })
or_kind = .block or_kind = .block
or_stmts = p.parse_block_no_scope(false) or_stmts = p.parse_block_no_scope(false)
or_pos = or_pos.extend(p.prev_tok.position())
p.close_scope() p.close_scope()
} }
// `foo()?` // `foo()?`
@ -1278,7 +1280,7 @@ fn (mut p Parser) dot_expr(left ast.Expr) ast.Expr {
or_block: ast.OrExpr{ or_block: ast.OrExpr{
stmts: or_stmts stmts: or_stmts
kind: or_kind kind: or_kind
pos: pos pos: or_pos
} }
} }
if is_filter || field_name == 'sort' { if is_filter || field_name == 'sort' {

View File

@ -355,6 +355,7 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr {
} }
mut or_stmts := []ast.Stmt{} mut or_stmts := []ast.Stmt{}
mut or_kind := ast.OrKind.absent mut or_kind := ast.OrKind.absent
mut or_pos := p.tok.position()
// allow `x := <-ch or {...}` to handle closed channel // allow `x := <-ch or {...}` to handle closed channel
if op == .arrow { if op == .arrow {
if p.tok.kind == .key_orelse { if p.tok.kind == .key_orelse {
@ -374,6 +375,7 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr {
}) })
or_kind = .block or_kind = .block
or_stmts = p.parse_block_no_scope(false) or_stmts = p.parse_block_no_scope(false)
or_pos = or_pos.extend(p.prev_tok.position())
p.close_scope() p.close_scope()
} }
if p.tok.kind == .question { if p.tok.kind == .question {
@ -388,7 +390,7 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr {
or_block: ast.OrExpr{ or_block: ast.OrExpr{
stmts: or_stmts stmts: or_stmts
kind: or_kind kind: or_kind
pos: pos pos: or_pos
} }
} }
} }

View File

@ -13,16 +13,16 @@ vlib/v/parser/tests/prefix_first.vv:26:3: warning: move infix `&` operator befor
27 | } 27 | }
28 | } 28 | }
vlib/v/parser/tests/prefix_first.vv:13:6: error: `if` expression requires an expression as the last statement of every branch vlib/v/parser/tests/prefix_first.vv:13:6: error: `if` expression requires an expression as the last statement of every branch
11 | 11 |
12 | // later this should compile correctly 12 | // later this should compile correctly
13 | _ = if true { 13 | _ = if true {
| ~~~~~~~ | ~~~~~~~
14 | v = 1 14 | v = 1
15 | -1 15 | -1
vlib/v/parser/tests/prefix_first.vv:24:6: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope vlib/v/parser/tests/prefix_first.vv:24:12: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope
22 | // later this should compile correctly 22 | // later this should compile correctly
23 | v := 3 23 | v := 3
24 | _ = opt() or { 24 | _ = opt() or {
| ~~~~~ | ~~~~
25 | _ = 1 25 | _ = 1
26 | &v 26 | &v