KT-60193 K2 scripts: configuration discovery might fail silently
Due to possible data races configuration discovery might fail. So far, it happened silently and we used so-called default one. This configuration is unaware of specific implicit imports, receivers, base class, etc. Hence, broken highlighting and navigation. This commit introduces the following changes: 1. Having default configuration for building `FirScript` is no longer an option. Missing configuration means error reported via exception. 2. Every configuration usage is now logged in DEBUG mode. Troubleshooting becomes easier. ^KT-60193 fixed
This commit is contained in:
+21
-13
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.scripting.compiler.plugin.services
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.*
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -49,7 +50,9 @@ class FirScriptConfiguratorExtensionImpl(
|
||||
override fun FirScriptBuilder.configure(fileBuilder: FirFileBuilder) {
|
||||
val sourceFile = fileBuilder.sourceFile ?: return
|
||||
|
||||
withConfigurationIfAny(sourceFile) { configuration ->
|
||||
val configuration = getOrLoadConfiguration(sourceFile)
|
||||
check(configuration != null) { "Configuration for ${sourceFile.asString()} wasn't found" }
|
||||
|
||||
// TODO: rewrite/extract decision logic for clarity
|
||||
configuration[ScriptCompilationConfiguration.baseClass]?.let { baseClass ->
|
||||
val baseClassFqn = FqName.fromSegments(baseClass.typeName.split("."))
|
||||
@@ -123,22 +126,28 @@ class FirScriptConfiguratorExtensionImpl(
|
||||
_knownAnnotationsForSamWithReceiver.add(it.typeName)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtSourceFile.asString() = path ?: name
|
||||
|
||||
private fun logConfiguration(file: KtSourceFile, config: ScriptCompilationConfiguration) {
|
||||
log.debug(
|
||||
"Using configuration: ${file.asString()} => " +
|
||||
"(${config[ScriptCompilationConfiguration.displayName]}, " +
|
||||
"ext=.${config[ScriptCompilationConfiguration.fileExtension]}, " +
|
||||
"pattern=${config[ScriptCompilationConfiguration.filePathPattern]})"
|
||||
)
|
||||
}
|
||||
|
||||
private fun withConfigurationIfAny(file: KtSourceFile, body: (ScriptCompilationConfiguration) -> Unit) {
|
||||
val configuration = session.scriptDefinitionProviderService?.let { providerService ->
|
||||
private fun getOrLoadConfiguration(file: KtSourceFile): ScriptCompilationConfiguration? {
|
||||
val service = checkNotNull(session.scriptDefinitionProviderService)
|
||||
val sourceCode = file.toSourceCode()
|
||||
val ktFile = sourceCode?.originalKtFile()
|
||||
with(providerService) {
|
||||
ktFile?.let { configurationFor(it) }
|
||||
?: sourceCode?.let { configurationFor(it) }
|
||||
?: defaultConfiguration()
|
||||
return with(service) {
|
||||
ktFile?.let { asKtFile -> configurationFor(asKtFile)?.also { logConfiguration(file, it) } }
|
||||
?: sourceCode?.let { asSourceCode -> configurationFor(asSourceCode)?.also { logConfiguration(file, it) } }
|
||||
}
|
||||
}
|
||||
|
||||
configuration?.let { body.invoke(it) }
|
||||
}
|
||||
|
||||
private fun buildContextReceiverWithFqName(classFqn: FqName, customName: Name? = null) =
|
||||
buildContextReceiver {
|
||||
typeRef = buildUserTypeRef {
|
||||
@@ -160,6 +169,8 @@ class FirScriptConfiguratorExtensionImpl(
|
||||
get() = _knownAnnotationsForSamWithReceiver
|
||||
|
||||
companion object {
|
||||
private val log = Logger.getInstance(FirScriptConfiguratorExtensionImpl::class.java)
|
||||
|
||||
fun getFactory(hostConfiguration: ScriptingHostConfiguration): Factory {
|
||||
return Factory { session -> FirScriptConfiguratorExtensionImpl(session, hostConfiguration) }
|
||||
}
|
||||
@@ -178,9 +189,6 @@ private fun FirScriptDefinitionProviderService.configurationFor(file: KtFile): S
|
||||
private fun FirScriptDefinitionProviderService.configurationFor(sourceCode: SourceCode): ScriptCompilationConfiguration? =
|
||||
definitionProvider?.findDefinition(sourceCode)?.compilationConfiguration
|
||||
|
||||
private fun FirScriptDefinitionProviderService.defaultConfiguration(): ScriptCompilationConfiguration? =
|
||||
definitionProvider?.getDefaultDefinition()?.compilationConfiguration
|
||||
|
||||
fun KtSourceFile.toSourceCode(): SourceCode? = when (this) {
|
||||
is KtPsiSourceFile -> (psiFile as? KtFile)?.let(::KtFileScriptSource) ?: VirtualFileScriptSource(psiFile.virtualFile)
|
||||
is KtVirtualFileSourceFile -> VirtualFileScriptSource(virtualFile)
|
||||
|
||||
Reference in New Issue
Block a user