From df39e7001cd03cde5116c6e7032742207e344acc Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Sun, 17 Jan 2021 04:39:44 +0000 Subject: [PATCH] parser: support `module:` for immutable private struct fields (#8140) --- vlib/v/ast/ast.v | 10 ++++++---- vlib/v/fmt/fmt.v | 2 ++ vlib/v/parser/struct.v | 13 +++++++++++++ vlib/v/parser/tests/struct_module_section.out | 12 ++++++++++++ vlib/v/parser/tests/struct_module_section.vv | 18 ++++++++++++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 vlib/v/parser/tests/struct_module_section.out create mode 100644 vlib/v/parser/tests/struct_module_section.vv diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 3ec290ef12..dce839ca2e 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -190,13 +190,15 @@ pub mut: pub struct StructDecl { pub: - pos token.Position - name string - gen_types []table.Type - is_pub bool + pos token.Position + name string + gen_types []table.Type + is_pub bool + // _pos fields for vfmt mut_pos int // mut: pub_pos int // pub: pub_mut_pos int // pub mut: + module_pos int // module: language table.Language is_union bool attrs []table.Attr diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 3dfed132b9..6a27f2007e 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -695,6 +695,8 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) { f.writeln('pub:') } else if i == node.pub_mut_pos { f.writeln('pub mut:') + } else if i == node.module_pos { + f.writeln('module:') } end_pos := field.pos.pos + field.pos.len comments := field.comments diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 8543ce07ee..d94c2f2039 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -92,6 +92,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { mut pub_pos := -1 mut pub_mut_pos := -1 mut global_pos := -1 + mut module_pos := -1 mut is_field_mut := false mut is_field_pub := false mut is_field_global := false @@ -156,6 +157,17 @@ fn (mut p Parser) struct_decl() ast.StructDecl { is_field_pub = true is_field_mut = true is_field_global = true + } else if p.tok.kind == .key_module { + if module_pos != -1 { + p.error('redefinition of `module` section') + return {} + } + p.next() + p.check(.colon) + module_pos = fields.len + is_field_pub = false + is_field_mut = false + is_field_global = false } for p.tok.kind == .comment { comments << p.comment() @@ -319,6 +331,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { mut_pos: mut_pos - embeds.len pub_pos: pub_pos - embeds.len pub_mut_pos: pub_mut_pos - embeds.len + module_pos: module_pos - embeds.len language: language is_union: is_union attrs: attrs diff --git a/vlib/v/parser/tests/struct_module_section.out b/vlib/v/parser/tests/struct_module_section.out new file mode 100644 index 0000000000..3bc03f75e9 --- /dev/null +++ b/vlib/v/parser/tests/struct_module_section.out @@ -0,0 +1,12 @@ +vlib/v/parser/tests/struct_module_section.vv:16:3: error: field `i` of struct `S1` is immutable + 14 | + 15 | mut s := S1{} + 16 | s.i++ + | ^ + 17 | mut s2 := S2{} + 18 | s2.j++ +vlib/v/parser/tests/struct_module_section.vv:18:4: error: field `j` of struct `S2` is immutable + 16 | s.i++ + 17 | mut s2 := S2{} + 18 | s2.j++ + | ^ diff --git a/vlib/v/parser/tests/struct_module_section.vv b/vlib/v/parser/tests/struct_module_section.vv new file mode 100644 index 0000000000..d15a49ceaf --- /dev/null +++ b/vlib/v/parser/tests/struct_module_section.vv @@ -0,0 +1,18 @@ +struct S1 { +pub mut: + v byte +module: + i int +} + +struct S2 { +module: + j int +mut: + v byte +} + +mut s := S1{} +s.i++ +mut s2 := S2{} +s2.j++