From e69f091bbd8adc2419c10bb4c2afa7dc37468c3f Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Wed, 19 Aug 2020 01:37:17 +0100 Subject: [PATCH] parser: require `(` on same line as name token for fn call or cast (#6160) --- vlib/v/parser/parser.v | 18 ++++++++---------- vlib/v/tests/parser_line_test.v | 9 +++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 vlib/v/tests/parser_line_test.v diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 3fa3893e5c..51aa5cd10f 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -966,7 +966,7 @@ pub fn (mut p Parser) name_expr() ast.Expr { // `chan typ{...}` if p.tok.lit == 'chan' { first_pos := p.tok.position() - mut last_pos := p.tok.position() + mut last_pos := first_pos chan_type := p.parse_chan_type() mut has_cap := false mut cap_expr := ast.Expr{} @@ -992,13 +992,8 @@ pub fn (mut p Parser) name_expr() ast.Expr { last_pos = p.tok.position() p.check(.rcbr) } - pos := token.Position{ - line_nr: first_pos.line_nr - pos: first_pos.pos - len: last_pos.pos - first_pos.pos + last_pos.len - } return ast.ChanInit{ - pos: pos + pos: first_pos.extend(last_pos) has_cap: has_cap cap_expr: cap_expr typ: chan_type @@ -1034,10 +1029,13 @@ pub fn (mut p Parser) name_expr() ast.Expr { } lit0_is_capital := p.tok.lit[0].is_capital() // p.warn('name expr $p.tok.lit $p.peek_tok.str()') - // fn call or type cast - if p.peek_tok.kind == .lpar || + same_line := p.tok.line_nr == p.peek_tok.line_nr + // `(` must be on same line as name token otherwise it's a ParExpr + if !same_line && p.peek_tok.kind == .lpar { + node = p.parse_ident(language) + } else if p.peek_tok.kind == .lpar || (p.peek_tok.kind == .lt && !lit0_is_capital && p.peek_tok2.kind == .name && p.peek_tok3.kind == .gt) { - // foo() or foo() + // foo(), foo() or type() cast mut name := p.tok.lit if mod.len > 0 { name = '${mod}.$name' diff --git a/vlib/v/tests/parser_line_test.v b/vlib/v/tests/parser_line_test.v new file mode 100644 index 0000000000..0422cb2d59 --- /dev/null +++ b/vlib/v/tests/parser_line_test.v @@ -0,0 +1,9 @@ +fn test_name_lpar() { + mut v := 2 + // check ParExpr is parsed, not CallExpr + mut p := &v + (*p)++ + _ = v + (*p)++ + assert v == 4 +}