From a132d97926d367973290d807e952a6e8320eb690 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 11 Nov 2024 18:23:15 +0800 Subject: [PATCH] parser: fix struct field name using keyword (fix #22826) (#22829) --- vlib/v/parser/expr.v | 5 +- vlib/v/parser/struct.v | 10 +- .../struct_field_name_using_keyword_test.v | 103 ++++++++++++++++++ 3 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 vlib/v/tests/structs/struct_field_name_using_keyword_test.v diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index 7b5a8094b..bbfbe197c 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -615,7 +615,7 @@ fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_ident bo } } } - } else if p.tok.kind == .key_as { + } else if p.tok.kind == .key_as && p.tok.line_nr == p.prev_tok.line_nr { // sum type as cast `x := SumType as Variant` if !p.inside_asm { pos := p.tok.pos() @@ -649,7 +649,8 @@ fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_ident bo pos: pos is_stmt: true } - } else if p.tok.kind.is_infix() && !(p.tok.kind in [.minus, .amp, .mul] + } else if p.tok.kind.is_infix() + && !(p.tok.kind in [.minus, .amp, .mul, .key_as, .key_in, .key_is] && p.tok.line_nr != p.prev_tok.line_nr) { // continue on infix expr node = p.infix_expr(node) diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 669b0e966..72f70bcf7 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -122,7 +122,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { end_comments = p.eat_comments(same_line: true) break } - if p.tok.kind == .key_pub { + if p.tok.kind == .key_pub && p.peek_tok.kind in [.key_mut, .colon] { p.next() if p.tok.kind == .key_mut { if pub_mut_pos != -1 { @@ -145,7 +145,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { is_field_global = false } p.check(.colon) - } else if p.tok.kind == .key_mut { + } else if p.tok.kind == .key_mut && p.peek_tok.kind == .colon { if mut_pos != -1 { p.error('redefinition of `mut` section') return ast.StructDecl{} @@ -156,7 +156,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { is_field_pub = false is_field_mut = true is_field_global = false - } else if p.tok.kind == .key_global { + } else if p.tok.kind == .key_global && p.peek_tok.kind == .colon { if global_pos != -1 { p.error('redefinition of `global` section') return ast.StructDecl{} @@ -167,7 +167,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { is_field_pub = true is_field_mut = true is_field_global = true - } else if p.tok.kind == .key_module { + } else if p.tok.kind == .key_module && p.peek_tok.kind == .colon { if module_pos != -1 { p.error('redefinition of `module` section') return ast.StructDecl{} @@ -184,7 +184,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { field_start_pos := p.tok.pos() mut is_field_volatile := false mut is_field_deprecated := false - if p.tok.kind == .key_volatile { + if p.tok.kind == .key_volatile && p.peek_token(2).line_nr == p.tok.line_nr { p.next() is_field_volatile = true } diff --git a/vlib/v/tests/structs/struct_field_name_using_keyword_test.v b/vlib/v/tests/structs/struct_field_name_using_keyword_test.v new file mode 100644 index 000000000..97c182c6c --- /dev/null +++ b/vlib/v/tests/structs/struct_field_name_using_keyword_test.v @@ -0,0 +1,103 @@ +module main + +struct Keywords { + import u8 + struct u8 + implements u8 + union u8 + interface u8 + enum u8 + const u8 + type u8 + fn u8 + return u8 + select u8 + match u8 + or u8 + if u8 + else u8 + goto u8 + assert u8 + for u8 + break u8 + continue u8 + unsafe u8 + defer u8 + go u8 + spawn u8 + rlock u8 + lock u8 + as u8 + in u8 + is u8 + nil u8 + none u8 + static u8 + shared u8 + atomic u8 + dump u8 + sizeof u8 + typeof u8 + isreftype u8 + asm u8 + module u8 + true u8 + false u8 + pub u8 + mut u8 + volatile u8 + global u8 +} + +fn test_struct_field_name_using_keyword() { + a := Keywords{ + import: 12 + struct: 12 + implements: 12 + union: 12 + interface: 12 + enum: 12 + const: 12 + type: 12 + fn: 12 + return: 12 + select: 12 + match: 12 + or: 12 + if: 12 + else: 12 + goto: 12 + assert: 12 + for: 12 + break: 12 + continue: 12 + unsafe: 12 + defer: 12 + go: 12 + spawn: 12 + rlock: 12 + lock: 12 + as: 12 + in: 12 + is: 12 + nil: 12 + none: 12 + static: 12 + shared: 12 + atomic: 12 + dump: 12 + sizeof: 12 + typeof: 12 + isreftype: 12 + asm: 12 + module: 12 + true: 12 + false: 12 + pub: 12 + mut: 12 + volatile: 12 + global: 12 + } + println(a) + assert true +} -- 2.39.5