Skip to content

Commit 5cb2683

Browse files
committed
v.gen.c,v.markused: fix println(ch) when ch is a channel
1 parent 0afeba5 commit 5cb2683

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

vlib/sync/channels.v

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ fn new_channel_st(n u32, st u32) &Channel {
136136
return ch
137137
}
138138

139+
pub fn (ch &Channel) auto_str(typename string) string {
140+
return 'chan $typename{cap: $ch.cap, closed: $ch.closed}'
141+
}
142+
139143
pub fn (mut ch Channel) close() {
140144
open_val := u16(0)
141145
if !C.atomic_compare_exchange_strong_u16(&ch.closed, &open_val, 1) {

vlib/v/gen/c/auto_str_methods.v

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ fn (mut g Gen) gen_str_for_type(typ ast.Type) string {
168168
ast.Interface {
169169
g.gen_str_for_interface(sym.info, styp, str_fn_name)
170170
}
171+
ast.Chan {
172+
g.gen_str_for_chan(sym.info, styp, str_fn_name)
173+
}
171174
else {
172175
verror("could not generate string method $str_fn_name for type '$styp'")
173176
}
@@ -489,6 +492,12 @@ fn (mut g Gen) gen_str_for_fn_type(info ast.FnType, styp string, str_fn_name str
489492
g.auto_str_funcs.writeln('static string ${str_fn_name}() { return _SLIT("${g.fn_decl_str(info)}");}')
490493
}
491494

495+
fn (mut g Gen) gen_str_for_chan(info ast.Chan, styp string, str_fn_name string) {
496+
elem_type_name := util.strip_main_name(g.table.get_type_name(g.unwrap_generic(info.elem_type)))
497+
g.type_definitions.writeln('static string ${str_fn_name}($styp x); // auto')
498+
g.auto_str_funcs.writeln('static string ${str_fn_name}($styp x) { return sync__Channel_auto_str(x, _SLIT("$elem_type_name")); }')
499+
}
500+
492501
[inline]
493502
fn styp_to_str_fn_name(styp string) string {
494503
return styp.replace_each(['*', '', '.', '__', ' ', '__']) + '_str'

vlib/v/markused/markused.v

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
8585
'21.clone_static',
8686
'21.first',
8787
'21.last',
88+
'21.pointers' /* TODO: handle generic methods calling array primitives more precisely in pool_test.v */,
8889
'21.reverse',
8990
'21.repeat',
9091
'21.slice',
@@ -141,7 +142,9 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
141142
all_fn_root_names << k
142143
continue
143144
}
144-
if k.ends_with('.str') {
145+
// auto generated string interpolation functions, may
146+
// call .str or .auto_str methods for user types:
147+
if k.ends_with('.str') || k.ends_with('.auto_str') {
145148
all_fn_root_names << k
146149
continue
147150
}
@@ -153,11 +156,25 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
153156
all_fn_root_names << k
154157
continue
155158
}
159+
// sync:
160+
if k == 'sync.new_channel_st' {
161+
all_fn_root_names << k
162+
continue
163+
}
164+
if k == 'sync.channel_select' {
165+
all_fn_root_names << k
166+
continue
167+
}
168+
if method_receiver_typename == '&sync.Channel' {
169+
all_fn_root_names << k
170+
continue
171+
}
156172
if k.ends_with('.lock') || k.ends_with('.unlock') || k.ends_with('.rlock')
157173
|| k.ends_with('.runlock') {
158174
all_fn_root_names << k
159175
continue
160176
}
177+
// testing framework:
161178
if pref.is_test {
162179
if k.starts_with('test_') || k.contains('.test_') {
163180
all_fn_root_names << k
@@ -169,6 +186,8 @@ pub fn mark_used(mut table ast.Table, pref &pref.Preferences, ast_files []&ast.F
169186
continue
170187
}
171188
}
189+
// public/exported functions can not be skipped,
190+
// especially when producing a shared library:
172191
if mfn.is_pub && pref.is_shared {
173192
all_fn_root_names << k
174193
continue

vlib/v/tests/channels_test.v

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
struct St1 {
2+
val int = 5
3+
another chan f64
4+
}
5+
6+
fn fn1(c chan St1) string {
7+
println('1')
8+
println(c)
9+
x := <-c
10+
println(x)
11+
return x.str()
12+
}
13+
14+
fn test_printing_of_channels() {
15+
ch := chan St1{cap: 10}
16+
fch := chan f64{cap: 100}
17+
ch <- St1{
18+
val: 1000
19+
another: fch
20+
}
21+
res := (go fn1(ch)).wait()
22+
println(res)
23+
println(ch)
24+
assert res.str().contains('another: ')
25+
assert ch.str() == 'chan St1{cap: 10, closed: 0}'
26+
assert fch.str() == 'chan f64{cap: 100, closed: 0}'
27+
fch.close()
28+
assert fch.str() == 'chan f64{cap: 100, closed: 1}'
29+
}

0 commit comments

Comments
 (0)