From b801d963a12eb8fb456f9d80d0a0907a7ac09cb6 Mon Sep 17 00:00:00 2001 From: Ilya Muradyan Date: Wed, 31 Aug 2022 21:20:07 +0200 Subject: [PATCH] [Scripting] Fix obtaining virtual file for getting compilation configuration --- .../scripting/definitions/definitions.kt | 24 +++++++++++++++---- .../definitions/dynamicConfigurations.kt | 17 +++++++------ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/definitions.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/definitions.kt index b581ea9c2ff..839d64bb625 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/definitions.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/definitions.kt @@ -19,20 +19,34 @@ import org.jetbrains.kotlin.parsing.KotlinParserDefinition import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.scripting.resolve.KtFileScriptSource import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract import kotlin.script.experimental.api.SourceCode inline fun runReadAction(crossinline runnable: () -> T): T { return ApplicationManager.getApplication().runReadAction(Computable { runnable() }) } -fun PsiFile.findScriptDefinition(): ScriptDefinition? { +@OptIn(ExperimentalContracts::class) +fun PsiFile.isScript(): Boolean { + contract { + returns(true) implies (this@isScript is KtFile) + } + // Do not use psiFile.script, see comments in findScriptDefinition - if (this !is KtFile/* || this.script == null*/) return null + if (this !is KtFile/* || this.script == null*/) return false - val virtualFile = this.virtualFile ?: this.originalFile.virtualFile ?: return null - if (virtualFile.isNonScript()) return null + // Sometimes - i.e. when event system is disabled for a view provider - requesting + // virtual file directly from the viewProvider is the only way of obtaining it + val virtualFile = virtualFile ?: originalFile.virtualFile ?: viewProvider.virtualFile + if (virtualFile.isNonScript()) return false - return findScriptDefinition(project, KtFileScriptSource(this)) + return true +} + +fun PsiFile.findScriptDefinition(): ScriptDefinition? { + return if (isScript()) findScriptDefinition(project, KtFileScriptSource(this)) + else null } @Deprecated("Use PsiFile.findScriptDefinition() instead") diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/dynamicConfigurations.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/dynamicConfigurations.kt index ac1b9581957..de135e28930 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/dynamicConfigurations.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/dynamicConfigurations.kt @@ -13,15 +13,14 @@ import kotlin.script.experimental.api.ScriptDiagnostic import kotlin.script.experimental.api.valueOr fun PsiFile.findScriptCompilationConfiguration(): ScriptCompilationConfiguration? { - // Do not use psiFile.script, see comments in findScriptDefinition - if (this !is KtFile/* || this.script == null*/) return null - val file = virtualFile ?: originalFile.virtualFile ?: return null - if (file.isNonScript()) return null - - val provider = ScriptDependenciesProvider.getInstance(project) - // Ignoring the error here, assuming that it will be reported elsewhere anyway (this is important scenario in IDE) - return provider?.getScriptConfiguration(this)?.configuration - ?: findScriptDefinition()?.compilationConfiguration + return if (isScript()) { + val provider = ScriptDependenciesProvider.getInstance(project) + // Ignoring the error here, assuming that it will be reported elsewhere anyway (this is important scenario in IDE) + provider?.getScriptConfiguration(this)?.configuration + ?: findScriptDefinition()?.compilationConfiguration + } else { + null + } } private fun ScriptCompilationConfigurationResult.valueOrError() = valueOr { failure ->