Inject ambient context into Go calls

This commit is contained in:
pavel 2026-08-27 22:31:10 +02:00
commit 5085ae51aa
8 changed files with 112 additions and 9 deletions

View file

@ -116,6 +116,48 @@ fun main() { runBlocking { useContext() } }`)
}
}
func TestGoContextIsInjectedFromAmbientScope(t *testing.T) {
program, err := Parse(`package demo
import exec os.exec
fun command(): *exec.Cmd { return exec.commandContext("date") }
fun main() { runBlocking { println(command()) } }`)
if err != nil {
t.Fatal(err)
}
output, err := GenerateGo(program)
if err != nil {
t.Fatal(err)
}
for _, expected := range []string{"func command(gotlinScope *GotlinCoroutineScope) *exec.Cmd", `exec.CommandContext(gotlinScope.Context(), "date")`, "command(gotlinScope)"} {
if !strings.Contains(string(output), expected) {
t.Fatalf("missing %q:\n%s", expected, output)
}
}
call := program.Functions[0].Body[0].(ReturnStmt).Value.(CallExpr)
goCall, ok := call.Meta.Semantic.Node.(HIRGoCall)
if !ok || !goCall.InjectContext || !goCall.Variadic {
t.Fatalf("Go call context metadata = %#v", call.Meta.Semantic.Node)
}
}
func TestExplicitGoContextPreventsAmbientInjection(t *testing.T) {
program, err := Parse(`package demo
import context
import exec os.exec
fun command(ctx: context.Context): *exec.Cmd { return exec.commandContext(ctx, "date") }`)
if err != nil {
t.Fatal(err)
}
output, err := GenerateGo(program)
if err != nil {
t.Fatal(err)
}
code := string(output)
if strings.Contains(code, "func command(gotlinScope") || !strings.Contains(code, `exec.CommandContext(ctx, "date")`) {
t.Fatalf("explicit context was not preserved:\n%s", code)
}
}
func TestRunBlockingCancelsAndJoinsChildrenOnPanic(t *testing.T) {
prog, err := Parse(`package demo fun main() { runBlocking { launch { delay(1) }; panic("failed") } }`)
if err != nil {