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
This commit is contained in:
Natalia Selezneva
2019-07-11 15:47:30 +03:00
parent 763f1e8606
commit e40cdef257
7 changed files with 46 additions and 19 deletions
@@ -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()
}
}
@@ -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() {
@@ -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()
@@ -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 {
@@ -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)
@@ -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
@@ -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)
}