From 35b0cd65e9732051db5e26b772831b8b47947de6 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Sun, 30 Jul 2023 03:29:54 +0200 Subject: [PATCH] [FIR] PsiRawFirBuilder: add missing script configurator PsiRawFirBuilder#visitScript didn't work because it didn't have a configurator Now FirScriptConfiguratorExtension split into two parts: * File * Script ^KT-60728 --- .../kotlin/fir/builder/PsiRawFirBuilder.kt | 43 +++++++++------- .../builder/FirScriptConfiguratorExtension.kt | 6 ++- .../FirScriptConfigurationExtensionImpl.kt | 51 ++++++++++--------- 3 files changed, 58 insertions(+), 42 deletions(-) diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt index 24604434c4f..9ad409539c1 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt @@ -1127,19 +1127,23 @@ open class PsiRawFirBuilder( for (declaration in file.declarations) { declarations += when (declaration) { is KtScript -> { - requireWithAttachment(file.declarations.size == 1, message = { "Expect the script to be the only declaration in the file" }) { - withEntry("fileName", file.name) - } - convertScript(declaration, this.name) { - for (configurator in baseSession.extensionService.scriptConfigurators) { - with(configurator) { configure(this@buildFile) } + requireWithAttachment( + file.declarations.size == 1, + message = { "Expect the script to be the only declaration in the file" }, + ) { + withEntry("fileName", file.name) + } + + convertScript(declaration, name, sourceFile) { + for (configurator in baseSession.extensionService.scriptConfigurators) { + with(configurator) { configureContainingFile(this@buildFile) } + } } } + is KtDestructuringDeclaration -> buildErrorTopLevelDestructuringDeclaration(declaration.toFirSourceElement()) + else -> declaration.convert() } - is KtDestructuringDeclaration -> buildErrorTopLevelDestructuringDeclaration(declaration.toFirSourceElement()) - else -> declaration.convert() } - } for (danglingModifierList in file.danglingModifierLists) { declarations += buildErrorTopLevelDeclarationForDanglingModifierList(danglingModifierList) @@ -1148,7 +1152,12 @@ open class PsiRawFirBuilder( } } - private fun convertScript(script: KtScript, fileName: String, setup: FirScriptBuilder.() -> Unit = {}): FirScript { + private fun convertScript( + script: KtScript, + fileName: String, + sourceFile: KtSourceFile?, + setup: FirScriptBuilder.() -> Unit = {}, + ): FirScript { return buildScript { source = script.toFirSourceElement() moduleData = baseModuleData @@ -1193,6 +1202,11 @@ open class PsiRawFirBuilder( } } setup() + if (sourceFile != null) { + for (configurator in baseSession.extensionService.scriptConfigurators) { + with(configurator) { configure(sourceFile) } + } + } } } @@ -1212,16 +1226,11 @@ open class PsiRawFirBuilder( } } - // TODO: if no original FirScript is passed here, the invalid script could be constructed, consider throwing an error override fun visitScript(script: KtScript, data: FirElement?): FirElement { val ktFile = script.containingKtFile val fileName = ktFile.name - return convertScript(script, fileName) { - (data as? FirScript)?.let { - contextReceivers.addAll(it.contextReceivers) - parameters.addAll(it.parameters) - } - } + val fileForSource = (data as? FirScript)?.psi?.containingFile as? KtFile ?: ktFile + return convertScript(script, fileName, KtPsiSourceFile(fileForSource)) } protected fun KtEnumEntry.toFirEnumEntry( diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/FirScriptConfiguratorExtension.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/FirScriptConfiguratorExtension.kt index ade712bf73f..b483c2fd298 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/FirScriptConfiguratorExtension.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/FirScriptConfiguratorExtension.kt @@ -1,10 +1,11 @@ /* - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.fir.builder +import org.jetbrains.kotlin.KtSourceFile import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.builder.FirFileBuilder import org.jetbrains.kotlin.fir.declarations.builder.FirScriptBuilder @@ -27,7 +28,8 @@ abstract class FirScriptConfiguratorExtension( fun interface Factory : FirExtension.Factory - abstract fun FirScriptBuilder.configure(fileBuilder: FirFileBuilder) + abstract fun FirScriptBuilder.configureContainingFile(fileBuilder: FirFileBuilder) + abstract fun FirScriptBuilder.configure(sourceFile: KtSourceFile) } val FirExtensionService.scriptConfigurators: List by FirExtensionService.registeredExtensions() diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/services/FirScriptConfigurationExtensionImpl.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/services/FirScriptConfigurationExtensionImpl.kt index 37b4fbe2d88..8b9c98016e7 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/services/FirScriptConfigurationExtensionImpl.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/services/FirScriptConfigurationExtensionImpl.kt @@ -49,14 +49,35 @@ class FirScriptConfiguratorExtensionImpl( ) : FirScriptConfiguratorExtension(session) { @OptIn(SymbolInternals::class) - override fun FirScriptBuilder.configure(fileBuilder: FirFileBuilder) { + override fun FirScriptBuilder.configureContainingFile(fileBuilder: FirFileBuilder) { val sourceFile = fileBuilder.sourceFile ?: return + val configuration = getOrLoadConfiguration(sourceFile) ?: run { + log.warn("Configuration for ${sourceFile.asString()} wasn't found. FirScriptBuilder wasn't configured.") + return + } - val configuration = getOrLoadConfiguration(sourceFile) - ?: run { - log.warn("Configuration for ${sourceFile.asString()} wasn't found. FirScriptBuilder wasn't configured.") - return + configuration[ScriptCompilationConfiguration.defaultImports]?.forEach { defaultImport -> + val trimmed = defaultImport.trim() + val endsWithStar = trimmed.endsWith("*") + val stripped = if (endsWithStar) trimmed.substring(0, trimmed.length - 2) else trimmed + val fqName = FqName.fromSegments(stripped.split(".")) + fileBuilder.imports += buildImport { + fileBuilder.sourceFile?.project()?.let { + val dummyElement = KtPsiFactory(it, markGenerated = true).createColon() + source = KtFakeSourceElement(dummyElement, KtFakeSourceElementKind.ImplicitImport) + } + importedFqName = fqName + isAllUnder = endsWithStar } + } + } + + @OptIn(SymbolInternals::class) + override fun FirScriptBuilder.configure(sourceFile: KtSourceFile) { + val configuration = getOrLoadConfiguration(sourceFile) ?: run { + log.warn("Configuration for ${sourceFile.asString()} wasn't found. FirScriptBuilder wasn't configured.") + return + } // TODO: rewrite/extract decision logic for clarity configuration.getNoDefault(ScriptCompilationConfiguration.baseClass)?.let { baseClass -> @@ -85,9 +106,11 @@ class FirScriptConfiguratorExtensionImpl( } } } + configuration[ScriptCompilationConfiguration.implicitReceivers]?.forEach { implicitReceiver -> contextReceivers.add(buildContextReceiverWithFqName(FqName.fromSegments(implicitReceiver.typeName.split(".")))) } + configuration[ScriptCompilationConfiguration.providedProperties]?.forEach { (propertyName, propertyType) -> val typeRef = buildUserTypeRef { isMarkedNullable = propertyType.isNullable @@ -108,24 +131,6 @@ class FirScriptConfiguratorExtensionImpl( } ) } - configuration[ScriptCompilationConfiguration.annotationsForSamWithReceivers]?.forEach { - _knownAnnotationsForSamWithReceiver.add(it.typeName) - } - - configuration[ScriptCompilationConfiguration.defaultImports]?.forEach { defaultImport -> - val trimmed = defaultImport.trim() - val endsWithStar = trimmed.endsWith("*") - val stripped = if (endsWithStar) trimmed.substring(0, trimmed.length - 2) else trimmed - val fqName = FqName.fromSegments(stripped.split(".")) - fileBuilder.imports += buildImport { - fileBuilder.sourceFile?.project()?.let { - val dummyElement = KtPsiFactory(it, markGenerated = true).createColon() - source = KtFakeSourceElement(dummyElement, KtFakeSourceElementKind.ImplicitImport) - } - importedFqName = fqName - isAllUnder = endsWithStar - } - } configuration[ScriptCompilationConfiguration.annotationsForSamWithReceivers]?.forEach { _knownAnnotationsForSamWithReceiver.add(it.typeName)