mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen,js: support [autostr: allowrecurse]
attribute, for allowing deep printing of data structures with pointer fields (trees, instead of graphs with cycles) (#16973)
This commit is contained in:
parent
7e05545a62
commit
ca000292f1
@ -860,6 +860,8 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, typ_str string,
|
||||
}
|
||||
fn_body.writeln('\tstring res = str_intp( ${(info.fields.len - field_skips.len) * 4 + 3}, _MOV((StrIntpData[]){')
|
||||
fn_body.writeln('\t\t{_SLIT("${clean_struct_v_type_name}{\\n"), 0, {.d_c=0}},')
|
||||
|
||||
allow_circular := info.attrs.any(it.name == 'autostr' && it.arg == 'allowrecurse')
|
||||
mut is_first := true
|
||||
for i, field in info.fields {
|
||||
// Skip `str:skip` fields
|
||||
@ -937,7 +939,7 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, typ_str string,
|
||||
}
|
||||
}
|
||||
// handle circular ref type of struct to the struct itself
|
||||
if styp == field_styp {
|
||||
if styp == field_styp && !allow_circular {
|
||||
fn_body.write_string('${funcprefix}_SLIT("<circular>")')
|
||||
} else {
|
||||
// manage C charptr
|
||||
|
@ -712,6 +712,7 @@ fn (mut g JsGen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name st
|
||||
|
||||
fn_builder.writeln('\tlet res = /*struct name*/new string("${clean_struct_v_type_name}{\\n")')
|
||||
|
||||
allow_circular := info.attrs.any(it.name == 'autostr' && it.arg == 'allowrecurse')
|
||||
for i, field in info.fields {
|
||||
mut ptr_amp := if field.typ.is_ptr() { '&' } else { '' }
|
||||
mut prefix := ''
|
||||
@ -758,7 +759,7 @@ fn (mut g JsGen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name st
|
||||
}
|
||||
}
|
||||
// handle circular ref type of struct to the struct itself
|
||||
if styp == field_styp {
|
||||
if styp == field_styp && !allow_circular {
|
||||
fn_builder.write_string('res.str += new string("<circular>")')
|
||||
} else {
|
||||
// manage C charptr
|
||||
|
23
vlib/v/tests/tag_autostr_allowrecurse_test.v
Normal file
23
vlib/v/tests/tag_autostr_allowrecurse_test.v
Normal file
@ -0,0 +1,23 @@
|
||||
[autostr: allowrecurse]
|
||||
struct Node {
|
||||
a &Node = unsafe { nil }
|
||||
b &Node = unsafe { nil }
|
||||
}
|
||||
|
||||
fn test_stringifying_a_value_of_a_struct_tagged_with_autostr_allowrecurse() {
|
||||
abc := &Node{
|
||||
a: &Node{
|
||||
b: &Node{}
|
||||
}
|
||||
b: &Node{
|
||||
a: &Node{}
|
||||
}
|
||||
}
|
||||
// println(abc)
|
||||
s := abc.str()
|
||||
assert !s.contains('&<circular>')
|
||||
assert s.contains('a: &Node{')
|
||||
assert s.contains('a: &nil')
|
||||
assert s.contains('b: &Node{')
|
||||
assert s.contains('b: &nil')
|
||||
}
|
Loading…
Reference in New Issue
Block a user