Scripting: do not call getConfiguration inside ScriptClassRootsCache

We already have all configurations inside `all` property.
If script doesn't have loaded configuration getting script sdk - ask for configuration explicitly to avoid situations when configuration is already loaded but not yet saved in memory cache

Looks related to KT-35590
^KT-35590
This commit is contained in:
Natalia Selezneva
2020-01-10 13:04:42 +03:00
parent 1336da8453
commit a24e62eaf7
4 changed files with 42 additions and 31 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 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.
*/
@@ -268,18 +268,12 @@ internal abstract class AbstractScriptConfigurationManager(
val value2 = _classpathRoots
if (value2 != null) return value2
val value3 = newClassRootsCache()
val value3 = ScriptClassRootsCache(project, cache.allApplied())
_classpathRoots = value3
return value3
}
}
private fun newClassRootsCache() =
object : ScriptClassRootsCache(project, cache.allApplied()) {
override fun getConfiguration(file: VirtualFile) =
this@AbstractScriptConfigurationManager.getConfiguration(file)
}
private fun clearClassRootsCaches() {
debug { "class roots caches cleared" }
@@ -297,12 +291,25 @@ internal abstract class AbstractScriptConfigurationManager(
ScriptDependenciesModificationTracker.getInstance(project).incModificationCount()
}
override fun getScriptSdk(file: VirtualFile): Sdk? = classpathRoots.getScriptSdk(file)
/**
* Returns script classpath roots
* Loads script configuration if classpath roots don't contain [file] yet
*/
private fun getActualClasspathRoots(file: VirtualFile): ScriptClassRootsCache {
if (classpathRoots.contains(file)) {
return classpathRoots
}
getConfiguration(file)
return classpathRoots
}
override fun getScriptSdk(file: VirtualFile): Sdk? = getActualClasspathRoots(file).getScriptSdk(file)
override fun getFirstScriptsSdk(): Sdk? = classpathRoots.firstScriptSdk
override fun getScriptDependenciesClassFilesScope(file: VirtualFile): GlobalSearchScope =
classpathRoots.getScriptDependenciesClassFilesScope(file)
getActualClasspathRoots(file).getScriptDependenciesClassFilesScope(file)
override fun getAllScriptsDependenciesClassFilesScope(): GlobalSearchScope = classpathRoots.allDependenciesClassFilesScope
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 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.
*/
@@ -32,7 +32,7 @@ interface ScriptConfigurationCache {
fun setLoaded(file: VirtualFile, configurationSnapshot: ScriptConfigurationSnapshot)
fun markOutOfDate(scope: ScriptConfigurationCacheScope)
fun allApplied(): Collection<Pair<VirtualFile, ScriptCompilationConfigurationWrapper>>
fun allApplied(): Map<VirtualFile, ScriptCompilationConfigurationWrapper>
fun clear()
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 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.
*/
@@ -61,11 +61,15 @@ open class ScriptConfigurationMemoryCache(
@Synchronized
@Suppress("UNCHECKED_CAST")
override fun allApplied() =
memoryCache.entrySet().mapNotNull {
if (it.value.applied?.configuration == null) null
else it.key to it.value.applied?.configuration
} as Collection<Pair<VirtualFile, ScriptCompilationConfigurationWrapper>>
override fun allApplied(): Map<VirtualFile, ScriptCompilationConfigurationWrapper> {
val result = hashMapOf<VirtualFile, ScriptCompilationConfigurationWrapper>()
for ((file, configuration) in memoryCache.entrySet()) {
if (configuration.applied?.configuration != null) {
result[file] = configuration.applied.configuration
}
}
return result
}
@Synchronized
override fun clear() {
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2020 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.
*/
@@ -20,12 +20,10 @@ import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.script.debug
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
internal abstract class ScriptClassRootsCache(
internal class ScriptClassRootsCache(
private val project: Project,
val all: Collection<Pair<VirtualFile, ScriptCompilationConfigurationWrapper>>
private val all: Map<VirtualFile, ScriptCompilationConfigurationWrapper>
) {
protected abstract fun getConfiguration(file: VirtualFile): ScriptCompilationConfigurationWrapper?
private fun getScriptSdk(compilationConfiguration: ScriptCompilationConfigurationWrapper?): Sdk? {
// workaround for mismatched gradle wrapper and plugin version
val javaHome = try {
@@ -39,7 +37,7 @@ internal abstract class ScriptClassRootsCache(
private val scriptsSdksCache: Map<VirtualFile, Sdk?> =
ConcurrentFactoryMap.createWeakMap { file ->
val compilationConfiguration = getConfiguration(file)
val compilationConfiguration = all[file]
return@createWeakMap getScriptSdk(compilationConfiguration)
?: ScriptConfigurationManager.getScriptDefaultSdk(project)
}
@@ -47,17 +45,17 @@ internal abstract class ScriptClassRootsCache(
fun getScriptSdk(file: VirtualFile): Sdk? = scriptsSdksCache[file]
val firstScriptSdk: Sdk? by lazy {
val firstCachedScript = all.firstOrNull() ?: return@lazy null
return@lazy getScriptSdk(firstCachedScript.second)
val firstCachedScript = all.keys.firstOrNull() ?: return@lazy null
return@lazy getScriptSdk(firstCachedScript)
}
private val allSdks by lazy {
all.mapNotNull { scriptsSdksCache[it.first] }
all.mapNotNull { scriptsSdksCache[it.key] }
.distinct()
}
private val allNonIndexedSdks by lazy {
all.mapNotNull { scriptsSdksCache[it.first] }
all.mapNotNull { scriptsSdksCache[it.key] }
.filterNonModuleSdk()
.distinct()
}
@@ -69,14 +67,14 @@ internal abstract class ScriptClassRootsCache(
val allDependenciesClassFiles by lazy {
val sdkFiles = allNonIndexedSdks.flatMap { it.rootProvider.getFiles(OrderRootType.CLASSES).toList() }
val scriptDependenciesClasspath = all.flatMap { it.second.dependenciesClassPath }.distinct()
val scriptDependenciesClasspath = all.flatMap { it.value.dependenciesClassPath }.distinct()
sdkFiles + ScriptConfigurationManager.toVfsRoots(scriptDependenciesClasspath)
}
val allDependenciesSources by lazy {
val sdkSources = allNonIndexedSdks.flatMap { it.rootProvider.getFiles(OrderRootType.SOURCES).toList() }
val scriptDependenciesSources = all.flatMap { it.second.dependenciesSources }.distinct()
val scriptDependenciesSources = all.flatMap { it.value.dependenciesSources }.distinct()
sdkSources + ScriptConfigurationManager.toVfsRoots(scriptDependenciesSources)
}
@@ -91,7 +89,7 @@ internal abstract class ScriptClassRootsCache(
private val scriptsDependenciesClasspathScopeCache: MutableMap<VirtualFile, GlobalSearchScope> =
ConcurrentFactoryMap.createWeakMap { file ->
val compilationConfiguration = getConfiguration(file)
val compilationConfiguration = all[file]
?: return@createWeakMap GlobalSearchScope.EMPTY_SCOPE
val roots = compilationConfiguration.dependenciesClassPath
@@ -145,4 +143,6 @@ internal abstract class ScriptClassRootsCache(
return false
}
fun contains(file: VirtualFile) = all.containsKey(file)
}