fmt: support `select` expressions (#6460)
parent
4f09ddccb4
commit
72ecc222ee
|
@ -937,7 +937,42 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
|
||||||
f.expr(node.high)
|
f.expr(node.high)
|
||||||
}
|
}
|
||||||
ast.SelectExpr {
|
ast.SelectExpr {
|
||||||
// TODO: implement this
|
f.writeln('select {')
|
||||||
|
f.indent++
|
||||||
|
for branch in node.branches {
|
||||||
|
if branch.comment.text != '' {
|
||||||
|
f.comment(branch.comment, {
|
||||||
|
inline: true
|
||||||
|
})
|
||||||
|
f.writeln('')
|
||||||
|
}
|
||||||
|
if branch.is_else {
|
||||||
|
f.write('else {')
|
||||||
|
} else {
|
||||||
|
if branch.is_timeout {
|
||||||
|
f.write('> ')
|
||||||
|
}
|
||||||
|
f.single_line_if = true
|
||||||
|
match branch.stmt as stmt {
|
||||||
|
ast.ExprStmt { f.expr(stmt.expr) }
|
||||||
|
else { f.stmt(branch.stmt) }
|
||||||
|
}
|
||||||
|
f.single_line_if = false
|
||||||
|
f.write(' {')
|
||||||
|
}
|
||||||
|
if branch.stmts.len > 0 {
|
||||||
|
f.writeln('')
|
||||||
|
f.stmts(branch.stmts)
|
||||||
|
}
|
||||||
|
f.writeln('}')
|
||||||
|
if branch.post_comments.len > 0 {
|
||||||
|
f.comments(branch.post_comments, {
|
||||||
|
inline: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.indent--
|
||||||
|
f.write('}')
|
||||||
}
|
}
|
||||||
ast.SelectorExpr {
|
ast.SelectorExpr {
|
||||||
f.expr(node.expr)
|
f.expr(node.expr)
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
import time
|
||||||
|
import sync
|
||||||
|
|
||||||
|
struct St {
|
||||||
|
a int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getint() int {
|
||||||
|
return 8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f1(ch1 chan int, ch2 chan St, ch3, ch4, ch5 chan int, sem sync.Semaphore) {
|
||||||
|
mut a := 5
|
||||||
|
select {
|
||||||
|
// pre comment
|
||||||
|
a = <-ch3 {
|
||||||
|
a = 0
|
||||||
|
}
|
||||||
|
b := <-ch2 {
|
||||||
|
a = b.a
|
||||||
|
}
|
||||||
|
ch3 <- 5 {
|
||||||
|
a = 1
|
||||||
|
}
|
||||||
|
ch2 <- St{
|
||||||
|
a: 37
|
||||||
|
} {
|
||||||
|
a = 2
|
||||||
|
}
|
||||||
|
// another comment
|
||||||
|
ch4 <- (6 + 7 * 9) {
|
||||||
|
a = 8
|
||||||
|
}
|
||||||
|
ch5 <- getint() {
|
||||||
|
a = 9
|
||||||
|
}
|
||||||
|
> 300 * time.millisecond {
|
||||||
|
a = 3
|
||||||
|
}
|
||||||
|
// post comment
|
||||||
|
}
|
||||||
|
assert a == 3
|
||||||
|
sem.post()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f2(ch1 chan St, ch2 chan int, sem sync.Semaphore) {
|
||||||
|
mut r := 23
|
||||||
|
for i in 0 .. 2 {
|
||||||
|
select {
|
||||||
|
b := <-ch1 {
|
||||||
|
r = b.a
|
||||||
|
}
|
||||||
|
ch2 <- r {
|
||||||
|
r = 17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i == 0 {
|
||||||
|
assert r == 17
|
||||||
|
} else {
|
||||||
|
assert r == 13
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sem.post()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_select_blocks() {
|
||||||
|
ch1 := chan int{cap: 1}
|
||||||
|
ch2 := chan St{}
|
||||||
|
ch3 := chan int{}
|
||||||
|
ch4 := chan int{}
|
||||||
|
ch5 := chan int{}
|
||||||
|
sem := sync.new_semaphore()
|
||||||
|
mut r := false
|
||||||
|
t := select {
|
||||||
|
b := <-ch1 {
|
||||||
|
println(b)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// no channel ready
|
||||||
|
r = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert r == true
|
||||||
|
assert t == true
|
||||||
|
go f2(ch2, ch3, sem)
|
||||||
|
n := <-ch3
|
||||||
|
assert n == 23
|
||||||
|
ch2 <- St{
|
||||||
|
a: 13
|
||||||
|
}
|
||||||
|
sem.wait()
|
||||||
|
stopwatch := time.new_stopwatch({})
|
||||||
|
go f1(ch1, ch2, ch3, ch4, ch5, sem)
|
||||||
|
sem.wait()
|
||||||
|
elapsed_ms := f64(stopwatch.elapsed()) / time.millisecond
|
||||||
|
assert elapsed_ms >= 295.0
|
||||||
|
ch1.close()
|
||||||
|
ch2.close()
|
||||||
|
mut h := 7
|
||||||
|
mut is_open := true
|
||||||
|
if select {
|
||||||
|
b := <-ch2 {
|
||||||
|
h = 0
|
||||||
|
}
|
||||||
|
ch1 <- h {
|
||||||
|
h = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
h = 2
|
||||||
|
}
|
||||||
|
} {
|
||||||
|
panic('channel is still open')
|
||||||
|
} else {
|
||||||
|
is_open = false
|
||||||
|
}
|
||||||
|
// no branch should have run
|
||||||
|
for select {
|
||||||
|
b := <-ch2 {
|
||||||
|
h = 0
|
||||||
|
}
|
||||||
|
} {
|
||||||
|
println('ch2 open')
|
||||||
|
}
|
||||||
|
println('ch2 closed')
|
||||||
|
assert h == 7
|
||||||
|
// since all channels are closed `select` should return `false`
|
||||||
|
assert is_open == false
|
||||||
|
}
|
Loading…
Reference in New Issue