| /* |
| * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. |
| */ |
| |
| package kotlinx.coroutines.internal |
| |
| import kotlinx.coroutines.* |
| import kotlin.coroutines.* |
| import kotlin.coroutines.intrinsics.* |
| import kotlin.jvm.* |
| |
| /** |
| * This is a coroutine instance that is created by [coroutineScope] builder. |
| */ |
| internal open class ScopeCoroutine<in T>( |
| context: CoroutineContext, |
| @JvmField val uCont: Continuation<T> // unintercepted continuation |
| ) : AbstractCoroutine<T>(context, true), CoroutineStackFrame { |
| final override val callerFrame: CoroutineStackFrame? get() = uCont as CoroutineStackFrame? |
| final override fun getStackTraceElement(): StackTraceElement? = null |
| final override val isScopedCoroutine: Boolean get() = true |
| |
| internal val parent: Job? get() = parentContext[Job] |
| |
| override fun afterCompletion(state: Any?) { |
| // Resume in a cancellable way by default when resuming from another context |
| uCont.intercepted().resumeCancellableWith(recoverResult(state, uCont)) |
| } |
| |
| override fun afterResume(state: Any?) { |
| // Resume direct because scope is already in the correct context |
| uCont.resumeWith(recoverResult(state, uCont)) |
| } |
| } |
| |
| internal class ContextScope(context: CoroutineContext) : CoroutineScope { |
| override val coroutineContext: CoroutineContext = context |
| // CoroutineScope is used intentionally for user-friendly representation |
| override fun toString(): String = "CoroutineScope(coroutineContext=$coroutineContext)" |
| } |