From e40cdef257968529d2e97922d7e0371d2d1b4fb9 Mon Sep 17 00:00:00 2001 From: Natalia Selezneva Date: Thu, 11 Jul 2019 15:47:30 +0300 Subject: [PATCH] Scripts: pass script definition as parameter to loader (KT-32554) This should avoid situation when script definition for file is changed between isApplicable and loadDependencies calls ^KT-32554 Fixed --- .../core/script/ScriptDependenciesManager.kt | 4 +++- .../ScriptsCompilationConfigurationUpdater.kt | 3 ++- .../AsyncScriptDependenciesLoader.kt | 12 +++++++++--- .../FromFileAttributeScriptDependenciesLoader.kt | 14 ++++++++++---- .../OutsiderFileDependenciesLoader.kt | 11 +++++++++-- .../dependencies/ScriptDependenciesLoader.kt | 5 +++-- .../dependencies/SyncScriptDependenciesLoader.kt | 16 ++++++++++------ 7 files changed, 46 insertions(+), 19 deletions(-) diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesManager.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesManager.kt index 72ec943286c..8d4aab1842d 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesManager.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesManager.kt @@ -30,6 +30,7 @@ import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.idea.caches.project.getAllProjectSdks import org.jetbrains.kotlin.idea.core.script.dependencies.SyncScriptDependenciesLoader import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider +import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResult import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper import java.io.File @@ -125,7 +126,8 @@ class ScriptDependenciesManager internal constructor( @TestOnly fun updateScriptDependenciesSynchronously(virtualFile: VirtualFile, project: Project) { val loader = SyncScriptDependenciesLoader(project) - loader.loadDependencies(virtualFile) + val scriptDefinition = virtualFile.findScriptDefinition(project) ?: return + loader.loadDependencies(virtualFile, scriptDefinition) loader.notifyRootsChanged() } } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptsCompilationConfigurationUpdater.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptsCompilationConfigurationUpdater.kt index 17fc4db147b..eef34638272 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptsCompilationConfigurationUpdater.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptsCompilationConfigurationUpdater.kt @@ -101,7 +101,8 @@ class ScriptsCompilationConfigurationUpdater( if (!ScriptDefinitionsManager.getInstance(project).isReady()) return if (!cache.shouldRunDependenciesUpdate(file)) return - loaders.filter { it.isApplicable(file) }.forEach { it.loadDependencies(file) } + val scriptDefinition = file.findScriptDefinition(project) ?: return + loaders.filter { it.isApplicable(file, scriptDefinition) }.forEach { it.loadDependencies(file, scriptDefinition) } } private fun makeRootsChangeIfNeeded() { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/AsyncScriptDependenciesLoader.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/AsyncScriptDependenciesLoader.kt index 0a9253bc96d..312bc5f0ab3 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/AsyncScriptDependenciesLoader.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/AsyncScriptDependenciesLoader.kt @@ -14,6 +14,7 @@ import com.intellij.openapi.vfs.VirtualFile import kotlinx.coroutines.Runnable import org.jetbrains.kotlin.idea.core.script.ScriptsCompilationConfigurationUpdater import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings +import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource import org.jetbrains.kotlin.scripting.resolve.refineScriptCompilationConfiguration @@ -28,12 +29,17 @@ class AsyncScriptDependenciesLoader internal constructor(project: Project) : Scr private var notifyRootChange: Boolean = false private var backgroundTasksQueue: LoaderBackgroundTask? = null - override fun isApplicable(file: VirtualFile): Boolean { - val scriptDefinition = file.findScriptDefinition(project) ?: return false + override fun isApplicable( + file: VirtualFile, + scriptDefinition: ScriptDefinition + ): Boolean { return ScriptsCompilationConfigurationUpdater.getInstance(project).isAsyncDependencyResolver(scriptDefinition) } - override fun loadDependencies(file: VirtualFile) { + override fun loadDependencies( + file: VirtualFile, + scriptDefinition: ScriptDefinition + ) { lock.write { if (backgroundTasksQueue == null) { backgroundTasksQueue = LoaderBackgroundTask() diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/FromFileAttributeScriptDependenciesLoader.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/FromFileAttributeScriptDependenciesLoader.kt index 66b7fce7ceb..5f2603a6ee6 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/FromFileAttributeScriptDependenciesLoader.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/FromFileAttributeScriptDependenciesLoader.kt @@ -9,7 +9,7 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.idea.core.script.scriptCompilationConfiguration import org.jetbrains.kotlin.idea.core.script.scriptDependencies -import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition +import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource import kotlin.script.experimental.api.asSuccess @@ -17,17 +17,23 @@ import kotlin.script.experimental.api.asSuccess // TODO: rename and provide alias for compatibility - this is not only about dependencies anymore class FromFileAttributeScriptDependenciesLoader(project: Project) : ScriptDependenciesLoader(project) { - override fun isApplicable(file: VirtualFile): Boolean { + override fun isApplicable( + file: VirtualFile, + scriptDefinition: ScriptDefinition + ): Boolean { return file.scriptDependencies != null || file.scriptCompilationConfiguration != null } - override fun loadDependencies(file: VirtualFile) { + override fun loadDependencies( + file: VirtualFile, + scriptDefinition: ScriptDefinition + ) { file.scriptCompilationConfiguration?.let { ScriptCompilationConfigurationWrapper.FromCompilationConfiguration(VirtualFileScriptSource(file), it).apply { debug(file) { "refined configuration from fileAttributes = $it" } } } ?: file.scriptDependencies?.let { - ScriptCompilationConfigurationWrapper.FromLegacy(VirtualFileScriptSource(file), it, file.findScriptDefinition(project)).apply { + ScriptCompilationConfigurationWrapper.FromLegacy(VirtualFileScriptSource(file), it, scriptDefinition).apply { debug(file) { "dependencies from fileAttributes = $it" } } }?.let { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/OutsiderFileDependenciesLoader.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/OutsiderFileDependenciesLoader.kt index 1af075a99ee..ea2ce778f46 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/OutsiderFileDependenciesLoader.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/OutsiderFileDependenciesLoader.kt @@ -10,13 +10,20 @@ import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager import org.jetbrains.kotlin.idea.highlighter.OutsidersPsiFileSupportUtils import org.jetbrains.kotlin.idea.highlighter.OutsidersPsiFileSupportWrapper +import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition class OutsiderFileDependenciesLoader(project: Project) : ScriptDependenciesLoader(project) { - override fun isApplicable(file: VirtualFile): Boolean { + override fun isApplicable( + file: VirtualFile, + scriptDefinition: ScriptDefinition + ): Boolean { return OutsidersPsiFileSupportWrapper.isOutsiderFile(file) } - override fun loadDependencies(file: VirtualFile) { + override fun loadDependencies( + file: VirtualFile, + scriptDefinition: ScriptDefinition + ) { val fileOrigin = OutsidersPsiFileSupportUtils.getOutsiderFileOrigin(project, file) ?: return val compilationConfiguration = ScriptDependenciesManager.getInstance(project).getRefinedCompilationConfiguration(fileOrigin) ?: return saveToCache(file, compilationConfiguration) diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/ScriptDependenciesLoader.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/ScriptDependenciesLoader.kt index 7407e009384..cdf328283de 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/ScriptDependenciesLoader.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/ScriptDependenciesLoader.kt @@ -15,6 +15,7 @@ import com.intellij.openapi.util.EmptyRunnable import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.idea.core.script.* import org.jetbrains.kotlin.idea.util.application.runWriteAction +import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResult import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper import org.jetbrains.kotlin.scripting.resolve.ScriptReportSink @@ -24,8 +25,8 @@ import kotlin.script.experimental.api.valueOrNull // TODO: rename and provide alias for compatibility - this is not only about dependencies anymore abstract class ScriptDependenciesLoader(protected val project: Project) { - abstract fun isApplicable(file: VirtualFile): Boolean - abstract fun loadDependencies(file: VirtualFile) + abstract fun isApplicable(file: VirtualFile, scriptDefinition: ScriptDefinition): Boolean + abstract fun loadDependencies(file: VirtualFile, scriptDefinition: ScriptDefinition) protected abstract fun shouldShowNotification(): Boolean diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/SyncScriptDependenciesLoader.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/SyncScriptDependenciesLoader.kt index eba6d376fd3..8a4fd0875c7 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/SyncScriptDependenciesLoader.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/dependencies/SyncScriptDependenciesLoader.kt @@ -8,20 +8,24 @@ package org.jetbrains.kotlin.idea.core.script.dependencies import com.intellij.openapi.project.Project import com.intellij.openapi.vfs.VirtualFile import org.jetbrains.kotlin.idea.core.script.ScriptsCompilationConfigurationUpdater -import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition +import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource import org.jetbrains.kotlin.scripting.resolve.refineScriptCompilationConfiguration class SyncScriptDependenciesLoader(project: Project) : ScriptDependenciesLoader(project) { - override fun isApplicable(file: VirtualFile): Boolean { - val scriptDefinition = file.findScriptDefinition(project) ?: return false + override fun isApplicable( + file: VirtualFile, + scriptDefinition: ScriptDefinition + ): Boolean { return !ScriptsCompilationConfigurationUpdater.getInstance(project).isAsyncDependencyResolver(scriptDefinition) } - override fun loadDependencies(file: VirtualFile) { - val scriptDef = file.findScriptDefinition(project) ?: return + override fun loadDependencies( + file: VirtualFile, + scriptDefinition: ScriptDefinition + ) { debug(file) { "start sync dependencies loading" } - val result = refineScriptCompilationConfiguration(VirtualFileScriptSource(file), scriptDef, project) + val result = refineScriptCompilationConfiguration(VirtualFileScriptSource(file), scriptDefinition, project) debug(file) { "finish sync dependencies loading" } processRefinedConfiguration(result, file) }