fmt: support `select` expressions (#6460)

pull/6464/head
Uwe Krüger 2020-09-23 22:22:39 +02:00 committed by GitHub
parent 4f09ddccb4
commit 72ecc222ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 164 additions and 1 deletions

View File

@ -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)

View File

@ -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
}