1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

parser, fmt: fix fmt in struct declarations with a fields, declared to be arrays of anonymous structs (fix #16947) (#16952)

This commit is contained in:
yuyi 2023-01-12 19:21:29 +08:00 committed by GitHub
parent 9e78724a41
commit 148d57827c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 18 deletions

View File

@ -132,18 +132,7 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
}
f.write(strings.repeat(` `, field_align.max_len - field.name.len - comments_len))
// Handle anon structs recursively
mut field_is_anon := false
sym := f.table.sym(field.typ)
if sym.kind == .struct_ {
info := sym.info as ast.Struct
field_is_anon = info.is_anon
}
if field_is_anon {
f.indent++
f.struct_decl(field.anon_struct_decl, true)
f.indent--
} else {
// If it's not an anon struct, just write the type of the field
if !f.write_anon_struct_field_decl(field.typ, field.anon_struct_decl) {
f.write(field_types[i])
}
f.mark_types_import_as_used(field.typ)
@ -201,6 +190,47 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
}
}
fn (mut f Fmt) write_anon_struct_field_decl(field_typ ast.Type, field_anon_decl ast.StructDecl) bool {
sym := f.table.sym(field_typ)
match sym.kind {
.struct_ {
info := sym.info as ast.Struct
if info.is_anon {
f.indent++
f.struct_decl(field_anon_decl, true)
f.indent--
return true
}
}
.array {
if sym.info is ast.Array {
elem_sym := f.table.sym(sym.info.elem_type)
if elem_sym.info is ast.Struct {
if elem_sym.info.is_anon {
f.write('[]'.repeat(sym.info.nr_dims))
f.write_anon_struct_field_decl(sym.info.elem_type, field_anon_decl)
return true
}
}
}
}
.array_fixed {
if sym.info is ast.ArrayFixed {
elem_sym := f.table.sym(sym.info.elem_type)
if elem_sym.info is ast.Struct {
if elem_sym.info.is_anon {
f.write('[${sym.info.size}]')
f.write_anon_struct_field_decl(sym.info.elem_type, field_anon_decl)
return true
}
}
}
}
else {}
}
return false
}
pub fn (mut f Fmt) struct_init(node ast.StructInit) {
struct_init_save := f.is_struct_init
f.is_struct_init = true

View File

@ -0,0 +1,13 @@
struct Abc {
a []struct {
b string
}
}
fn main() {
abc := Abc{
a: [struct {'this is b'}]
}
dump(abc)
}

View File

@ -434,9 +434,9 @@ pub fn (mut p Parser) parse_type() ast.Type {
}
// Anon structs
if p.tok.kind == .key_struct {
struct_decl := p.struct_decl(true)
p.anon_struct_decl = p.struct_decl(true)
// Find the registered anon struct type, it was registered above in `p.struct_decl()`
return p.table.find_type_idx(struct_decl.name)
return p.table.find_type_idx(p.anon_struct_decl.name)
}
language := p.parse_language()

View File

@ -89,6 +89,7 @@ mut:
defer_vars []ast.Ident
should_abort bool // when too many errors/warnings/notices are accumulated, should_abort becomes true, and the parser should stop
codegen_text string
anon_struct_decl ast.StructDecl
struct_init_generic_types []ast.Type
if_cond_comments []ast.Comment
script_mode bool

View File

@ -202,7 +202,6 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
mut type_pos := token.Pos{}
mut field_pos := token.Pos{}
mut option_pos := token.Pos{}
mut anon_struct_decl := ast.StructDecl{}
if is_embed {
// struct embedding
type_pos = p.tok.pos()
@ -247,9 +246,9 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
if p.tok.kind == .key_struct {
// Anon structs
if p.tok.kind == .key_struct {
anon_struct_decl = p.struct_decl(true)
p.anon_struct_decl = p.struct_decl(true)
// Find the registered anon struct type, it was registered above in `p.struct_decl()`
typ = p.table.find_type_idx(anon_struct_decl.name)
typ = p.table.find_type_idx(p.anon_struct_decl.name)
}
} else {
start_type_pos := p.tok.pos()
@ -308,8 +307,9 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
is_global: is_field_global
is_volatile: is_field_volatile
is_deprecated: is_field_deprecated
anon_struct_decl: anon_struct_decl
anon_struct_decl: p.anon_struct_decl
}
p.anon_struct_decl = ast.StructDecl{}
}
// save embeds as table fields too, it will be used in generation phase
fields << ast.StructField{