parser: warn about ambiguous infix/prefix op token (#6491)
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 struct InfixExpr {
|
||||||
pub:
|
pub:
|
||||||
op token.Kind
|
op token.Kind
|
||||||
|
@ -434,6 +436,7 @@ pub mut:
|
||||||
auto_locked string
|
auto_locked string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ++, --
|
||||||
pub struct PostfixExpr {
|
pub struct PostfixExpr {
|
||||||
pub:
|
pub:
|
||||||
op token.Kind
|
op token.Kind
|
||||||
|
@ -443,6 +446,7 @@ pub mut:
|
||||||
auto_locked string
|
auto_locked string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See: token.Kind.is_prefix
|
||||||
pub struct PrefixExpr {
|
pub struct PrefixExpr {
|
||||||
pub:
|
pub:
|
||||||
op token.Kind
|
op token.Kind
|
||||||
|
|
|
@ -269,12 +269,14 @@ pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_iden
|
||||||
pos: pos
|
pos: pos
|
||||||
}
|
}
|
||||||
} else if p.tok.kind.is_infix() {
|
} else if p.tok.kind.is_infix() {
|
||||||
|
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
|
// return early for deref assign `*x = 2` goes to prefix expr
|
||||||
if p.tok.kind == .mul &&
|
if p.tok.kind == .mul && p.peek_tok2.kind == .assign {
|
||||||
p.tok.line_nr != p.prev_tok.line_nr &&
|
|
||||||
p.peek_tok2.kind == .assign {
|
|
||||||
return node
|
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
|
// continue on infix expr
|
||||||
node = p.infix_expr(node)
|
node = p.infix_expr(node)
|
||||||
// return early `if bar is SumType as b {`
|
// return early `if bar is SumType as b {`
|
||||||
|
|
|
@ -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
|
|
@ -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]
|
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 {
|
pub fn (kind Kind) is_infix() bool {
|
||||||
return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .key_in,
|
return kind in [.plus, .minus, .mod, .mul, .div, .eq, .ne, .gt, .lt, .key_in,
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue