Skip to content

Commit 0cd29ad

Browse files
ligeeTeamCityServer
authored and
TeamCityServer
committed
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
1 parent 9b1de90 commit 0cd29ad

File tree

20 files changed

+89
-67
lines changed

20 files changed

+89
-67
lines changed

libraries/examples/scripting/jvm-maven-deps/script/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ dependencies {
77
compile(project(":kotlin-scripting-jvm"))
88
compile(project(":kotlin-scripting-dependencies"))
99
compile(project(":kotlin-scripting-dependencies-maven"))
10+
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core"))
1011
}
1112

1213
sourceSets {

libraries/scripting/common/build.gradle.kts

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ project.updateJvmTarget("1.6")
77

88
dependencies {
99
compile(kotlinStdlib())
10-
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core"))
1110
compileOnly(project(":kotlin-reflect-api"))
1211
testCompile(commonDep("junit"))
1312
}

libraries/scripting/common/src/kotlin/script/experimental/host/BasicScriptingHost.kt

+4-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@
1818

1919
package kotlin.script.experimental.host
2020

21-
import kotlinx.coroutines.CoroutineScope
22-
import kotlinx.coroutines.runBlocking
2321
import kotlin.script.experimental.api.*
22+
import kotlin.script.experimental.impl.internalScriptingRunSuspend
2423

2524
/**
2625
* The base class for scripting host implementations
@@ -32,7 +31,9 @@ abstract class BasicScriptingHost(
3231
/**
3332
* The overridable wrapper for executing evaluation in a desired coroutines context
3433
*/
35-
open fun <T> runInCoroutineContext(block: suspend CoroutineScope.() -> T): T = runBlocking { block() }
34+
open fun <T> runInCoroutineContext(block: suspend () -> T): T =
35+
@Suppress("DEPRECATION_ERROR")
36+
internalScriptingRunSuspend { block() }
3637

3738
/**
3839
* The default implementation of the evaluation function
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
3+
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
4+
*/
5+
6+
package kotlin.script.experimental.impl
7+
8+
import kotlin.coroutines.Continuation
9+
import kotlin.coroutines.CoroutineContext
10+
import kotlin.coroutines.EmptyCoroutineContext
11+
import kotlin.coroutines.startCoroutine
12+
13+
// Copied with modifications form kotlin.coroutines.jvm.internal.runSuspend/RunSuspend
14+
// to use as an equivalent of runBlocking without dependency on the kotlinx.coroutines
15+
16+
@Deprecated("For internal use only, use kotlinx.coroutines instead", level = DeprecationLevel.ERROR)
17+
fun <T> internalScriptingRunSuspend(block: suspend () -> T) : T {
18+
val run = InternalScriptingRunSuspend<T>()
19+
block.startCoroutine(run)
20+
return run.await()
21+
}
22+
23+
private class InternalScriptingRunSuspend<T> : Continuation<T> {
24+
override val context: CoroutineContext
25+
get() = EmptyCoroutineContext
26+
27+
@Suppress("RESULT_CLASS_IN_RETURN_TYPE")
28+
var result: Result<T>? = null
29+
30+
override fun resumeWith(result: Result<T>) = synchronized(this) {
31+
this.result = result
32+
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).notifyAll()
33+
}
34+
35+
fun await(): T = synchronized(this) {
36+
while (true) {
37+
when (val result: Result<T>? = this.result) {
38+
null -> @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).wait()
39+
else -> break
40+
}
41+
}
42+
return result!!.getOrThrow()
43+
}
44+
}
45+

