cgen: fix `dump(x)` with `fn (x &Type) str() string {`
parent
24ffc1ffb2
commit
90ba856107
|
@ -506,6 +506,7 @@ fn styp_to_str_fn_name(styp string) string {
|
||||||
return styp.replace_each(['*', '', '.', '__', ' ', '__']) + '_str'
|
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) {
|
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 str_method_expects_ptr != is_elem_ptr {
|
||||||
if 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
|
// custom methods management
|
||||||
has_custom_str := sym.has_method('str')
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
mut field_styp := g.typ(field.typ).replace('*', '')
|
sftyp := g.typ(field.typ)
|
||||||
field_styp_fn_name := if has_custom_str {
|
mut field_styp := sftyp.replace('*', '')
|
||||||
|
field_styp_fn_name := if sym_has_str_method {
|
||||||
'${field_styp}_str'
|
'${field_styp}_str'
|
||||||
} else {
|
} else {
|
||||||
g.get_str_fn(field.typ)
|
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)}=')
|
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 {
|
if field.typ in ast.cptr_types {
|
||||||
func = '(voidptr) it.$field.name'
|
func = '(voidptr) it.$field.name'
|
||||||
} else if field.typ.is_ptr() {
|
} 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_builder.writeln('}')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn struct_auto_str_func1(sym &ast.TypeSymbol, field_type ast.Type, fn_name string, field_name string) string {
|
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 {
|
||||||
has_custom_str, expects_ptr, _ := sym.str_method_info()
|
deref, _ := deref_kind(expects_ptr, field_type.is_ptr(), field_type)
|
||||||
if sym.kind == .enum_ {
|
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) {
|
} else if should_use_indent_func(sym.kind) {
|
||||||
mut obj := 'it.${c_name(field_name)}'
|
obj := 'it.${c_name(field_name)}'
|
||||||
if field_type.is_ptr() && !expects_ptr {
|
|
||||||
obj = '*$obj'
|
|
||||||
}
|
|
||||||
if has_custom_str {
|
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] {
|
} else if sym.kind in [.array, .array_fixed, .map, .sum_type] {
|
||||||
if has_custom_str {
|
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 {
|
} else if sym.kind == .function {
|
||||||
return '${fn_name}()'
|
return '${fn_name}()'
|
||||||
} else {
|
} else {
|
||||||
if sym.kind == .chan {
|
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)}'
|
mut method_str := 'it.${c_name(field_name)}'
|
||||||
if sym.kind == .bool {
|
if sym.kind == .bool {
|
||||||
|
|
|
@ -21,10 +21,12 @@ fn (mut g Gen) dump_expr_definitions() {
|
||||||
mut dump_typedefs := map[string]bool{}
|
mut dump_typedefs := map[string]bool{}
|
||||||
mut dump_fns := strings.new_builder(100)
|
mut dump_fns := strings.new_builder(100)
|
||||||
for dump_type, cname in g.table.dumps {
|
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)
|
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'
|
mut str_dumparg_type := '$cname$ptr_asterisk'
|
||||||
if dump_sym.kind == .function {
|
if dump_sym.kind == .function {
|
||||||
fninfo := dump_sym.info as ast.FnType
|
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_typedefs['typedef $str_tdef;'] = true
|
||||||
}
|
}
|
||||||
dump_fn_name := '_v_dump_expr_$cname' + (if is_ptr { '_ptr' } else { '' })
|
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)
|
dump_fns)
|
||||||
{
|
{
|
||||||
continue
|
continue
|
||||||
|
@ -52,8 +54,8 @@ fn (mut g Gen) dump_expr_definitions() {
|
||||||
if is_ptr {
|
if is_ptr {
|
||||||
dump_fns.writeln('\teprint(${ctoslit('&')});')
|
dump_fns.writeln('\teprint(${ctoslit('&')});')
|
||||||
}
|
}
|
||||||
dump_fns.writeln('\teprintln(${to_string_fn_name}(${ptr_asterisk}x));')
|
dump_fns.writeln('\teprintln(${to_string_fn_name}(${deref}dump_arg));')
|
||||||
dump_fns.writeln('\treturn x;')
|
dump_fns.writeln('\treturn dump_arg;')
|
||||||
dump_fns.writeln('}')
|
dump_fns.writeln('}')
|
||||||
}
|
}
|
||||||
for tdef, _ in dump_typedefs {
|
for tdef, _ in dump_typedefs {
|
||||||
|
|
|
@ -20,3 +20,50 @@ fn test_dump_of_functions() {
|
||||||
assert foo == x
|
assert foo == x
|
||||||
assert y == zoo
|
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