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)
|
||||
}
|
||||
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 {
|
||||
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