libraries/scripting/dependencies-maven/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ dependencies {
3333
testImplementation(commonDep("junit"))
3434
testRuntimeOnly("org.slf4j:slf4j-nop:1.7.30")
3535
testImplementation(kotlin("reflect"))
36+
testImplementation(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core"))
3637
}
3738

3839
sourceSets {

libraries/scripting/dependencies/build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ project.updateJvmTarget("1.6")
88
dependencies {
99
compile(kotlinStdlib())
1010
compile(project(":kotlin-scripting-common"))
11-
testCompile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core"))
1211
testCompile(commonDep("junit"))
12+
testImplementation(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core"))
1313
}
1414

1515
sourceSets {

libraries/scripting/jvm-host-test/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ dependencies {
1818
testCompile(projectTests(":compiler:tests-common"))
1919
testCompile(project(":kotlin-scripting-compiler"))
2020
testCompile(project(":daemon-common")) // TODO: fix import (workaround for jps build)
21+
testImplementation(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core"))
2122

2223
testRuntimeOnly(project(":kotlin-compiler"))
2324
testRuntimeOnly(project(":kotlin-reflect"))

libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/repl/legacyReplCompilation.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
package kotlin.script.experimental.jvmhost.repl
77

8-
import kotlinx.coroutines.runBlocking
98
import org.jetbrains.kotlin.backend.common.push
109
import org.jetbrains.kotlin.cli.common.repl.*
1110
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmReplCompilerBase
@@ -15,6 +14,7 @@ import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzerBase
1514
import java.util.concurrent.locks.ReentrantReadWriteLock
1615
import kotlin.concurrent.write
1716
import kotlin.script.experimental.api.*
17+
import kotlin.script.experimental.impl.internalScriptingRunSuspend
1818
import kotlin.script.experimental.host.ScriptingHostConfiguration
1919
import kotlin.script.experimental.host.withDefaultsFrom
2020
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
@@ -56,7 +56,8 @@ class JvmReplCompiler(
5656
}()
5757
}
5858

59-
when (val res = runBlocking { replCompiler.compile(listOf(snippet), scriptCompilationConfiguration) }) {
59+
@Suppress("DEPRECATION_ERROR")
60+
when (val res = internalScriptingRunSuspend { replCompiler.compile(listOf(snippet), scriptCompilationConfiguration) }) {
6061
is ResultWithDiagnostics.Success -> {
6162
val lineId = LineId(codeLine.no, 0, snippet.hashCode())
6263
replCompilerState.apply {

libraries/scripting/jvm-host/src/kotlin/script/experimental/jvmhost/repl/legacyReplEvaluation.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55

66
package kotlin.script.experimental.jvmhost.repl
77

8-
import kotlinx.coroutines.runBlocking
98
import org.jetbrains.kotlin.cli.common.repl.*
109
import org.jetbrains.kotlin.cli.common.repl.ReplEvaluator
1110
import java.util.concurrent.locks.ReentrantReadWriteLock
1211
import kotlin.concurrent.write
1312
import kotlin.reflect.KClass
1413
import kotlin.script.experimental.api.*
14+
import kotlin.script.experimental.impl.internalScriptingRunSuspend
1515
import kotlin.script.experimental.jvm.BasicJvmScriptEvaluator
1616
import kotlin.script.experimental.jvm.baseClassLoader
1717
import kotlin.script.experimental.jvm.impl.KJvmCompiledScript
@@ -60,7 +60,8 @@ class JvmReplEvaluator(
6060
}
6161
}
6262

63-
val res = runBlocking { scriptEvaluator(compiledScript, currentConfiguration) }
63+
@Suppress("DEPRECATION_ERROR")
64+
val res = internalScriptingRunSuspend { scriptEvaluator(compiledScript, currentConfiguration) }
6465

6566
when (res) {
6667
is ResultWithDiagnostics.Success -> {

libraries/scripting/jvm/src/kotlin/script/experimental/jvm/impl/BridgeDependenciesResolver.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
package kotlin.script.experimental.jvm.impl
77

8-
import kotlinx.coroutines.runBlocking
98
import java.io.File
109
import kotlin.script.dependencies.Environment
1110
import kotlin.script.dependencies.ScriptContents
@@ -16,6 +15,7 @@ import kotlin.script.experimental.dependencies.ScriptDependencies
1615
import kotlin.script.experimental.dependencies.ScriptReport
1716
import kotlin.script.experimental.host.FileScriptSource
1817
import kotlin.script.experimental.host.toScriptSource
18+
import kotlin.script.experimental.impl.internalScriptingRunSuspend
1919
import kotlin.script.experimental.jvm.JvmDependency
2020
import kotlin.script.experimental.jvm.compat.mapToLegacyScriptReportPosition
2121
import kotlin.script.experimental.jvm.compat.mapToLegacyScriptReportSeverity
@@ -27,7 +27,8 @@ class BridgeDependenciesResolver(
2727
) : AsyncDependenciesResolver {
2828

2929
override fun resolve(scriptContents: ScriptContents, environment: Environment): DependenciesResolver.ResolveResult =
30-
runBlocking {
30+
@Suppress("DEPRECATION_ERROR")
31+
internalScriptingRunSuspend {
3132
resolveAsync(scriptContents, environment)
3233
}
3334

libraries/scripting/jvm/src/kotlin/script/experimental/jvm/runner.kt

+7-38
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55

66
package kotlin.script.experimental.jvm
77

8-
import kotlin.coroutines.Continuation
9-
import kotlin.coroutines.CoroutineContext
10-
import kotlin.coroutines.EmptyCoroutineContext
11-
import kotlin.coroutines.startCoroutine
12-
import kotlin.script.experimental.api.*
8+
import kotlin.script.experimental.api.ScriptCompilationConfiguration
9+
import kotlin.script.experimental.api.baseClass
10+
import kotlin.script.experimental.api.hostConfiguration
11+
import kotlin.script.experimental.api.onFailure
1312
import kotlin.script.experimental.host.createEvaluationConfigurationFromTemplate
1413
import kotlin.script.experimental.host.withDefaultsFrom
14+
import kotlin.script.experimental.impl.internalScriptingRunSuspend
1515
import kotlin.script.experimental.jvm.impl.createScriptFromClassLoader
1616

1717
@Suppress("unused") // script codegen generates a call to it
@@ -29,42 +29,11 @@ fun runCompiledScript(scriptClass: Class<*>, vararg args: String) {
2929
mainArguments(args)
3030
}
3131
}
32-
runScriptSuspend {
32+
@Suppress("DEPRECATION_ERROR")
33+
internalScriptingRunSuspend {
3334
evaluator(script, evaluationConfiguration).onFailure {
3435
it.reports.forEach(System.err::println)
3536
}
3637
}
3738
}
3839

39-
// Copied form kotlin.coroutines.jvm.internal.runSuspend/RunSuspend to create a runner without dependency on the kotlinx.coroutines
40-
private fun runScriptSuspend(block: suspend () -> Unit) {
41-
val run = RunScriptSuspend()
42-
block.startCoroutine(run)
43-
run.await()
44-
}
45-
46-
private class RunScriptSuspend : Continuation<Unit> {
47-
override val context: CoroutineContext
48-
get() = EmptyCoroutineContext
49-
50-
@Suppress("RESULT_CLASS_IN_RETURN_TYPE")
51-
var result: Result<Unit>? = null
52-
53-
override fun resumeWith(result: Result<Unit>) = synchronized(this) {
54-
this.result = result
55-
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).notifyAll()
56-
}
57-
58-
fun await() = synchronized(this) {
59-
while (true) {
60-
when (val result = this.result) {
61-
null -> @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).wait()
62-
else -> {
63-
result.getOrThrow() // throw up failure
64-
return
65-
}
66-
}
67-
}
68-
}
69-
}
70-

libraries/tools/kotlin-main-kts/build.gradle.kts

+1-2
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ dependencies {
3838
embedded(project(":kotlin-scripting-jvm-host-unshaded")) { isTransitive = false }
3939
embedded(project(":kotlin-scripting-dependencies")) { isTransitive = false }
4040
embedded("org.apache.ivy:ivy:2.5.0")
41-
embedded(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false }
42-
embedded(commonDep("org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm")) {
41+
embedded(commonDep("org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm")) {
4342
isTransitive = false
4443
attributes {
4544
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))

libraries/tools/kotlin-main-kts/src/org/jetbrains/kotlin/mainKts/scriptDef.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
package org.jetbrains.kotlin.mainKts
77

8-
import kotlinx.coroutines.runBlocking
98
import org.jetbrains.kotlin.mainKts.impl.Directories
109
import org.jetbrains.kotlin.mainKts.impl.IvyResolver
1110
import java.io.File
@@ -19,6 +18,7 @@ import kotlin.script.experimental.dependencies.*
1918
import kotlin.script.experimental.host.FileBasedScriptSource
2019
import kotlin.script.experimental.host.FileScriptSource
2120
import kotlin.script.experimental.host.ScriptingHostConfiguration
21+
import kotlin.script.experimental.impl.internalScriptingRunSuspend
2222
import kotlin.script.experimental.jvm.*
2323
import kotlin.script.experimental.jvm.compat.mapLegacyDiagnosticSeverity
2424
import kotlin.script.experimental.jvm.compat.mapLegacyScriptPosition
@@ -135,7 +135,8 @@ class MainKtsConfigurator : RefineScriptCompilationConfigurationHandler {
135135
}
136136

137137
val resolveResult = try {
138-
runBlocking {
138+
@Suppress("DEPRECATION_ERROR")
139+
internalScriptingRunSuspend {
139140
resolver.resolveFromScriptSourceAnnotations(annotations.filter { it.annotation is DependsOn || it.annotation is Repository })
140141
}
141142
} catch (e: Throwable) {

libraries/tools/kotlin-script-util/src/test/kotlin/org/jetbrains/kotlin/script/util/ScriptUtilIT.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.jetbrains.kotlin.script.util
1818

1919
import com.intellij.openapi.util.Disposer
20-
import kotlinx.coroutines.runBlocking
2120
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
2221
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
2322
import org.jetbrains.kotlin.cli.common.messages.*
@@ -55,6 +54,7 @@ import kotlin.reflect.KClass
5554
import kotlin.script.experimental.api.onSuccess
5655
import kotlin.script.experimental.api.valueOr
5756
import kotlin.script.experimental.host.toScriptSource
57+
import kotlin.script.experimental.impl.internalScriptingRunSuspend
5858
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
5959
import kotlin.script.experimental.jvm.util.scriptCompilationClasspathFromContext
6060

@@ -199,7 +199,8 @@ done
199199
val script = File(scriptPath).toScriptSource()
200200
val newScriptDefinition = ScriptDefinitionProvider.getInstance(environment.project)!!.findDefinition(script)!!
201201
val compiledScript = scriptCompiler.compile(script, newScriptDefinition.compilationConfiguration).onSuccess {
202-
runBlocking {
202+
@Suppress("DEPRECATION_ERROR")
203+
internalScriptingRunSuspend {
203204
it.getClass(newScriptDefinition.evaluationConfiguration)
204205
}
205206
}.valueOr {

plugins/scripting/scripting-compiler-impl-embeddable/build.gradle.kts

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ dependencies {
1010
runtimeOnly(project(":kotlin-scripting-common"))
1111
runtimeOnly(project(":kotlin-scripting-jvm"))
1212
runtimeOnly(kotlinStdlib())
13-
runtimeOnly(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core"))
1413
}
1514

1615
publish()

plugins/scripting/scripting-compiler-impl/build.gradle.kts

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ dependencies {
1717
compile(project(":kotlin-scripting-jvm"))
1818
compile(kotlinStdlib())
1919
compileOnly(project(":kotlin-reflect-api"))
20-
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core"))
2120
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
2221
compileOnly(intellijDep()) { includeJars("asm-all", rootProject = rootProject) }
2322

plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/AsyncDependencyResolverWrapper.kt

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55

66
package org.jetbrains.kotlin.scripting.resolve
77

8-
import kotlinx.coroutines.runBlocking
98
import kotlin.script.dependencies.Environment
109
import kotlin.script.dependencies.ScriptContents
1110
import kotlin.script.experimental.dependencies.AsyncDependenciesResolver
1211
import kotlin.script.experimental.dependencies.DependenciesResolver
12+
import kotlin.script.experimental.impl.internalScriptingRunSuspend
1313

1414
// wraps AsyncDependenciesResolver to provide implementation for synchronous DependenciesResolver::resolve
1515
class AsyncDependencyResolverWrapper(
@@ -18,8 +18,9 @@ class AsyncDependencyResolverWrapper(
1818

1919
override fun resolve(
2020
scriptContents: ScriptContents, environment: Environment
21-
): DependenciesResolver.ResolveResult
22-
= runBlocking { delegate.resolveAsync(scriptContents, environment) }
21+
): DependenciesResolver.ResolveResult =
22+
@Suppress("DEPRECATION_ERROR")
23+
internalScriptingRunSuspend { delegate.resolveAsync(scriptContents, environment) }
2324

2425

2526
suspend override fun resolveAsync(

plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/refineCompilationConfiguration.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import com.intellij.psi.PsiElement
1616
import com.intellij.psi.PsiFile
1717
import com.intellij.psi.PsiManager
1818
import com.intellij.testFramework.LightVirtualFile
19-
import kotlinx.coroutines.runBlocking
2019
import org.jetbrains.kotlin.idea.KotlinLanguage
2120
import org.jetbrains.kotlin.psi.KtAnnotationEntry
2221
import org.jetbrains.kotlin.psi.KtFile
@@ -34,6 +33,7 @@ import kotlin.script.experimental.dependencies.AsyncDependenciesResolver
3433
import kotlin.script.experimental.dependencies.DependenciesResolver
3534
import kotlin.script.experimental.dependencies.ScriptDependencies
3635
import kotlin.script.experimental.host.*
36+
import kotlin.script.experimental.impl.internalScriptingRunSuspend
3737
import kotlin.script.experimental.jvm.*
3838
import kotlin.script.experimental.jvm.compat.mapToDiagnostics
3939
import kotlin.script.experimental.jvm.impl.toClassPathOrEmpty
@@ -255,7 +255,8 @@ fun refineScriptCompilationConfiguration(
255255
// runBlocking is using there to avoid loading dependencies asynchronously
256256
// because it leads to starting more than one gradle daemon in case of resolving dependencies in build.gradle.kts
257257
// It is more efficient to use one hot daemon consistently than multiple daemon in parallel
258-
runBlocking {
258+
@Suppress("DEPRECATION_ERROR")
259+
internalScriptingRunSuspend {
259260
resolver.resolveAsync(scriptContents, environment)
260261
}
261262
} else {

plugins/scripting/scripting-compiler/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ dependencies {
3535
testCompile(commonDep("junit:junit"))
3636

3737
testImplementation(intellijCoreDep()) { includeJars("intellij-core") }
38+
testImplementation(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core"))
3839
testRuntimeOnly(intellijDep()) { includeJars("jps-model", "jna") }
3940

4041
testImplementation(project(":kotlin-reflect"))

0 commit comments

Comments
 (0)