mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
fmt: handle anon structs; tests: bring back anon struct test
This commit is contained in:
parent
972bba66d1
commit
f5001192f9
@ -316,6 +316,7 @@ pub mut:
|
||||
default_expr_typ Type
|
||||
name string
|
||||
typ Type
|
||||
anon_struct_decl StructDecl // only if the field is an anonymous struct
|
||||
}
|
||||
|
||||
pub fn (f &StructField) equals(o &StructField) bool {
|
||||
|
@ -1121,7 +1121,7 @@ pub mut:
|
||||
parent_type Type
|
||||
}
|
||||
|
||||
// human readable type name
|
||||
// human readable type name, also used by vfmt
|
||||
pub fn (t &Table) type_to_str(typ Type) string {
|
||||
return t.type_to_str_using_aliases(typ, map[string]string{})
|
||||
}
|
||||
|
@ -500,7 +500,7 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
|
||||
f.sql_stmt(node)
|
||||
}
|
||||
ast.StructDecl {
|
||||
f.struct_decl(node)
|
||||
f.struct_decl(node, false)
|
||||
}
|
||||
ast.TypeDecl {
|
||||
f.type_decl(node)
|
||||
|
@ -6,7 +6,7 @@ module fmt
|
||||
import strings
|
||||
import v.ast
|
||||
|
||||
pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
||||
pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) {
|
||||
f.attrs(node.attrs)
|
||||
if node.is_pub {
|
||||
f.write('pub ')
|
||||
@ -18,7 +18,9 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
||||
}
|
||||
f.write_language_prefix(node.language)
|
||||
name := node.name.after('.') // strip prepended module
|
||||
if !is_anon {
|
||||
f.write(name)
|
||||
}
|
||||
f.write_generic_types(node.generic_types)
|
||||
if node.fields.len == 0 && node.embeds.len == 0 && node.pos.line_nr == node.pos.last_line {
|
||||
f.writeln(' {}')
|
||||
@ -28,8 +30,11 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
||||
mut comment_aligns := []AlignInfo{}
|
||||
mut default_expr_aligns := []AlignInfo{}
|
||||
mut field_types := []string{cap: node.fields.len}
|
||||
// Calculate the alignments first
|
||||
for i, field in node.fields {
|
||||
ft := f.no_cur_mod(f.table.type_to_str_using_aliases(field.typ, f.mod2alias))
|
||||
// Handle anon structs recursively
|
||||
sym := f.table.sym(field.typ)
|
||||
field_types << ft
|
||||
attrs_len := inline_attrs_len(field.attrs)
|
||||
end_pos := field.pos.pos + field.pos.len
|
||||
@ -68,6 +73,7 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
||||
f.comments(comments, level: .indent)
|
||||
}
|
||||
}
|
||||
// Now handle each field
|
||||
mut field_align_i := 0
|
||||
mut comment_align_i := 0
|
||||
mut default_expr_align_i := 0
|
||||
@ -125,7 +131,21 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
||||
field_align = field_aligns[field_align_i]
|
||||
}
|
||||
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
|
||||
f.write(field_types[i])
|
||||
}
|
||||
f.mark_types_import_as_used(field.typ)
|
||||
attrs_len := inline_attrs_len(field.attrs)
|
||||
has_attrs := field.attrs.len > 0
|
||||
@ -174,7 +194,11 @@ pub fn (mut f Fmt) struct_decl(node ast.StructDecl) {
|
||||
}
|
||||
}
|
||||
f.comments_after_last_field(node.end_comments)
|
||||
if is_anon {
|
||||
f.write('}')
|
||||
} else {
|
||||
f.writeln('}\n')
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut f Fmt) struct_init(node ast.StructInit) {
|
||||
|
@ -26,7 +26,17 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
|
||||
defer {
|
||||
g.write(')')
|
||||
}
|
||||
if g.is_shared && !g.inside_opt_data && !g.is_arraymap_set {
|
||||
|
||||
mut is_anon := false
|
||||
if sym.kind == .struct_ {
|
||||
mut info := sym.info as ast.Struct
|
||||
|
||||
is_anon = info.is_anon
|
||||
}
|
||||
if is_anon {
|
||||
// No name needed for anon structs, C figures it out on its own.
|
||||
g.writeln('{')
|
||||
} else if g.is_shared && !g.inside_opt_data && !g.is_arraymap_set {
|
||||
mut shared_typ := node.typ.set_flag(.shared_f)
|
||||
shared_styp = g.typ(shared_typ)
|
||||
g.writeln('($shared_styp*)__dup${shared_styp}(&($shared_styp){.mtx = {0}, .val =($styp){')
|
||||
|
@ -199,6 +199,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
|
||||
mut typ := ast.Type(0)
|
||||
mut type_pos := token.Pos{}
|
||||
mut field_pos := token.Pos{}
|
||||
mut anon_struct_decl := ast.StructDecl{}
|
||||
if is_embed {
|
||||
// struct embedding
|
||||
type_pos = p.tok.pos()
|
||||
@ -237,7 +238,16 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
|
||||
}
|
||||
}
|
||||
p.inside_struct_field_decl = true
|
||||
if p.tok.kind == .key_struct {
|
||||
// Anon structs
|
||||
if p.tok.kind == .key_struct {
|
||||
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)
|
||||
}
|
||||
} else {
|
||||
typ = p.parse_type()
|
||||
}
|
||||
p.inside_struct_field_decl = false
|
||||
if typ.idx() == 0 {
|
||||
// error is set in parse_type
|
||||
@ -287,6 +297,7 @@ 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
|
||||
}
|
||||
}
|
||||
// save embeds as table fields too, it will be used in generation phase
|
||||
|
@ -413,16 +413,18 @@ fn test_struct_update() {
|
||||
assert c2.name == 'test'
|
||||
}
|
||||
|
||||
/*
|
||||
// Test anon structs
|
||||
struct Book {
|
||||
x Foo
|
||||
title string
|
||||
author struct {
|
||||
name string
|
||||
age int
|
||||
}
|
||||
|
||||
title string
|
||||
}
|
||||
|
||||
fn test_anon() {}
|
||||
*/
|
||||
fn test_anon() {
|
||||
// book := Book{author:struct{'sdf', 23}}
|
||||
// println(book.author.age)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user