gen: fix autogeneration of .str() methods for sumtypes that have child types with custom .str() methods
							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('));') | ||||||
|  |  | ||||||
|  | @ -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