From 5258f52497aba7d2dc1e626787b85e2fca18bd88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kr=C3=BCger?= <45282134+UweKrueger@users.noreply.github.com> Date: Tue, 8 Sep 2020 00:36:05 +0200 Subject: [PATCH] fmt: add support for `chan` types and operations (#6328) --- vlib/sync/channel_opt_propagate_test.v | 4 +- vlib/v/fmt/fmt.v | 17 ++++++- vlib/v/fmt/tests/chan_ops_keep.vv | 65 ++++++++++++++++++++++++++ vlib/v/table/atypes.v | 44 +++++++++-------- 4 files changed, 106 insertions(+), 24 deletions(-) create mode 100644 vlib/v/fmt/tests/chan_ops_keep.vv diff --git a/vlib/sync/channel_opt_propagate_test.v b/vlib/sync/channel_opt_propagate_test.v index 0850ceb858..4bb4138aee 100644 --- a/vlib/sync/channel_opt_propagate_test.v +++ b/vlib/sync/channel_opt_propagate_test.v @@ -5,7 +5,7 @@ const ( ) fn get_val_from_chan(ch chan i64) ?i64 { - r := <-ch? + r := <-ch ? return r } @@ -33,7 +33,7 @@ fn test_channel_array_mut() { chs[0] <- t t = <-chs[1] } - (&sync.Channel(chs[0])).close() + chs[0].close() sem.wait() assert t == 100 + num_iterations } diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 84399b4761..ebc3373111 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -717,9 +717,17 @@ pub fn (mut f Fmt) prefix_expr_cast_expr(fexpr ast.Expr) { is_pe_amp_ce = true f.expr(ce) } + } else if fexpr is ast.CastExpr { + last := f.out.cut_last(1) + if last != '&' { + f.out.write(last) + } } if !is_pe_amp_ce { f.expr(fexpr) + if fexpr is ast.PrefixExpr { + f.or_expr(fexpr.or_block) + } } } @@ -1628,12 +1636,17 @@ fn expr_is_single_line(expr ast.Expr) bool { } pub fn (mut f Fmt) chan_init(mut it ast.ChanInit) { + info := f.table.get_type_symbol(it.typ).chan_info() if it.elem_type == 0 && it.typ > 0 { - info := f.table.get_type_symbol(it.typ).chan_info() it.elem_type = info.elem_type } + is_mut := info.is_mut + el_typ := if is_mut { it.elem_type.set_nr_muls(it.elem_type.nr_muls() - 1) } else { it.elem_type } f.write('chan ') - f.write(f.type_to_str(it.elem_type)) + if is_mut { + f.write('mut ') + } + f.write(f.type_to_str(el_typ)) f.write('{') if it.has_cap { f.write('cap: ') diff --git a/vlib/v/fmt/tests/chan_ops_keep.vv b/vlib/v/fmt/tests/chan_ops_keep.vv new file mode 100644 index 0000000000..df3d3af1da --- /dev/null +++ b/vlib/v/fmt/tests/chan_ops_keep.vv @@ -0,0 +1,65 @@ +import sync + +const ( + num_iterations = 10000 +) + +struct St { + a int +} + +fn get_val_from_chan(ch chan i64) ?i64 { + r := <-ch ? + return r +} + +fn get_val_from_chan2(ch chan i64) ?i64 { + r := <-ch or { + println('error') + return error(err) + } + return r +} + +// this function gets an array of channels for `i64` +fn do_rec_calc_send(chs []chan i64, sem sync.Semaphore) { + mut msg := '' + for { + mut s := get_val_from_chan(chs[0]) or { + msg = err.str() + break + } + s++ + chs[1] <- s + } + assert msg == 'channel closed' + sem.post() +} + +fn test_channel_array_mut() { + mut chs := [chan i64{}, chan i64{cap: 10}] + sem := sync.new_semaphore() + go do_rec_calc_send(chs, sem) + mut t := i64(100) + for _ in 0 .. num_iterations { + chs[0] <- t + t = <-chs[1] + } + (&sync.Channel(chs[0])).close() + orr := &sync.Channel(chs[0]) + chs[1].close() + ch := chan int{} + ch.close() + a := ch.cap + b := ch.len + c := ch[1].cap + d := ch[o].len + sem.wait() + assert t == 100 + num_iterations + ch2 := chan mut St{cap: 10} + go g(ch2) +} + +fn g(ch chan mut St) { + return +} diff --git a/vlib/v/table/atypes.v b/vlib/v/table/atypes.v index 7044b5485c..57f04abfe2 100644 --- a/vlib/v/table/atypes.v +++ b/vlib/v/table/atypes.v @@ -804,32 +804,36 @@ pub fn (table &Table) type_to_str(t Type) string { map_start = 'map[string]' } if sym.kind == .chan || 'chan_' in res { - res = res.replace('chan_', '') + res = res.replace('chan_', 'chan ') } // mod.submod.submod2.Type => submod2.Type - if res.contains('.') { - vals := res.split('.') - if vals.len > 2 { - res = vals[vals.len - 2] + '.' + vals[vals.len - 1] + mut parts := res.split(' ') + for i, _ in parts { + if parts[i].contains('.') { + vals := parts[i].split('.') + if vals.len > 2 { + parts[i] = vals[vals.len - 2] + '.' + vals[vals.len - 1] + } + if parts[i].starts_with(table.cmod_prefix) || + (sym.kind == .array && parts[i].starts_with('[]' + table.cmod_prefix)) { + parts[i] = parts[i].replace_once(table.cmod_prefix, '') + } + if sym.kind == .array && !parts[i].starts_with('[]') { + parts[i] = '[]' + parts[i] + } + if sym.kind == .map && !parts[i].starts_with('map') { + parts[i] = map_start + parts[i] + } } - if res.starts_with(table.cmod_prefix) || - (sym.kind == .array && res.starts_with('[]' + table.cmod_prefix)) { - res = res.replace_once(table.cmod_prefix, '') + if parts[i].contains('_mut') { + parts[i] = 'mut ' + parts[i].replace('_mut', '') } - if sym.kind == .array && !res.starts_with('[]') { - res = '[]' + res - } - if sym.kind == .map && !res.starts_with('map') { - res = map_start + res - } - if sym.kind == .chan && !res.starts_with('chan') { - res = 'chan ' + res + nr_muls := t.nr_muls() + if nr_muls > 0 { + parts[i] = strings.repeat(`&`, nr_muls) + parts[i] } } - nr_muls := t.nr_muls() - if nr_muls > 0 { - res = strings.repeat(`&`, nr_muls) + res - } + res = parts.join(' ') if t.has_flag(.optional) { if sym.kind == .void { res = '?'