From d71d9ad7c009110eafe73d2fdf2db90e1b9899e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=C3=A4schle?= Date: Thu, 26 Nov 2020 23:57:03 +0100 Subject: [PATCH] =?UTF-8?q?=D1=81gen:=20print=20generic=20structs=20(#6967?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vlib/v/gen/auto_str_methods.v | 6 ++++++ vlib/v/gen/cgen.v | 7 +++---- vlib/v/tests/str_gen_test.v | 21 +++++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/vlib/v/gen/auto_str_methods.v b/vlib/v/gen/auto_str_methods.v index b31ada80561ef5..0bbe8aae1f5692 100644 --- a/vlib/v/gen/auto_str_methods.v +++ b/vlib/v/gen/auto_str_methods.v @@ -367,6 +367,12 @@ fn (mut g Gen) gen_str_for_struct(info table.Struct, styp string, str_fn_name st g.type_definitions.writeln('string indent_${str_fn_name}($styp x, int indent_count); // auto') g.auto_str_funcs.writeln('string indent_${str_fn_name}($styp x, int indent_count) {') mut clean_struct_v_type_name := styp.replace('__', '.') + if clean_struct_v_type_name.contains('_T_') { + // TODO: this is a bit hacky. styp shouldn't be even parsed with _T_ + // use something different than g.typ for styp + clean_struct_v_type_name = clean_struct_v_type_name.replace('_T_', '<').replace('_', ', ') + + '>' + } if styp.ends_with('*') { deref_typ := styp.replace('*', '') g.auto_str_funcs.writeln('\t$deref_typ *it = x;') diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 5b2df6f00dce4a..f1819d2e94e211 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -500,11 +500,10 @@ static inline $opt_el_type __Option_${styp}_popval($styp ch) { fn (g &Gen) cc_type2(t table.Type) string { sym := g.table.get_type_symbol(g.unwrap_generic(t)) mut styp := util.no_dots(sym.name) - if sym.kind == .struct_ { - info := sym.info as table.Struct - if info.generic_types.len > 0 { + if mut sym.info is table.Struct { + if sym.info.generic_types.len > 0 { mut sgtyps := '_T' - for gt in info.generic_types { + for gt in sym.info.generic_types { gts := g.table.get_type_symbol(if gt.has_flag(.generic) { g.unwrap_generic(gt) } else { gt }) sgtyps += '_$gts.name' } diff --git a/vlib/v/tests/str_gen_test.v b/vlib/v/tests/str_gen_test.v index 4a7d960f003be7..7908b11b753843 100644 --- a/vlib/v/tests/str_gen_test.v +++ b/vlib/v/tests/str_gen_test.v @@ -269,3 +269,24 @@ fn test_alias_struct() { assert t.str() == 'TestAlias($ts)' assert '$t' == 'TestAlias(TestStruct{\n x: 0\n})' } + +struct GenericStruct { + x T +} + +fn test_generic_struct() { + x := GenericStruct{} + assert '$x' == 'GenericStruct{\n x: TestStruct{\n x: 0\n }\n}' + assert x.str() == 'GenericStruct{\n x: TestStruct{\n x: 0\n }\n}' +} + +struct MultiGenericStruct { + t T + x X +} + +fn test_multi_generic_struct() { + x := MultiGenericStruct{} + assert '$x' == 'MultiGenericStruct{\n t: TestStruct{\n x: 0\n }\n x: TestStruct{\n x: 0\n }\n}' + assert x.str() == 'MultiGenericStruct{\n t: TestStruct{\n x: 0\n }\n x: TestStruct{\n x: 0\n }\n}' +}