diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt index f82e542abe5..763ab7b302f 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/lazy/resolve/RawFirNonLocalDeclarationBuilder.kt @@ -146,10 +146,17 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( } private inner class VisitorWithReplacement(private val containingClass: FirRegularClass?) : Visitor() { - fun convertDestructuringDeclaration(element: KtDestructuringDeclaration): FirVariable { + fun convertDestructuringDeclaration(element: KtDestructuringDeclaration, containingDeclaration: FirDeclaration?): FirVariable { val replacementDeclaration = replacementApplier?.tryReplace(element) ?: element requireIsInstance(replacementDeclaration) - return buildErrorTopLevelDestructuringDeclaration(replacementDeclaration.toFirSourceElement()) + return if (containingDeclaration is FirScript) { + withContainerSymbol(containingDeclaration.symbol) { + // Annotations from script destructuring declarations are linked to the script itself + buildScriptDestructuringDeclaration(replacementDeclaration) + } + } else { + buildErrorTopLevelDestructuringDeclaration(replacementDeclaration.toFirSourceElement()) + } } fun convertAnonymousInitializer(element: KtAnonymousInitializer, containingDeclaration: FirDeclaration?): FirAnonymousInitializer { @@ -348,7 +355,7 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( else -> visitor.convertElement(declarationToBuild, originalDeclaration) } } - is KtDestructuringDeclaration -> visitor.convertDestructuringDeclaration(declarationToBuild) + is KtDestructuringDeclaration -> visitor.convertDestructuringDeclaration(declarationToBuild, containingDeclaration) is KtCodeFragment -> { val firFile = visitor.convertElement(declarationToBuild, originalDeclaration) as FirFile firFile.codeFragment @@ -359,7 +366,7 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( } val parent = iterator.next() - if (parent !is FirRegularClass) return moveNext(iterator, containingDeclaration = null) + if (parent !is FirRegularClass) return moveNext(iterator, containingDeclaration = parent) val classOrObject = parent.psi if (classOrObject !is KtClassOrObject) { diff --git a/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructionWithNoRValueScript.txt b/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructionWithNoRValueScript.txt index d5620b3400f..81533820625 100644 --- a/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructionWithNoRValueScript.txt +++ b/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructionWithNoRValueScript.txt @@ -3,7 +3,7 @@ FIR element: FirPropertyImpl FIR source kind: KtRealSourceElementKind FIR element rendered: -[ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableMarkerKey=true] lval : = ERROR_EXPR(Initializer required for destructuring declaration) +[ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableMarkerKey=true] lval : = LAZY_EXPRESSION FIR FILE: FILE: [ResolvedTo(IMPORTS)] destructionWithNoRValueScript.kts @@ -11,7 +11,7 @@ FILE: [ResolvedTo(IMPORTS)] destructionWithNoRValueScript.kts SCRIPT: [ResolvedTo(RAW_FIR)] [ResolvedTo(RAW_FIR)] lval args: R|kotlin/Array| - [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableMarkerKey=true] lval : = ERROR_EXPR(Initializer required for destructuring declaration) + [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableMarkerKey=true] lval : = LAZY_EXPRESSION public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val o: = R|/|.component1#() diff --git a/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructuringScript.txt b/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructuringScript.txt index d6a88523738..02ccc83d6b4 100644 --- a/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructuringScript.txt +++ b/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructuringScript.txt @@ -3,7 +3,7 @@ FIR element: FirPropertyImpl FIR source kind: KtRealSourceElementKind FIR element rendered: -[ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableMarkerKey=true] lval : = pair# +[ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableMarkerKey=true] lval : = LAZY_EXPRESSION FIR FILE: FILE: [ResolvedTo(IMPORTS)] destructuringScript.kts @@ -22,7 +22,7 @@ FILE: [ResolvedTo(IMPORTS)] destructuringScript.kts public? final? [ResolvedTo(RAW_FIR)] val pair: = LAZY_EXPRESSION public? [ResolvedTo(RAW_FIR)] get(): - [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableMarkerKey=true] lval : = pair# + [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableMarkerKey=true] lval : = LAZY_EXPRESSION public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val first: = R|/|.component1#() 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 36c9b4d666d..b46911759f2 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 @@ -1280,6 +1280,26 @@ open class PsiRawFirBuilder( } } + protected fun buildScriptDestructuringDeclaration(destructuringDeclaration: KtDestructuringDeclaration): FirVariable { + val initializer = destructuringDeclaration.initializer + val firInitializer = buildOrLazyExpression(initializer?.toFirSourceElement()) { + initializer.toFirExpression { ConeSyntaxDiagnostic("Initializer required for destructuring declaration") } + } + + val destructuringContainerVar = generateTemporaryVariable( + moduleData = baseModuleData, + source = destructuringDeclaration.toFirSourceElement(), + specialName = "destruct", + initializer = firInitializer, + origin = FirDeclarationOrigin.Synthetic.ScriptTopLevelDestructuringDeclarationContainer, + extractAnnotationsTo = { extractAnnotationsTo(it) }, + ).apply { + isDestructuringDeclarationContainerVariable = true + } + + return destructuringContainerVar + } + private fun convertScript( script: KtScript, fileName: String, @@ -1301,7 +1321,6 @@ open class PsiRawFirBuilder( while (scriptDeclarationsIter.hasNext()) { val declaration = scriptDeclarationsIter.next() val isLast = !scriptDeclarationsIter.hasNext() - val declarationSource = declaration.toFirSourceElement() when (declaration) { is KtScriptInitializer -> { val initializer = buildAnonymousInitializer( @@ -1315,16 +1334,7 @@ open class PsiRawFirBuilder( declarations.add(initializer) } is KtDestructuringDeclaration -> { - val destructuringContainerVar = generateTemporaryVariable( - baseModuleData, - declarationSource, - "destruct", - declaration.initializer.toFirExpression { ConeSyntaxDiagnostic("Initializer required for destructuring declaration") }, - origin = FirDeclarationOrigin.Synthetic.ScriptTopLevelDestructuringDeclarationContainer, - extractAnnotationsTo = { extractAnnotationsTo(it) } - ).apply { - isDestructuringDeclarationContainerVariable = true - } + val destructuringContainerVar = buildScriptDestructuringDeclaration(declaration) declarations.add(destructuringContainerVar) declarations.addDestructuringVariables( diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/scriptLevelDestructuringWithAnnotation.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/scriptLevelDestructuringWithAnnotation.lazyBodies.txt index 4e2eb670b82..9e8f3b8e89a 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/scriptLevelDestructuringWithAnnotation.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/scriptLevelDestructuringWithAnnotation.lazyBodies.txt @@ -1,15 +1,17 @@ FILE: scriptLevelDestructuringWithAnnotation.kts SCRIPT: - @DestrAnno(LAZY_EXPRESSION) lval : = IntegerLiteral(0).to#(IntegerLiteral(1)) + @DestrAnno(LAZY_EXPRESSION) lval : = LAZY_EXPRESSION @LeftAnno(LAZY_EXPRESSION) public final val a: = R|/|.component1#() @RightAnno(LAZY_EXPRESSION) public final val b: = R|/|.component2#() - @Destr2Anno(LAZY_EXPRESSION) lval : = IntegerLiteral(2).to#(IntegerLiteral(3)) + @Destr2Anno(LAZY_EXPRESSION) lval : = LAZY_EXPRESSION @SecondLeftAnno(LAZY_EXPRESSION) public final val c: = R|/|.component1#() @SecondRightAnno(LAZY_EXPRESSION) public final val d: = R|/|.component2#() + +