1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

v.gen.c,v.markused: fix println(ch) when ch is a channel

This commit is contained in:
Delyan Angelov 2021-06-01 13:37:37 +03:00
parent 0afeba5588
commit 5cb2683e97
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
4 changed files with 62 additions and 1 deletions

View File

@ -136,6 +136,10 @@ fn new_channel_st(n u32, st u32) &Channel {
return ch
}
pub fn (ch &Channel) auto_str(typename string) string {
return 'chan $typename{cap: $ch.cap, closed: $ch.closed}'
}
pub fn (mut ch Channel) close() {
open_val := u16(0)
if !C.atomic_compare_exchange_strong_u16(&ch.closed, &open_val, 1) {

View File

@ -168,6 +168,9 @@ fn (mut g Gen) gen_str_for_type(typ ast.Type) string {
ast.Interface {
g.gen_str_for_interface(sym.info, styp, str_fn_name)
}
ast.Chan {
g.gen_str_for_chan(sym.info, styp, str_fn_name)
}
else {
verror("could not generate string method $str_fn_name for type '$styp'")
}
@ -489,6 +492,12 @@ fn (mut g Gen) gen_str_for_fn_type(info ast.FnType, styp string, str_fn_name str
g.auto_str_funcs.writeln('static string ${str_fn_name}() { return _SLIT("${g.fn_decl_str(info)}");}')
}
fn (mut g Gen) gen_str_for_chan(info ast.Chan, styp string, str_fn_name string) {
elem_type_name := util.strip_main_name(g.table.get_type_name(g.unwrap_generic(info.elem_type)))
g.type_definitions.writeln('static string ${str_fn_name}($styp x); // auto')
g.auto_str_funcs.writeln('static string ${str_fn_name}($styp x) { return sync__Channel_auto_str(x, _SLIT("$elem_type_name")); }')
}
[inline]
fn styp_to_str_fn_name(styp string) string {
return styp.replace_each(['*', '', '.', '__', ' ', '__']) + '_str'

View File

@ -85,6 +85,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
'21.clone_static',
'21.first',
'21.last',
'21.pointers' /* TODO: handle generic methods calling array primitives more precisely in pool_test.v */,
'21.reverse',
'21.repeat',
'21.slice',
@ -141,7 +142,9 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
all_fn_root_names << k
continue
}
if k.ends_with('.str') {
// auto generated string interpolation functions, may
// call .str or .auto_str methods for user types:
if k.ends_with('.str') || k.ends_with('.auto_str') {
all_fn_root_names << k
continue
}
@ -153,11 +156,25 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
all_fn_root_names << k
continue
}
// sync:
if k == 'sync.new_channel_st' {
all_fn_root_names << k
continue
}
if k == 'sync.channel_select' {
all_fn_root_names << k
continue
}
if method_receiver_typename == '&sync.Channel' {
all_fn_root_names << k
continue
}
if k.ends_with('.lock') || k.ends_with('.unlock') || k.ends_with('.rlock')
|| k.ends_with('.runlock') {
all_fn_root_names << k
continue
}
// testing framework:
if pref.is_test {
if k.starts_with('test_') || k.contains('.test_') {
all_fn_root_names << k
@ -169,6 +186,8 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
continue
}
}
// public/exported functions can not be skipped,
// especially when producing a shared library:
if mfn.is_pub && pref.is_shared {
all_fn_root_names << k
continue

View File

@ -0,0 +1,29 @@
struct St1 {
val int = 5
another chan f64
}
fn fn1(c chan St1) string {
println('1')
println(c)
x := <-c
println(x)
return x.str()
}
fn test_printing_of_channels() {
ch := chan St1{cap: 10}
fch := chan f64{cap: 100}
ch <- St1{
val: 1000
another: fch
}
res := (go fn1(ch)).wait()
println(res)
println(ch)
assert res.str().contains('another: ')
assert ch.str() == 'chan St1{cap: 10, closed: 0}'
assert fch.str() == 'chan f64{cap: 100, closed: 0}'
fch.close()
assert fch.str() == 'chan f64{cap: 100, closed: 1}'
}