Skip to content

Commit fefddb6

Browse files
ligeeSpace Team
authored andcommitted
Scripting: Fix caching of packages in JvmPackagePartProvider
since in scripting scenarios the loadedModules could be updated later in the pipeline, previous caching approach led to problems. #KT-76009 fixed
1 parent 81ec1a6 commit fefddb6

4 files changed

Lines changed: 57 additions & 2 deletions

File tree

compiler/cli/cli-base/src/org/jetbrains/kotlin/cli/jvm/compiler/JvmPackagePartProvider.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ class JvmPackagePartProvider(
3131

3232
override val loadedModules: MutableList<ModuleMappingInfo<VirtualFile>> = SmartList()
3333

34+
private var allPackageNamesCache: Set<String>? = null
35+
36+
override val allPackageNames: Set<String>
37+
get() {
38+
// assuming that the modifications of loadedModules happen in predictable moments now, so nos syncronization is used
39+
if (allPackageNamesCache == null) {
40+
allPackageNamesCache = loadedModules.flatMapTo(mutableSetOf<String>()) { it.mapping.packageFqName2Parts.keys }
41+
}
42+
return allPackageNamesCache!!
43+
}
44+
45+
// TODO: redesign to avoid cache-unfriendly usages, see KT-76516
3446
fun addRoots(roots: List<JavaRoot>, messageCollector: MessageCollector) {
3547
for ((root, type) in roots) {
3648
if (type != JavaRoot.RootType.BINARY) continue
@@ -45,6 +57,7 @@ class JvmPackagePartProvider(
4557
deserializationConfiguration, messageCollector
4658
)?.let {
4759
loadedModules.add(ModuleMappingInfo(root, it, moduleFile.nameWithoutExtension))
60+
allPackageNamesCache = null
4861
}
4962
}
5063
}

core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/JvmPackagePartProviderBase.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ abstract class JvmPackagePartProviderBase<MappingsKey> : PackageAndMetadataPartP
3838
return result.toList()
3939
}
4040

41-
private val allPackageNames: Set<String> by lazy {
41+
protected open val allPackageNames: Set<String> by lazy {
4242
loadedModules.flatMapTo(mutableSetOf()) { it.mapping.packageFqName2Parts.keys }
4343
}
4444

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ dependencies {
4444
testApi(libs.junit.platform.launcher)
4545
testApi(kotlinTest("junit5"))
4646

47+
testApi(project(":kotlin-scripting-dependencies-maven"))
48+
4749
testImplementation(intellijCore())
4850
testImplementation(libs.kotlinx.coroutines.core)
4951
testImplementation(commonDependency("org.jetbrains.kotlin:kotlin-reflect")) { isTransitive = false }

plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/test/CustomK2ReplTest.kt

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package org.jetbrains.kotlin.scripting.compiler.test
77

8+
import kotlinx.coroutines.runBlocking
89
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
910
import org.jetbrains.kotlin.scripting.compiler.plugin.SCRIPT_TEST_BASE_COMPILER_ARGUMENTS_PROPERTY
1011
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.K2ReplCompiler
@@ -14,12 +15,18 @@ import java.io.File
1415
import kotlin.reflect.full.declaredMemberFunctions
1516
import kotlin.reflect.full.declaredMemberProperties
1617
import kotlin.script.experimental.api.*
18+
import kotlin.script.experimental.dependencies.CompoundDependenciesResolver
19+
import kotlin.script.experimental.dependencies.FileSystemDependenciesResolver
20+
import kotlin.script.experimental.dependencies.maven.MavenDependenciesResolver
1721
import kotlin.script.experimental.host.toScriptSource
1822
import kotlin.script.experimental.impl.internalScriptingRunSuspend
1923
import kotlin.script.experimental.jvm.KJvmEvaluatedSnippet
2024
import kotlin.script.experimental.jvm.updateClasspath
2125
import kotlin.script.experimental.util.LinkedSnippet
22-
import kotlin.test.*
26+
import kotlin.test.Test
27+
import kotlin.test.assertEquals
28+
import kotlin.test.assertTrue
29+
import kotlin.test.fail
2330

2431
class ReplReceiver1 {
2532
val ok = "OK"
@@ -28,6 +35,7 @@ class ReplReceiver1 {
2835
@Suppress("unused") // Used in snippets
2936
class TestReplReceiver1() { fun checkReceiver(block: ReplReceiver1.() -> Any) = block(ReplReceiver1()) }
3037

38+
private val dependenciesResolver = CompoundDependenciesResolver(FileSystemDependenciesResolver(), MavenDependenciesResolver())
3139

3240
class CustomK2ReplTest {
3341

@@ -118,6 +126,38 @@ class CustomK2ReplTest {
118126
)
119127
}
120128

129+
@Test
130+
fun testWithUpdatingDependeciesAndImportKotlinDeclarations() {
131+
evalAndCheckSnippetsResultVals(
132+
sequenceOf(
133+
"println(\"firstLine\")",
134+
"import org.jetbrains.kotlinx.dataframe.jupyter.KotlinNotebookPluginUtils",
135+
"KotlinNotebookPluginUtils.getKotlinNotebookIDEBuildNumber().toString()",
136+
"import org.jetbrains.kotlinx.dataframe.jupyter.importDataSchema",
137+
"importDataSchema(\"ftp://xx\").url.toString()",
138+
),
139+
sequenceOf(null, null, "null", null, "ftp://xx"),
140+
baseCompilationConfiguration.with {
141+
refineConfiguration {
142+
beforeCompiling { (script, config, _) ->
143+
if (!script.text.contains("firstLine")) {
144+
val resolveResults = runBlocking {
145+
dependenciesResolver.resolve("org.jetbrains.kotlinx:dataframe-core:0.15.0")
146+
}
147+
if (resolveResults is ResultWithDiagnostics.Failure)
148+
resolveResults
149+
else
150+
config.with {
151+
updateClasspath(resolveResults.valueOrThrow())
152+
defaultImports("kotlin.random.Random")
153+
}.asSuccess()
154+
} else config.asSuccess()
155+
}
156+
}
157+
}
158+
)
159+
}
160+
121161
@Test
122162
fun testBasicReflection() {
123163
evalAndCheckSnippets(

0 commit comments

Comments
 (0)