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:
parent
9e78724a41
commit
148d57827c
@ -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
|
||||
|
@ -0,0 +1,13 @@
|
||||
struct Abc {
|
||||
a []struct {
|
||||
b string
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
abc := Abc{
|
||||
a: [struct {'this is b'}]
|
||||
}
|
||||
|
||||
dump(abc)
|
||||
}
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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{
|
||||
|
Loading…
Reference in New Issue
Block a user