mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
gen: fix autogeneration of .str() methods for sumtypes that have child types with custom .str() methods
This commit is contained in:
parent
74115fe70a
commit
4065a0327a
@ -600,11 +600,13 @@ fn (mut g Gen) gen_str_for_union_sum_type(info table.SumType, styp string, str_f
|
|||||||
g.gen_str_for_type(typ)
|
g.gen_str_for_type(typ)
|
||||||
}
|
}
|
||||||
sym := g.table.get_type_symbol(typ)
|
sym := g.table.get_type_symbol(typ)
|
||||||
if sym.kind == .struct_ {
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
|
deref := if sym_has_str_method && str_method_expects_ptr { ' ' } else { '*' }
|
||||||
|
if sym.kind == .struct_ && !sym_has_str_method {
|
||||||
func_name = 'indent_$func_name'
|
func_name = 'indent_$func_name'
|
||||||
}
|
}
|
||||||
g.auto_str_funcs.write('\t\tcase $typ: return _STR("${clean_sum_type_v_type_name}($value_fmt)", 2, ${func_name}(*($typ_str*)x._$sym.cname')
|
g.auto_str_funcs.write('\t\tcase $typ: return _STR("${clean_sum_type_v_type_name}($value_fmt)", 2, ${func_name}(${deref}($typ_str*)x._$sym.cname')
|
||||||
if sym.kind == .struct_ {
|
if sym.kind == .struct_ && !sym_has_str_method {
|
||||||
g.auto_str_funcs.write(', indent_count')
|
g.auto_str_funcs.write(', indent_count')
|
||||||
}
|
}
|
||||||
g.auto_str_funcs.writeln('));')
|
g.auto_str_funcs.writeln('));')
|
||||||
|
43
vlib/v/tests/sumtype_str_for_subtypes_with_str_test.v
Normal file
43
vlib/v/tests/sumtype_str_for_subtypes_with_str_test.v
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Test whether a sumtype that has multiple subtypes,
|
||||||
|
// some with custom .str() methods, can be converted to a string,
|
||||||
|
// i.e. whether its own autogenerated .str() method will work.
|
||||||
|
// NB: Dictionary.str() calls $v.str() in the string interpolation,
|
||||||
|
// which in turn can call Dictionary.str(), i.e. they are mutually
|
||||||
|
// recursive.
|
||||||
|
type Object = Dictionary | Stream | bool | f32 | int | string
|
||||||
|
|
||||||
|
struct Dictionary {
|
||||||
|
items map[string]Object
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Stream {
|
||||||
|
mut:
|
||||||
|
content string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (dict Dictionary) str() string {
|
||||||
|
mut temp := []string{}
|
||||||
|
for k, v in dict.items {
|
||||||
|
temp << ' << "$k": ' + v.str().replace('\n', ' ')
|
||||||
|
}
|
||||||
|
return '\n' + temp.join('\n') + '\n'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_str_of_sumtype_works() {
|
||||||
|
o := Object(Dictionary{
|
||||||
|
items: {
|
||||||
|
'abc': Object(Stream{
|
||||||
|
content: 'xyz'
|
||||||
|
})
|
||||||
|
'aaa': Object(int(321))
|
||||||
|
'bbb': Object(f32(3.14))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
so := o.str()
|
||||||
|
println(so)
|
||||||
|
assert so.starts_with('Object(')
|
||||||
|
assert so.contains('<< "abc": Object(Stream{')
|
||||||
|
assert so.contains('<< "aaa": Object(321)')
|
||||||
|
assert so.contains('<< "bbb": Object(3.14')
|
||||||
|
assert so.ends_with(')')
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user