Get rid of kotlinx-coroutines usage in scripting libs and plugins

the dependency on the coroutines library caused various problems like
KT-30778, or stdlib/runtime version conflicts.
The only function used was `runBlocking`, so this change replaces it
with the internal implementation based on the similar internal thing
from the stdlib.
#KT-30778 fixed
This commit is contained in:
Ilya Chernikov
2021-07-16 11:02:17 +02:00
committed by TeamCityServer
parent 9b1de90452
commit 0cd29adcc7
20 changed files with 89 additions and 67 deletions
@@ -18,9 +18,8 @@
package kotlin.script.experimental.host
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.runBlocking
import kotlin.script.experimental.api.*
import kotlin.script.experimental.impl.internalScriptingRunSuspend
/**
* The base class for scripting host implementations
@@ -32,7 +31,9 @@ abstract class BasicScriptingHost(
/**
* The overridable wrapper for executing evaluation in a desired coroutines context
*/
open fun <T> runInCoroutineContext(block: suspend CoroutineScope.() -> T): T = runBlocking { block() }
open fun <T> runInCoroutineContext(block: suspend () -> T): T =
@Suppress("DEPRECATION_ERROR")
internalScriptingRunSuspend { block() }
/**
* The default implementation of the evaluation function
@@ -0,0 +1,45 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.script.experimental.impl
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.startCoroutine
// Copied with modifications form kotlin.coroutines.jvm.internal.runSuspend/RunSuspend
// to use as an equivalent of runBlocking without dependency on the kotlinx.coroutines
@Deprecated("For internal use only, use kotlinx.coroutines instead", level = DeprecationLevel.ERROR)
fun <T> internalScriptingRunSuspend(block: suspend () -> T) : T {
val run = InternalScriptingRunSuspend<T>()
block.startCoroutine(run)
return run.await()
}
private class InternalScriptingRunSuspend<T> : Continuation<T> {
override val context: CoroutineContext
get() = EmptyCoroutineContext
@Suppress("RESULT_CLASS_IN_RETURN_TYPE")
var result: Result<T>? = null
override fun resumeWith(result: Result<T>) = synchronized(this) {
this.result = result
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).notifyAll()
}
fun await(): T = synchronized(this) {
while (true) {
when (val result: Result<T>? = this.result) {
null -> @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).wait()
else -> break
}
}
return result!!.getOrThrow()
}
}