Skip to content

Commit fd7986c

Browse files
authored
parser: fix recognition of mod.Enum.val inside fn args (#21908)
1 parent 6e8124f commit fd7986c

File tree

2 files changed

+67
-44
lines changed

2 files changed

+67
-44
lines changed

vlib/v/parser/parser.v

Lines changed: 57 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2774,34 +2774,43 @@ fn (mut p Parser) name_expr() ast.Expr {
27742774
got: '${p.prev_tok}'
27752775
)
27762776
}
2777-
node = p.call_expr(language, mod)
2778-
if p.tok.kind == .lpar && p.prev_tok.line_nr == p.tok.line_nr {
2779-
p.next()
2780-
pos := p.tok.pos()
2781-
args := p.call_args()
2782-
p.check(.rpar)
2783-
2784-
mut or_kind := ast.OrKind.absent
2785-
mut or_stmts := []ast.Stmt{}
2786-
mut or_pos := p.tok.pos()
2787-
if p.tok.kind in [.not, .question] {
2788-
or_kind = if p.tok.kind == .not { .propagate_result } else { .propagate_option }
2777+
// mod.Enum.val
2778+
if p.peek_tok.kind == .dot && p.peek_token(3).kind in [.comma, .rpar] {
2779+
node = p.enum_val_expr(mod)
2780+
} else {
2781+
node = p.call_expr(language, mod)
2782+
if p.tok.kind == .lpar && p.prev_tok.line_nr == p.tok.line_nr {
27892783
p.next()
2790-
}
2791-
if p.tok.kind == .key_orelse {
2792-
// `foo() or {}``
2793-
or_kind = .block
2794-
or_stmts, or_pos = p.or_block(.with_err_var)
2795-
}
2796-
node = ast.CallExpr{
2797-
left: node
2798-
args: args
2799-
pos: pos
2800-
scope: p.scope
2801-
or_block: ast.OrExpr{
2802-
stmts: or_stmts
2803-
kind: or_kind
2804-
pos: or_pos
2784+
pos := p.tok.pos()
2785+
args := p.call_args()
2786+
p.check(.rpar)
2787+
2788+
mut or_kind := ast.OrKind.absent
2789+
mut or_stmts := []ast.Stmt{}
2790+
mut or_pos := p.tok.pos()
2791+
if p.tok.kind in [.not, .question] {
2792+
or_kind = if p.tok.kind == .not {
2793+
.propagate_result
2794+
} else {
2795+
.propagate_option
2796+
}
2797+
p.next()
2798+
}
2799+
if p.tok.kind == .key_orelse {
2800+
// `foo() or {}``
2801+
or_kind = .block
2802+
or_stmts, or_pos = p.or_block(.with_err_var)
2803+
}
2804+
node = ast.CallExpr{
2805+
left: node
2806+
args: args
2807+
pos: pos
2808+
scope: p.scope
2809+
or_block: ast.OrExpr{
2810+
stmts: or_stmts
2811+
kind: or_kind
2812+
pos: or_pos
2813+
}
28052814
}
28062815
}
28072816
}
@@ -2879,23 +2888,7 @@ fn (mut p Parser) name_expr() ast.Expr {
28792888
}
28802889
}
28812890
}
2882-
// `Color.green`
2883-
mut enum_name := p.check_name()
2884-
enum_name_pos := p.prev_tok.pos()
2885-
if mod != '' {
2886-
enum_name = mod + '.' + enum_name
2887-
} else {
2888-
enum_name = p.imported_symbols[enum_name] or { p.prepend_mod(enum_name) }
2889-
}
2890-
p.check(.dot)
2891-
val := p.check_name()
2892-
p.expr_mod = ''
2893-
return ast.EnumVal{
2894-
enum_name: enum_name
2895-
val: val
2896-
pos: enum_name_pos.extend(p.prev_tok.pos())
2897-
mod: mod
2898-
}
2891+
return p.enum_val_expr(mod)
28992892
} else if language == .js && p.peek_tok.kind == .dot && p.peek_token(2).kind == .name {
29002893
// JS. function call with more than 1 dot
29012894
node = p.call_expr(language, mod)
@@ -2967,6 +2960,26 @@ enum OrBlockErrVarMode {
29672960
with_err_var
29682961
}
29692962

2963+
fn (mut p Parser) enum_val_expr(mod string) ast.EnumVal {
2964+
// `Color.green`
2965+
mut enum_name := p.check_name()
2966+
enum_name_pos := p.prev_tok.pos()
2967+
if mod != '' {
2968+
enum_name = mod + '.' + enum_name
2969+
} else {
2970+
enum_name = p.imported_symbols[enum_name] or { p.prepend_mod(enum_name) }
2971+
}
2972+
p.check(.dot)
2973+
val := p.check_name()
2974+
p.expr_mod = ''
2975+
return ast.EnumVal{
2976+
enum_name: enum_name
2977+
val: val
2978+
pos: enum_name_pos.extend(p.prev_tok.pos())
2979+
mod: mod
2980+
}
2981+
}
2982+
29702983
fn (mut p Parser) or_block(err_var_mode OrBlockErrVarMode) ([]ast.Stmt, token.Pos) {
29712984
was_inside_or_expr := p.inside_or_expr
29722985
defer {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import os
2+
3+
fn test_main() {
4+
wrap_reset := '\e[?7l'
5+
os.signal_opt(os.Signal.int, fn [wrap_reset] (sig os.Signal) {
6+
print(wrap_reset)
7+
exit(0)
8+
}) or {}
9+
assert true
10+
}

0 commit comments

Comments
 (0)