@@ -12,33 +12,49 @@ pub fn (mut b Builder) gen_auto_fn() {
1212fn (mut b Builder) gen_auto_str_fn () {
1313 mut generic_to_concrete_map := map [ast.Type][][]ast.Type{}
1414 // construct a `type_map`, to generate only one file for a module
15- mut need_auto_str_fn_type_map := map [string ][]& ast.TypeSymbol {}
15+ mut need_auto_str_fn_type_map := map [string ][]ast.Type {}
1616 mut already_gen_str_map := map [string ]bool {}
1717 for t, _ in b.table.used_features.used_str {
1818 if t == ast.no_type || t == ast.void_type {
1919 continue
2020 }
2121 s := b.table.sym (t)
22+ $if trace_auto_fn ? {
23+ dump (s.name)
24+ }
2225 has_str_method := s.has_method_with_sumtype_parent ('str' )
2326 || s.has_method_with_generic_parent ('str' )
2427 if has_str_method || s.kind == .function || s.mod == '' {
2528 continue
2629 } else {
2730 unsafe {
28- if s ! in need_auto_str_fn_type_map[s.mod] {
29- need_auto_str_fn_type_map[s.mod] << s
31+ if t ! in need_auto_str_fn_type_map[s.mod] {
32+ need_auto_str_fn_type_map[s.mod] << t
3033 }
3134 }
3235 }
3336 }
37+ $if trace_auto_fn ? {
38+ dump (need_auto_str_fn_type_map)
39+ // x := b.table.type_symbols.map(it.name).join('\n')
40+ // dump(x)
41+ // for k in b.table.type_symbols {
42+ // if k.name.contains('main.Response') {
43+ // if k.info is ast.Struct {
44+ // dump(k.info)
45+ // }
46+ // }
47+ // }
48+ }
3449
3550 if need_auto_str_fn_type_map.len > 0 {
3651 mut sb := strings.new_builder (128 )
3752 mut check_file_list := []& ast.File{}
3853 for full_mod_name, types in need_auto_str_fn_type_map {
3954 mod_name := full_mod_name.all_after_last ('.' )
4055 sb.writeln ('module ${mod_name} \n import strings' )
41- for t in types {
56+ for t_ in types {
57+ t := b.table.sym (t_)
4258 mut type_name := b.auto_fn_get_type_name (t, false ) // main.MyS[int] => MyS[T]
4359 if t.name.starts_with ('C.' ) {
4460 type_name = 'C.' + type_name
@@ -49,12 +65,19 @@ fn (mut b Builder) gen_auto_str_fn() {
4965 match t.kind {
5066 .struct {
5167 info := t.info as ast.Struct
68+ // $if trace_auto_fn ? {
69+ // dump(info)
70+ // }
5271 if info.parent_type.has_flag (.generic) {
5372 // for `post_process_generic_fns`
5473 generic_to_concrete_map[info.parent_type] << [
5574 info.concrete_types,
5675 ]
5776 }
77+ concrete_types := b.get_concrete_types (t_)
78+ if concrete_types.len > 0 {
79+ generic_to_concrete_map[t_] << concrete_types
80+ }
5881 hint := 'type=${t.idx} \n t.name=${t.name} '
5982 if type_name ! in already_gen_str_map {
6083 b.gen_str_for_struct (mut sb, type_name, type_name2 , info,
@@ -180,9 +203,11 @@ fn (mut b Builder) gen_str_for_alias(mut sb strings.Builder, alias_name string,
180203 }
181204 parent_type_name := b.table.type_to_str (info.parent_type)
182205 sb.writeln ('@[markused]\n pub fn (it ${alias_name} ) str() string {' )
183- sb.writeln ('\t parent_it := *(&${parent_type_name} (&it))' )
206+ // sb.writeln('\tparent_it := *(&${parent_type_name}(&it))')
207+ sb.writeln ('\t mut parent_it := ${parent_type_name} {}' )
208+ sb.writeln ('\t parent_it = unsafe {it}' )
184209 sb.writeln ('\t mut res := strings.new_builder(222)' )
185- sb.writeln ("\t res.write_string(' ${alias_name2} (\$ {parent_it})')" )
210+ sb.writeln ("\t res.write_string('${alias_name2} (\$ {parent_it})')" )
186211 // sb.writeln('\t// note: this can be removed after move dump beyond cgen')
187212 // sb.writeln('\tmut sb := strings.new_builder(222)')
188213 // sb.writeln('\tsb.indent(res.str())')
@@ -225,12 +250,33 @@ fn (mut b Builder) auto_fn_fix_generics(mut file ast.File, generic_to_concrete_m
225250 if file.generic_fns.len == 0 {
226251 return
227252 }
253+ $if trace_auto_fn ? {
254+ dump (generic_to_concrete_map)
255+ }
228256 for node in file.generic_fns {
257+ $if trace_auto_fn ? {
258+ dump (node.receiver.typ)
259+ }
229260 if concrete_types := generic_to_concrete_map[node.receiver.typ] {
261+ $if trace_auto_fn ? {
262+ dump (concrete_types)
263+ }
230264 fkey := node.fkey ()
231265 b.table.fn_generic_types[fkey] << concrete_types
232266 }
233267 }
234268 b.checker.change_current_file (file)
235269 b.checker.post_process_generic_fns () or {}
236270}
271+
272+ fn (mut b Builder) get_concrete_types (typ ast.Type) []ast.Type {
273+ mut concrete_types := []ast.Type{}
274+ for t in b.table.type_symbols {
275+ if t.info is ast.Struct {
276+ if t.info.parent_type == typ && t.info.concrete_types.len > 0 {
277+ concrete_types << t.info.concrete_types
278+ }
279+ }
280+ }
281+ return concrete_types
282+ }
0 commit comments