| // LANGUAGE: +ContextParameters |
| |
| import kotlin.coroutines.* |
| |
| typealias ContextBlock<T> = suspend context(Context<T>) T.(T) -> Unit |
| |
| var buffer = "" |
| |
| class Context<T>(private val subject : T, private val ctxName: String) { |
| |
| fun doInContext() { |
| buffer = "$ctxName:$subject" |
| } |
| |
| suspend fun execute(block: ContextBlock<T>) { |
| block(this, subject, subject) |
| } |
| } |
| |
| data class Subject(val name : String) |
| |
| suspend fun test(subject : Subject, block : ContextBlock<Subject>) = Context(subject, "my other context").execute(block) |
| |
| fun builder(c: suspend () -> Unit) { |
| c.startCoroutine(Continuation(EmptyCoroutineContext) { |
| it.getOrThrow() |
| }) |
| } |
| |
| fun box(): String { |
| val subject = Subject("John DOE") |
| builder { Context(subject,"my context").execute { contextOf<Context<Subject>>().doInContext() } } // Should output "In context <my context> with subject Subject(name=John DOE)" |
| if (buffer != "my context:Subject(name=John DOE)") return "FAIL 1: $buffer" |
| builder { test(subject) { contextOf<Context<Subject>>().doInContext() } } // Should output "In context <my other context> with subject Subject(name=John DOE)" |
| if (buffer != "my other context:Subject(name=John DOE)") return "FAIL 2: $buffer" |
| return "OK" |
| } |