cgen: make generics printable (#6700)

pull/6703/head
Daniel Däschle 2020-10-31 18:43:06 +01:00 committed by GitHub
parent db59585a51
commit 9fdf04b7ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 17 deletions

View File

@ -314,7 +314,7 @@ pub fn (c &Checker) get_default_fmt(ftyp table.Type, typ table.Type) byte {
} else if typ.is_pointer() {
return `p`
} else {
mut sym := c.table.get_type_symbol(ftyp)
mut sym := c.table.get_type_symbol(c.unwrap_generic(ftyp))
if sym.kind == .alias {
// string aliases should be printable
info := sym.info as table.Alias

View File

@ -8,7 +8,7 @@ import v.util
// already generated styp, reuse it
fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string {
mut sym := g.table.get_type_symbol(typ)
mut sym := g.table.get_type_symbol(g.unwrap_generic(typ))
mut str_fn_name := styp_to_str_fn_name(styp)
if sym.info is table.Alias {
sym = g.table.get_type_symbol((sym.info as table.Alias).parent_type)

View File

@ -336,30 +336,31 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
if node.precisions[i] != 987698 {
fmt = '${fmt}.${node.precisions[i]}'
}
typ := g.unwrap_generic(node.expr_types[i])
if fspec == `s` {
if node.fwidths[i] == 0 {
g.write('.*s')
} else {
g.write('*.*s')
}
} else if node.expr_types[i].is_float() {
} else if typ.is_float() {
g.write('$fmt${fspec:c}')
} else if node.expr_types[i].is_pointer() {
} else if typ.is_pointer() {
if fspec == `p` {
g.write('${fmt}p')
} else {
g.write('$fmt"PRI${fspec:c}PTR"')
}
} else if node.expr_types[i].is_int() {
} else if typ.is_int() {
if fspec == `c` {
g.write('${fmt}c')
} else {
g.write('$fmt"PRI${fspec:c}')
if node.expr_types[i] in [table.i8_type, table.byte_type] {
if typ in [table.i8_type, table.byte_type] {
g.write('8')
} else if node.expr_types[i] in [table.i16_type, table.u16_type] {
} else if typ in [table.i16_type, table.u16_type] {
g.write('16')
} else if node.expr_types[i] in [table.i64_type, table.u64_type] {
} else if typ in [table.i64_type, table.u64_type] {
g.write('64')
} else {
g.write('32')
@ -378,7 +379,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
g.write('", $num_string_parts, ')
// Build args
for i, expr in node.exprs {
if node.expr_types[i] == table.string_type {
typ := g.unwrap_generic(node.expr_types[i])
if typ == table.string_type {
if g.inside_vweb_tmpl {
g.write('vweb__filter(')
g.expr(expr)
@ -386,18 +388,17 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
} else {
g.expr(expr)
}
} else if node.expr_types[i] == table.bool_type {
} else if typ == table.bool_type {
g.expr(expr)
g.write(' ? _SLIT("true") : _SLIT("false")')
} else if node.expr_types[i].is_number() || node.expr_types[i].is_pointer() ||
node.fmts[i] == `d` {
if node.expr_types[i].is_signed() && node.fmts[i] in [`x`, `X`, `o`] {
} else if typ.is_number() || typ.is_pointer() || node.fmts[i] == `d` {
if typ.is_signed() && node.fmts[i] in [`x`, `X`, `o`] {
// convert to unsigned first befors C's integer propagation strikes
if node.expr_types[i] == table.i8_type {
if typ == table.i8_type {
g.write('(byte)(')
} else if node.expr_types[i] == table.i16_type {
} else if typ == table.i16_type {
g.write('(u16)(')
} else if node.expr_types[i] == table.int_type {
} else if typ == table.int_type {
g.write('(u32)(')
} else {
g.write('(u64)(')
@ -408,7 +409,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
g.expr(expr)
}
} else if node.fmts[i] == `s` {
g.gen_expr_to_string(expr, node.expr_types[i])
g.gen_expr_to_string(expr, typ)
} else {
g.expr(expr)
}

View File

@ -218,3 +218,16 @@ fn test_map_with_struct() {
assert a.str() == 'MapWithStruct{\n foo: {\'test\': TestStruct{\n x: 0\n }}\n}'
assert '$a' == 'MapWithStruct{\n foo: {\'test\': TestStruct{\n x: 0\n }}\n}'
}
struct ForGeneric {}
fn generic_fn_interpolation<T>(p T) string {
return '$p'
}
fn generic_fn_str<T>(p T) string {
return p.str()
}
fn test_generic_auto_str() {
s := ForGeneric{}
assert generic_fn_interpolation(s) == 'ForGeneric{}'
assert generic_fn_str(s) == 'ForGeneric{}'
}