KT-56632 Script configuration isn't loaded for embedded code snippets

From now on we load script configurations for embedded Kotlin code
snippets. Potentially this might lead to an extra load during a file
analysis.

IDEA side test for the change is here:
`HighlightingTestGenerated.Uncategorized#testKotlinInJavaInjection`

^KT-56632 fixed
This commit is contained in:
Andrei Klunnyi
2023-02-16 12:25:41 +01:00
committed by Space Team
parent 3c35328c09
commit 661a2626f3
3 changed files with 22 additions and 26 deletions
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.scripting.definitions
import com.intellij.ide.highlighter.JavaClassFileType import com.intellij.ide.highlighter.JavaClassFileType
import com.intellij.ide.highlighter.JavaFileType import com.intellij.ide.highlighter.JavaFileType
import com.intellij.injected.editor.VirtualFileWindow
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.fileTypes.FileTypeRegistry import com.intellij.openapi.fileTypes.FileTypeRegistry
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
@@ -61,19 +62,26 @@ fun VirtualFile.findScriptDefinition(project: Project): ScriptDefinition? {
return findScriptDefinition(project, VirtualFileScriptSource(this)) return findScriptDefinition(project, VirtualFileScriptSource(this))
} }
fun findScriptDefinition(project: Project, script: SourceCode): ScriptDefinition? { fun findScriptDefinition(project: Project, script: SourceCode): ScriptDefinition {
val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(project) ?: return null val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(project) ?: return null
?: throw IllegalStateException("Unable to get script definition: ScriptDefinitionProvider is not configured.") ?: throw IllegalStateException("Unable to get script definition: ScriptDefinitionProvider is not configured.")
return scriptDefinitionProvider.findDefinition(script) ?: scriptDefinitionProvider.getDefaultDefinition() return scriptDefinitionProvider.findDefinition(script) ?: scriptDefinitionProvider.getDefaultDefinition()
} }
fun VirtualFile.isNonScript(): Boolean = fun VirtualFile.isNonScript(): Boolean = when (this) {
isDirectory || is VirtualFileWindow -> {
extension == KotlinFileType.EXTENSION || // This file is an embedded Kotlin code snippet.
extension == JavaFileType.INSTANCE.defaultExtension || !this.isKotlinFileType()
extension == JavaClassFileType.INSTANCE.defaultExtension || }
!this.isKotlinFileType() else -> {
isDirectory ||
extension == KotlinFileType.EXTENSION ||
extension == JavaFileType.INSTANCE.defaultExtension ||
extension == JavaClassFileType.INSTANCE.defaultExtension ||
!this.isKotlinFileType()
}
}
private fun VirtualFile.isKotlinFileType(): Boolean { private fun VirtualFile.isKotlinFileType(): Boolean {
if (extension == KotlinParserDefinition.STD_SCRIPT_SUFFIX) return true if (extension == KotlinParserDefinition.STD_SCRIPT_SUFFIX) return true
@@ -5,24 +5,10 @@
package org.jetbrains.kotlin.scripting.definitions package org.jetbrains.kotlin.scripting.definitions
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResult import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResult
import kotlin.script.experimental.api.ScriptCompilationConfiguration
import kotlin.script.experimental.api.ScriptDiagnostic import kotlin.script.experimental.api.ScriptDiagnostic
import kotlin.script.experimental.api.valueOr import kotlin.script.experimental.api.valueOr
fun PsiFile.findScriptCompilationConfiguration(): ScriptCompilationConfiguration? {
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 -> private fun ScriptCompilationConfigurationResult.valueOrError() = valueOr { failure ->
val singleCause = failure.reports.singleOrNull { it.severity == ScriptDiagnostic.Severity.ERROR } val singleCause = failure.reports.singleOrNull { it.severity == ScriptDiagnostic.Severity.ERROR }
if (singleCause != null) if (singleCause != null)
@@ -36,10 +36,7 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
import org.jetbrains.kotlin.resolve.scopes.utils.addImportingScope import org.jetbrains.kotlin.resolve.scopes.utils.addImportingScope
import org.jetbrains.kotlin.resolve.source.toSourceElement import org.jetbrains.kotlin.resolve.source.toSourceElement
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition import org.jetbrains.kotlin.scripting.definitions.*
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider
import org.jetbrains.kotlin.scripting.definitions.ScriptPriorities
import org.jetbrains.kotlin.scripting.definitions.findScriptCompilationConfiguration
import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.typeUtil.isNothing import org.jetbrains.kotlin.types.typeUtil.isNothing
@@ -121,7 +118,12 @@ class LazyScriptDescriptor(
override fun getPriority() = priority override fun getPriority() = priority
val scriptCompilationConfiguration: () -> ScriptCompilationConfiguration = resolveSession.storageManager.createLazyValue { val scriptCompilationConfiguration: () -> ScriptCompilationConfiguration = resolveSession.storageManager.createLazyValue {
scriptInfo.script.containingKtFile.findScriptCompilationConfiguration() run {
val containingFile = scriptInfo.script.containingKtFile
val provider = ScriptDependenciesProvider.getInstance(containingFile.project)
provider?.getScriptConfiguration(containingFile)?.configuration
?: containingFile.findScriptDefinition()?.compilationConfiguration
}
?: throw IllegalArgumentException("Unable to find script compilation configuration for the script ${scriptInfo.script.containingFile}") ?: throw IllegalArgumentException("Unable to find script compilation configuration for the script ${scriptInfo.script.containingFile}")
} }