mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: fix dump(x)
with fn (x &Type) str() string {
This commit is contained in:
parent
24ffc1ffb2
commit
90ba856107
@ -506,6 +506,7 @@ fn styp_to_str_fn_name(styp string) string {
|
||||
return styp.replace_each(['*', '', '.', '__', ' ', '__']) + '_str'
|
||||
}
|
||||
|
||||
// deref_kind returns deref, deref_label
|
||||
fn deref_kind(str_method_expects_ptr bool, is_elem_ptr bool, typ ast.Type) (string, string) {
|
||||
if str_method_expects_ptr != is_elem_ptr {
|
||||
if is_elem_ptr {
|
||||
@ -823,9 +824,10 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri
|
||||
}
|
||||
|
||||
// custom methods management
|
||||
has_custom_str := sym.has_method('str')
|
||||
mut field_styp := g.typ(field.typ).replace('*', '')
|
||||
field_styp_fn_name := if has_custom_str {
|
||||
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||
sftyp := g.typ(field.typ)
|
||||
mut field_styp := sftyp.replace('*', '')
|
||||
field_styp_fn_name := if sym_has_str_method {
|
||||
'${field_styp}_str'
|
||||
} else {
|
||||
g.get_str_fn(field.typ)
|
||||
@ -839,7 +841,8 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri
|
||||
fn_builder.write_string('{_SLIT("$quote_str"), $g_fmt, {.${data_str(base_fmt)}=')
|
||||
}
|
||||
|
||||
mut func := struct_auto_str_func1(sym, field.typ, field_styp_fn_name, field.name)
|
||||
mut func := struct_auto_str_func1(sym, field.typ, field_styp_fn_name, field.name,
|
||||
sym_has_str_method, str_method_expects_ptr)
|
||||
if field.typ in ast.cptr_types {
|
||||
func = '(voidptr) it.$field.name'
|
||||
} else if field.typ.is_ptr() {
|
||||
@ -875,29 +878,26 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri
|
||||
fn_builder.writeln('}')
|
||||
}
|
||||
|
||||
fn struct_auto_str_func1(sym &ast.TypeSymbol, field_type ast.Type, fn_name string, field_name string) string {
|
||||
has_custom_str, expects_ptr, _ := sym.str_method_info()
|
||||
fn struct_auto_str_func1(sym &ast.TypeSymbol, field_type ast.Type, fn_name string, field_name string, has_custom_str bool, expects_ptr bool) string {
|
||||
deref, _ := deref_kind(expects_ptr, field_type.is_ptr(), field_type)
|
||||
if sym.kind == .enum_ {
|
||||
return '${fn_name}(it.${c_name(field_name)})'
|
||||
return '${fn_name}(${deref}it.${c_name(field_name)})'
|
||||
} else if should_use_indent_func(sym.kind) {
|
||||
mut obj := 'it.${c_name(field_name)}'
|
||||
if field_type.is_ptr() && !expects_ptr {
|
||||
obj = '*$obj'
|
||||
}
|
||||
obj := 'it.${c_name(field_name)}'
|
||||
if has_custom_str {
|
||||
return '${fn_name}($obj)'
|
||||
return '${fn_name}($deref$obj)'
|
||||
}
|
||||
return 'indent_${fn_name}($obj, indent_count + 1)'
|
||||
return 'indent_${fn_name}($deref$obj, indent_count + 1)'
|
||||
} else if sym.kind in [.array, .array_fixed, .map, .sum_type] {
|
||||
if has_custom_str {
|
||||
return '${fn_name}(it.${c_name(field_name)})'
|
||||
return '${fn_name}(${deref}it.${c_name(field_name)})'
|
||||
}
|
||||
return 'indent_${fn_name}(it.${c_name(field_name)}, indent_count + 1)'
|
||||
return 'indent_${fn_name}(${deref}it.${c_name(field_name)}, indent_count + 1)'
|
||||
} else if sym.kind == .function {
|
||||
return '${fn_name}()'
|
||||
} else {
|
||||
if sym.kind == .chan {
|
||||
return '${fn_name}(it.${c_name(field_name)})'
|
||||
return '${fn_name}(${deref}it.${c_name(field_name)})'
|
||||
}
|
||||
mut method_str := 'it.${c_name(field_name)}'
|
||||
if sym.kind == .bool {
|
||||
|
@ -21,10 +21,12 @@ fn (mut g Gen) dump_expr_definitions() {
|
||||
mut dump_typedefs := map[string]bool{}
|
||||
mut dump_fns := strings.new_builder(100)
|
||||
for dump_type, cname in g.table.dumps {
|
||||
to_string_fn_name := g.get_str_fn(dump_type)
|
||||
is_ptr := ast.Type(dump_type).is_ptr()
|
||||
ptr_asterisk := if is_ptr { '*' } else { '' }
|
||||
dump_sym := g.table.get_type_symbol(dump_type)
|
||||
_, str_method_expects_ptr, _ := dump_sym.str_method_info()
|
||||
is_ptr := ast.Type(dump_type).is_ptr()
|
||||
deref, _ := deref_kind(str_method_expects_ptr, is_ptr, dump_type)
|
||||
to_string_fn_name := g.get_str_fn(dump_type)
|
||||
ptr_asterisk := if is_ptr { '*' } else { '' }
|
||||
mut str_dumparg_type := '$cname$ptr_asterisk'
|
||||
if dump_sym.kind == .function {
|
||||
fninfo := dump_sym.info as ast.FnType
|
||||
@ -36,7 +38,7 @@ fn (mut g Gen) dump_expr_definitions() {
|
||||
dump_typedefs['typedef $str_tdef;'] = true
|
||||
}
|
||||
dump_fn_name := '_v_dump_expr_$cname' + (if is_ptr { '_ptr' } else { '' })
|
||||
if g.writeln_fn_header('$str_dumparg_type ${dump_fn_name}(string fpath, int line, string sexpr, $str_dumparg_type x)', mut
|
||||
if g.writeln_fn_header('$str_dumparg_type ${dump_fn_name}(string fpath, int line, string sexpr, $str_dumparg_type dump_arg)', mut
|
||||
dump_fns)
|
||||
{
|
||||
continue
|
||||
@ -52,8 +54,8 @@ fn (mut g Gen) dump_expr_definitions() {
|
||||
if is_ptr {
|
||||
dump_fns.writeln('\teprint(${ctoslit('&')});')
|
||||
}
|
||||
dump_fns.writeln('\teprintln(${to_string_fn_name}(${ptr_asterisk}x));')
|
||||
dump_fns.writeln('\treturn x;')
|
||||
dump_fns.writeln('\teprintln(${to_string_fn_name}(${deref}dump_arg));')
|
||||
dump_fns.writeln('\treturn dump_arg;')
|
||||
dump_fns.writeln('}')
|
||||
}
|
||||
for tdef, _ in dump_typedefs {
|
||||
|
@ -20,3 +20,50 @@ fn test_dump_of_functions() {
|
||||
assert foo == x
|
||||
assert y == zoo
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
struct StructWithStrMethodTakingReference {
|
||||
x int
|
||||
}
|
||||
|
||||
pub fn (t &StructWithStrMethodTakingReference) str() string {
|
||||
return 'StructWithStrMethodTakingReference{x: $t.x}'
|
||||
}
|
||||
|
||||
fn test_dump_of_type_that_has_custom_str_method_with_reference_parameter() {
|
||||
s := StructWithStrMethodTakingReference{123}
|
||||
assert dump(s).x == 123
|
||||
ps := &StructWithStrMethodTakingReference{456}
|
||||
assert dump(ps).x == 456
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
struct StructWithNormalStrMethod {
|
||||
x int
|
||||
}
|
||||
|
||||
pub fn (t StructWithNormalStrMethod) str() string {
|
||||
return 'StructWithNormalStrMethod{x: $t.x}'
|
||||
}
|
||||
|
||||
fn test_dump_of_type_that_has_normal_custom_str_method() {
|
||||
s := StructWithNormalStrMethod{123}
|
||||
assert dump(s).x == 123
|
||||
ps := &StructWithNormalStrMethod{456}
|
||||
assert dump(ps).x == 456
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
struct StructWithoutStrMethod {
|
||||
x int
|
||||
}
|
||||
|
||||
fn test_dump_of_type_that_has_no_custom_str_method() {
|
||||
s := StructWithoutStrMethod{123}
|
||||
assert dump(s).x == 123
|
||||
ps := &StructWithoutStrMethod{456}
|
||||
assert dump(ps).x == 456
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user