Add expression functions with context boundaries
This commit is contained in:
parent
5085ae51aa
commit
773c34f3f4
18 changed files with 391 additions and 52 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, "coroutineContext": true}
|
||||
var coroutineBuiltins = map[string]bool{"runBlocking": true, "withContext": 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 statementsUseCoroutines(fn.Body) {
|
||||
if statementsUseCoroutines(fn.Body) || (fn.ExpressionBody != nil && expressionUsesCoroutines(fn.ExpressionBody)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, class := range program.Classes {
|
||||
for _, fn := range class.Methods {
|
||||
if statementsUseCoroutines(fn.Body) {
|
||||
if statementsUseCoroutines(fn.Body) || (fn.ExpressionBody != nil && expressionUsesCoroutines(fn.ExpressionBody)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +96,9 @@ func (g *goGenerator) emitCoroutineSupport() {
|
|||
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 (scope *GotlinCoroutineScope) WithContext(ctx context.Context, block func(*GotlinCoroutineScope)) { merged,cancel:=context.WithCancel(ctx); stop:=context.AfterFunc(scope.ctx,cancel); defer stop(); defer cancel(); child:=gotlinNewCoroutineScope(merged); 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("func gotlinRunWithContext(ctx context.Context, block func(*GotlinCoroutineScope)) { scope:=gotlinNewCoroutineScope(ctx); 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 }")
|
||||
g.line("func gotlinAsync[T any](scope *GotlinCoroutineScope, block func(*GotlinCoroutineScope) T) *GotlinDeferred[T] { deferred:=&GotlinDeferred[T]{done:make(chan struct{})}; scope.Launch(func(child *GotlinCoroutineScope){defer close(deferred.done);defer func(){if value:=recover();value!=nil{deferred.failure=value;scope.fail(value)}}();deferred.value=block(child)}); return deferred }")
|
||||
g.line("func (deferred *GotlinDeferred[T]) await() T { <-deferred.done; if deferred.failure!=nil{panic(deferred.failure)}; return deferred.value }")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue