mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parser: warn about ambiguous infix/prefix op token (#6491)
This commit is contained in:
parent
9e31335744
commit
9f33b33803
@ -422,6 +422,8 @@ pub fn (i &Ident) var_info() IdentVar {
|
||||
}
|
||||
}
|
||||
|
||||
// left op right
|
||||
// See: token.Kind.is_infix
|
||||
pub struct InfixExpr {
|
||||
pub:
|
||||
op token.Kind
|
||||
@ -434,6 +436,7 @@ pub mut:
|
||||
auto_locked string
|
||||
}
|
||||
|
||||
// ++, --
|
||||
pub struct PostfixExpr {
|
||||
pub:
|
||||
op token.Kind
|
||||
@ -443,6 +446,7 @@ pub mut:
|
||||
auto_locked string
|
||||
}
|
||||
|
||||
// See: token.Kind.is_prefix
|
||||
pub struct PrefixExpr {
|
||||
pub:
|
||||
op token.Kind
|
||||
|
@ -269,11 +269,13 @@ pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_iden
|
||||
pos: pos
|
||||
}
|
||||
} else if p.tok.kind.is_infix() {
|
||||
// return early for deref assign `*x = 2` goes to prefix expr
|
||||
if p.tok.kind == .mul &&
|
||||
p.tok.line_nr != p.prev_tok.line_nr &&
|
||||
p.peek_tok2.kind == .assign {
|
||||
return node
|
||||
if p.tok.kind.is_prefix() && p.tok.line_nr != p.prev_tok.line_nr {
|
||||
// return early for deref assign `*x = 2` goes to prefix expr
|
||||
if p.tok.kind == .mul && p.peek_tok2.kind == .assign {
|
||||
return node
|
||||
}
|
||||
// added 10/2020: LATER this will be parsed as PrefixExpr instead
|
||||
p.warn_with_pos('move infix `$p.tok.kind` operator before new line (if infix intended) or use brackets for a prefix expression', p.tok.position())
|
||||
}
|
||||
// continue on infix expr
|
||||
node = p.infix_expr(node)
|
||||
|
28
vlib/v/parser/tests/prefix_first.out
Normal file
28
vlib/v/parser/tests/prefix_first.out
Normal file
@ -0,0 +1,28 @@
|
||||
vlib/v/parser/tests/prefix_first.vv:15:3: warning: move infix `-` operator before new line (if infix intended) or use brackets for a prefix expression
|
||||
13 | _ = if true {
|
||||
14 | v = 1
|
||||
15 | -1
|
||||
| ^
|
||||
16 | } else {1}
|
||||
17 | }
|
||||
vlib/v/parser/tests/prefix_first.vv:26:3: warning: move infix `&` operator before new line (if infix intended) or use brackets for a prefix expression
|
||||
24 | _ = opt() or {
|
||||
25 | _ = 1
|
||||
26 | &v
|
||||
| ^
|
||||
27 | }
|
||||
28 | }
|
||||
vlib/v/parser/tests/prefix_first.vv:13:6: error: `if` expression requires an expression as the last statement of every branch
|
||||
11 |
|
||||
12 | // later this should compile correctly
|
||||
13 | _ = if true {
|
||||
| ~~~~~~~
|
||||
14 | v = 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
|
||||
22 | // later this should compile correctly
|
||||
23 | v := 3
|
||||
24 | _ = opt() or {
|
||||
| ~~~~~
|
||||
25 | _ = 1
|
||||
26 | &v
|
28
vlib/v/parser/tests/prefix_first.vv
Normal file
28
vlib/v/parser/tests/prefix_first.vv
Normal file
@ -0,0 +1,28 @@
|
||||
// a prefix op can be parsed as an infix op if there's an expression on the line before
|
||||
// https://github.com/vlang/v/pull/6491
|
||||
fn test_prefix() {
|
||||
mut v := 1
|
||||
mut p := &v
|
||||
// OK, special workaround
|
||||
unsafe {
|
||||
v = 1
|
||||
*p = 2
|
||||
}
|
||||
|
||||
// later this should compile correctly
|
||||
_ = if true {
|
||||
v = 1
|
||||
-1
|
||||
} else {1}
|
||||
}
|
||||
|
||||
fn opt() ?&int {return none}
|
||||
|
||||
fn test_prefix_or() {
|
||||
// later this should compile correctly
|
||||
v := 3
|
||||
_ = opt() or {
|
||||
_ = 1
|
||||
&v
|
||||
}
|
||||
}
|
@ -409,6 +409,10 @@ pub fn (k Kind) is_start_of_type() bool {
|
||||
return k in [.name, .lpar, .amp, .lsbr, .question]
|
||||
}
|
||||
|
||||
pub fn (kind Kind) is_prefix() bool {
|
||||
return kind in [.minus, .amp, .mul, .not, .bit_not]
|
||||
}
|
||||
|
||||
pub fn (kind Kind) is_infix() bool {
|
||||
return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .key_in,
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user