Infer coroutine effects automatically
This commit is contained in:
parent
bac1183593
commit
5b30e49486
15 changed files with 339 additions and 103 deletions
|
|
@ -5,17 +5,17 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
var coroutineBuiltins = map[string]bool{"runBlocking": true, "coroutineScope": true, "launch": true, "async": true, "delay": true, "withTimeout": true, "isActive": true}
|
||||
var coroutineBuiltins = map[string]bool{"runBlocking": true, "coroutineScope": true, "launch": true, "async": true, "delay": true, "withTimeout": true, "isActive": true, "coroutineContext": true}
|
||||
|
||||
func programUsesCoroutines(program *Program) bool {
|
||||
for _, fn := range program.Functions {
|
||||
if fn.Suspend || statementsUseCoroutines(fn.Body) {
|
||||
if statementsUseCoroutines(fn.Body) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, class := range program.Classes {
|
||||
for _, fn := range class.Methods {
|
||||
if fn.Suspend || statementsUseCoroutines(fn.Body) {
|
||||
if statementsUseCoroutines(fn.Body) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -94,6 +94,7 @@ func (g *goGenerator) emitCoroutineSupport() {
|
|||
g.line("func (scope *GotlinCoroutineScope) Scope(block func(*GotlinCoroutineScope)) { child:=gotlinNewCoroutineScope(scope.ctx); defer child.cancel(); defer func(){if value:=recover();value!=nil{child.cancel();child.workers.Wait();panic(value)}}(); block(child); child.wait() }")
|
||||
g.line("func (scope *GotlinCoroutineScope) Delay(ms int) { timer:=time.NewTimer(time.Duration(ms)*time.Millisecond); defer timer.Stop(); select { case <-timer.C: case <-scope.ctx.Done(): panic(scope.ctx.Err()) } }")
|
||||
g.line("func (scope *GotlinCoroutineScope) IsActive() bool { return scope.ctx.Err()==nil }")
|
||||
g.line("func (scope *GotlinCoroutineScope) Context() context.Context { return scope.ctx }")
|
||||
g.line("func (scope *GotlinCoroutineScope) WithTimeout(ms int, block func(*GotlinCoroutineScope)) { ctx,cancel:=context.WithTimeout(scope.ctx,time.Duration(ms)*time.Millisecond); defer cancel(); child:=gotlinNewCoroutineScope(ctx); defer child.cancel(); block(child); child.wait() }")
|
||||
g.line("func gotlinRunBlocking(block func(*GotlinCoroutineScope)) { scope:=gotlinNewCoroutineScope(context.Background()); defer scope.cancel(); defer func(){if value:=recover();value!=nil{scope.cancel();scope.workers.Wait();panic(value)}}(); block(scope); scope.wait() }")
|
||||
g.line("type GotlinDeferred[T any] struct { done chan struct{}; value T; failure any }")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue