From fd7986c7fb495239c7327bf3c6ea1df0d8f13198 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Tue, 23 Jul 2024 05:47:34 -0300 Subject: [PATCH] parser: fix recognition of `mod.Enum.val` inside fn args (#21908) --- vlib/v/parser/parser.v | 101 +++++++++++--------- vlib/v/tests/fullname_enumval_as_arg_test.v | 10 ++ 2 files changed, 67 insertions(+), 44 deletions(-) create mode 100644 vlib/v/tests/fullname_enumval_as_arg_test.v diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index d24e8ccbc8a7f4..ffec096b9efd80 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -2774,34 +2774,43 @@ fn (mut p Parser) name_expr() ast.Expr { got: '${p.prev_tok}' ) } - node = p.call_expr(language, mod) - if p.tok.kind == .lpar && p.prev_tok.line_nr == p.tok.line_nr { - p.next() - pos := p.tok.pos() - args := p.call_args() - p.check(.rpar) - - mut or_kind := ast.OrKind.absent - mut or_stmts := []ast.Stmt{} - mut or_pos := p.tok.pos() - if p.tok.kind in [.not, .question] { - or_kind = if p.tok.kind == .not { .propagate_result } else { .propagate_option } + // mod.Enum.val + if p.peek_tok.kind == .dot && p.peek_token(3).kind in [.comma, .rpar] { + node = p.enum_val_expr(mod) + } else { + node = p.call_expr(language, mod) + if p.tok.kind == .lpar && p.prev_tok.line_nr == p.tok.line_nr { p.next() - } - if p.tok.kind == .key_orelse { - // `foo() or {}`` - or_kind = .block - or_stmts, or_pos = p.or_block(.with_err_var) - } - node = ast.CallExpr{ - left: node - args: args - pos: pos - scope: p.scope - or_block: ast.OrExpr{ - stmts: or_stmts - kind: or_kind - pos: or_pos + pos := p.tok.pos() + args := p.call_args() + p.check(.rpar) + + mut or_kind := ast.OrKind.absent + mut or_stmts := []ast.Stmt{} + mut or_pos := p.tok.pos() + if p.tok.kind in [.not, .question] { + or_kind = if p.tok.kind == .not { + .propagate_result + } else { + .propagate_option + } + p.next() + } + if p.tok.kind == .key_orelse { + // `foo() or {}`` + or_kind = .block + or_stmts, or_pos = p.or_block(.with_err_var) + } + node = ast.CallExpr{ + left: node + args: args + pos: pos + scope: p.scope + or_block: ast.OrExpr{ + stmts: or_stmts + kind: or_kind + pos: or_pos + } } } } @@ -2879,23 +2888,7 @@ fn (mut p Parser) name_expr() ast.Expr { } } } - // `Color.green` - mut enum_name := p.check_name() - enum_name_pos := p.prev_tok.pos() - if mod != '' { - enum_name = mod + '.' + enum_name - } else { - enum_name = p.imported_symbols[enum_name] or { p.prepend_mod(enum_name) } - } - p.check(.dot) - val := p.check_name() - p.expr_mod = '' - return ast.EnumVal{ - enum_name: enum_name - val: val - pos: enum_name_pos.extend(p.prev_tok.pos()) - mod: mod - } + return p.enum_val_expr(mod) } else if language == .js && p.peek_tok.kind == .dot && p.peek_token(2).kind == .name { // JS. function call with more than 1 dot node = p.call_expr(language, mod) @@ -2967,6 +2960,26 @@ enum OrBlockErrVarMode { with_err_var } +fn (mut p Parser) enum_val_expr(mod string) ast.EnumVal { + // `Color.green` + mut enum_name := p.check_name() + enum_name_pos := p.prev_tok.pos() + if mod != '' { + enum_name = mod + '.' + enum_name + } else { + enum_name = p.imported_symbols[enum_name] or { p.prepend_mod(enum_name) } + } + p.check(.dot) + val := p.check_name() + p.expr_mod = '' + return ast.EnumVal{ + enum_name: enum_name + val: val + pos: enum_name_pos.extend(p.prev_tok.pos()) + mod: mod + } +} + fn (mut p Parser) or_block(err_var_mode OrBlockErrVarMode) ([]ast.Stmt, token.Pos) { was_inside_or_expr := p.inside_or_expr defer { diff --git a/vlib/v/tests/fullname_enumval_as_arg_test.v b/vlib/v/tests/fullname_enumval_as_arg_test.v new file mode 100644 index 00000000000000..90f0e98cea46d0 --- /dev/null +++ b/vlib/v/tests/fullname_enumval_as_arg_test.v @@ -0,0 +1,10 @@ +import os + +fn test_main() { + wrap_reset := '\e[?7l' + os.signal_opt(os.Signal.int, fn [wrap_reset] (sig os.Signal) { + print(wrap_reset) + exit(0) + }) or {} + assert true +}