|  | // This file is compiled into each stepping test. | 
|  |  | 
|  | package testUtils | 
|  |  | 
|  | import kotlin.coroutines.Continuation | 
|  | import kotlin.coroutines.CoroutineContext | 
|  | import kotlin.coroutines.EmptyCoroutineContext | 
|  |  | 
|  | external interface ValueDescriptionForSteppingTests { | 
|  | var isNull: Boolean? | 
|  | var isReferenceType: Boolean? | 
|  | var valueDescription: String? | 
|  | var typeName: String? | 
|  | } | 
|  |  | 
|  | external object JSON { | 
|  | fun stringify(o: Any?): String | 
|  | } | 
|  |  | 
|  | /** | 
|  | * This function is only called from the debugger | 
|  | */ | 
|  | @JsExport | 
|  | fun makeValueDescriptionForSteppingTests(value: Any?): ValueDescriptionForSteppingTests? { | 
|  | val jsTypeName = jsTypeOf(value) | 
|  | val displayedTypeName = when (jsTypeName) { | 
|  | "undefined" -> return null | 
|  | "string", "object", "function" -> if (value == null) jsTypeName else { | 
|  | val klass = value::class | 
|  | // Fully qualified names are not yet supported in Kotlin/JS reflection | 
|  | knownFqNames[klass] ?: klass.simpleName ?: "<anonymous>" | 
|  | } | 
|  | else -> jsTypeName | 
|  | } | 
|  | return js("{}").unsafeCast<ValueDescriptionForSteppingTests>().apply { | 
|  | isNull = value == null | 
|  | isReferenceType = jsTypeName == "object" || jsTypeName == "function" | 
|  | valueDescription = when (jsTypeName) { | 
|  | "string" -> JSON.stringify(value) | 
|  | else -> value.toString() | 
|  | } | 
|  | typeName = displayedTypeName | 
|  | } | 
|  | } | 
|  |  | 
|  | private val minimalFqNames = mapOf( | 
|  | Long::class to "kotlin.Long", | 
|  | String::class to "kotlin.String", | 
|  | Array::class to "kotlin.Array", | 
|  | RuntimeException::class to "kotlin.RuntimeException", | 
|  | ArithmeticException::class to "kotlin.ArithmeticException", | 
|  | ) | 
|  |  | 
|  | private val knownFqNames = minimalFqNames + stdlibFqNames | 
|  |  | 
|  | private object EmptyContinuation: Continuation<Any?> { | 
|  | override val context: CoroutineContext | 
|  | get() = EmptyCoroutineContext | 
|  |  | 
|  | override fun resumeWith(result: Result<Any?>) { | 
|  | result.getOrThrow() | 
|  | } | 
|  | } | 
|  |  | 
|  | @JsExport | 
|  | fun makeEmptyContinuation(): dynamic = EmptyContinuation |