cgen: fix autostr of shared fields (#14455)
parent
a52fbc5e51
commit
46f94e8d68
|
@ -910,7 +910,16 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri
|
||||||
fn_body.writeln('\tstring res = str_intp( ${info.fields.len * 4 + 3}, _MOV((StrIntpData[]){')
|
fn_body.writeln('\tstring res = str_intp( ${info.fields.len * 4 + 3}, _MOV((StrIntpData[]){')
|
||||||
fn_body.writeln('\t\t{_SLIT("$clean_struct_v_type_name{\\n"), 0, {.d_c=0}},')
|
fn_body.writeln('\t\t{_SLIT("$clean_struct_v_type_name{\\n"), 0, {.d_c=0}},')
|
||||||
for i, field in info.fields {
|
for i, field in info.fields {
|
||||||
mut ptr_amp := if field.typ.is_ptr() { '&' } else { '' }
|
ftyp_noshared := if field.typ.has_flag(.shared_f) {
|
||||||
|
field.typ.deref().clear_flag(.shared_f)
|
||||||
|
} else {
|
||||||
|
field.typ
|
||||||
|
}
|
||||||
|
mut ptr_amp := if ftyp_noshared.is_ptr() {
|
||||||
|
'&'
|
||||||
|
} else {
|
||||||
|
''
|
||||||
|
}
|
||||||
base_fmt := g.type_to_fmt(g.unwrap_generic(field.typ))
|
base_fmt := g.type_to_fmt(g.unwrap_generic(field.typ))
|
||||||
|
|
||||||
// manage prefix and quote symbol for the filed
|
// manage prefix and quote symbol for the filed
|
||||||
|
@ -933,7 +942,7 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri
|
||||||
|
|
||||||
// custom methods management
|
// custom methods management
|
||||||
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
sftyp := g.typ(field.typ)
|
sftyp := g.typ(ftyp_noshared)
|
||||||
mut field_styp := sftyp.replace('*', '')
|
mut field_styp := sftyp.replace('*', '')
|
||||||
field_styp_fn_name := if sym_has_str_method {
|
field_styp_fn_name := if sym_has_str_method {
|
||||||
mut field_fn_name := '${field_styp}_str'
|
mut field_fn_name := '${field_styp}_str'
|
||||||
|
@ -943,7 +952,7 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri
|
||||||
}
|
}
|
||||||
field_fn_name
|
field_fn_name
|
||||||
} else {
|
} else {
|
||||||
g.get_str_fn(field.typ)
|
g.get_str_fn(ftyp_noshared)
|
||||||
}
|
}
|
||||||
|
|
||||||
// manage the fact hat with float we use always the g representation
|
// manage the fact hat with float we use always the g representation
|
||||||
|
@ -960,7 +969,7 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri
|
||||||
if field.typ in ast.cptr_types {
|
if field.typ in ast.cptr_types {
|
||||||
func = '(voidptr) it.$field.name'
|
func = '(voidptr) it.$field.name'
|
||||||
caller_should_free = false
|
caller_should_free = false
|
||||||
} else if field.typ.is_ptr() {
|
} else if ftyp_noshared.is_ptr() {
|
||||||
// reference types can be "nil"
|
// reference types can be "nil"
|
||||||
funcprefix += 'isnil(it.${c_name(field.name)})'
|
funcprefix += 'isnil(it.${c_name(field.name)})'
|
||||||
funcprefix += ' ? _SLIT("nil") : '
|
funcprefix += ' ? _SLIT("nil") : '
|
||||||
|
@ -999,34 +1008,35 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, styp string, str_fn_name stri
|
||||||
fn_body.writeln('\t}));')
|
fn_body.writeln('\t}));')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn struct_auto_str_func(sym &ast.TypeSymbol, field_type ast.Type, fn_name string, field_name string, has_custom_str bool, expects_ptr bool) (string, bool) {
|
fn struct_auto_str_func(sym &ast.TypeSymbol, _field_type ast.Type, fn_name string, field_name string, has_custom_str bool, expects_ptr bool) (string, bool) {
|
||||||
$if trace_autostr ? {
|
$if trace_autostr ? {
|
||||||
eprintln('> struct_auto_str_func: $sym.name | field_type.debug() | $fn_name | $field_name | $has_custom_str | $expects_ptr')
|
eprintln('> struct_auto_str_func: $sym.name | field_type.debug() | $fn_name | $field_name | $has_custom_str | $expects_ptr')
|
||||||
}
|
}
|
||||||
|
field_type := if _field_type.has_flag(.shared_f) { _field_type.deref() } else { _field_type }
|
||||||
|
sufix := if field_type.has_flag(.shared_f) { '->val' } else { '' }
|
||||||
deref, _ := deref_kind(expects_ptr, field_type.is_ptr(), field_type)
|
deref, _ := deref_kind(expects_ptr, field_type.is_ptr(), field_type)
|
||||||
if sym.kind == .enum_ {
|
if sym.kind == .enum_ {
|
||||||
return '${fn_name}(${deref}it.${c_name(field_name)})', true
|
return '${fn_name}(${deref}it.${c_name(field_name)})', true
|
||||||
} else if should_use_indent_func(sym.kind) {
|
} else if should_use_indent_func(sym.kind) {
|
||||||
obj := 'it.${c_name(field_name)}'
|
obj := '${deref}it.${c_name(field_name)}$sufix'
|
||||||
if has_custom_str {
|
if has_custom_str {
|
||||||
return '${fn_name}($deref$obj)', true
|
return '${fn_name}($obj)', true
|
||||||
}
|
}
|
||||||
return 'indent_${fn_name}($deref$obj, indent_count + 1)', true
|
return 'indent_${fn_name}($obj, indent_count + 1)', true
|
||||||
} else if sym.kind in [.array, .array_fixed, .map, .sum_type] {
|
} else if sym.kind in [.array, .array_fixed, .map, .sum_type] {
|
||||||
|
obj := '${deref}it.${c_name(field_name)}$sufix'
|
||||||
if has_custom_str {
|
if has_custom_str {
|
||||||
return '${fn_name}(${deref}it.${c_name(field_name)})', true
|
return '${fn_name}($obj)', true
|
||||||
}
|
}
|
||||||
return 'indent_${fn_name}(${deref}it.${c_name(field_name)}, indent_count + 1)', true
|
return 'indent_${fn_name}($obj, indent_count + 1)', true
|
||||||
} else if sym.kind == .function {
|
} else if sym.kind == .function {
|
||||||
return '${fn_name}()', true
|
return '${fn_name}()', true
|
||||||
|
} else if sym.kind == .chan {
|
||||||
|
return '${fn_name}(${deref}it.${c_name(field_name)}$sufix)', true
|
||||||
} else {
|
} else {
|
||||||
if sym.kind == .chan {
|
|
||||||
return '${fn_name}(${deref}it.${c_name(field_name)})', true
|
|
||||||
}
|
|
||||||
mut method_str := 'it.${c_name(field_name)}'
|
mut method_str := 'it.${c_name(field_name)}'
|
||||||
mut caller_should_free := false
|
|
||||||
if sym.kind == .bool {
|
if sym.kind == .bool {
|
||||||
method_str += ' ? _SLIT("true") : _SLIT("false")'
|
return '$method_str ? _SLIT("true") : _SLIT("false")', false
|
||||||
} else if (field_type.is_int_valptr() || field_type.is_float_valptr())
|
} else if (field_type.is_int_valptr() || field_type.is_float_valptr())
|
||||||
&& field_type.is_ptr() && !expects_ptr {
|
&& field_type.is_ptr() && !expects_ptr {
|
||||||
// ptr int can be "nil", so this needs to be casted to a string
|
// ptr int can be "nil", so this needs to be casted to a string
|
||||||
|
@ -1045,6 +1055,6 @@ fn struct_auto_str_func(sym &ast.TypeSymbol, field_type ast.Type, fn_name string
|
||||||
fmt_type := StrIntpType.si_i32
|
fmt_type := StrIntpType.si_i32
|
||||||
return 'str_intp(1, _MOV((StrIntpData[]){{_SLIT0, ${u32(fmt_type) | 0xfe00}, {.d_i32 = *$method_str }}}))', true
|
return 'str_intp(1, _MOV((StrIntpData[]){{_SLIT0, ${u32(fmt_type) | 0xfe00}, {.d_i32 = *$method_str }}}))', true
|
||||||
}
|
}
|
||||||
return method_str, caller_should_free
|
return method_str, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
struct AA {
|
||||||
|
a shared []int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_shared_str() {
|
||||||
|
a := AA{
|
||||||
|
a: [1, 2]
|
||||||
|
}
|
||||||
|
assert a.str() == 'AA{\n a: [1, 2]\n}'
|
||||||
|
}
|
Loading…
Reference in New Issue