From a24e62eaf7a336bbcb2b7c78ef95b07f775ca668 Mon Sep 17 00:00:00 2001 From: Natalia Selezneva Date: Fri, 10 Jan 2020 13:04:42 +0300 Subject: [PATCH] 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 --- .../AbstractScriptConfigurationManager.kt | 27 ++++++++++++------- .../cache/ScriptConfigurationCache.kt | 4 +-- .../cache/ScriptConfigurationMemoryCache.kt | 16 ++++++----- .../utils/ScriptClassRootsCache.kt | 26 +++++++++--------- 4 files changed, 42 insertions(+), 31 deletions(-) diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/AbstractScriptConfigurationManager.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/AbstractScriptConfigurationManager.kt index 9f7eb018d50..90b895e2157 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/AbstractScriptConfigurationManager.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/AbstractScriptConfigurationManager.kt @@ -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 diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/cache/ScriptConfigurationCache.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/cache/ScriptConfigurationCache.kt index ade97cb9227..e4ab18b6c9e 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/cache/ScriptConfigurationCache.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/cache/ScriptConfigurationCache.kt @@ -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> + fun allApplied(): Map fun clear() } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/cache/ScriptConfigurationMemoryCache.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/cache/ScriptConfigurationMemoryCache.kt index 98ec1f8ef55..04032005632 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/cache/ScriptConfigurationMemoryCache.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/cache/ScriptConfigurationMemoryCache.kt @@ -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> + override fun allApplied(): Map { + val result = hashMapOf() + for ((file, configuration) in memoryCache.entrySet()) { + if (configuration.applied?.configuration != null) { + result[file] = configuration.applied.configuration + } + } + return result + } @Synchronized override fun clear() { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/utils/ScriptClassRootsCache.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/utils/ScriptClassRootsCache.kt index 535a2e44d4d..48ed12bb6c3 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/utils/ScriptClassRootsCache.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/configuration/utils/ScriptClassRootsCache.kt @@ -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> + private val all: Map ) { - 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 = 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 = 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) } \ No newline at end of file