From 312feb3dca0299fa9c2f06e068fd7f4496f4d430 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Fri, 9 Feb 2024 23:14:50 +0100 Subject: [PATCH] [FIR] make script destructuring declaration entry initializer lazy expression This change is required to properly support such declarations in lazy resolution mode as we usually replaced initializers with lazy expressions during the body calculation phase ^KT-62840 --- .../RawFirNonLocalDeclarationBuilder.kt | 33 +++++++++ .../annotations/destructuringAnnotation.txt | 4 +- .../destructionWithNoRValueScript.txt | 4 +- .../declarations/destructuringScript.txt | 4 +- ...tementLevelAsLastStatement.lazyResolve.txt | 72 +++++++++---------- .../kotlin/fir/builder/PsiRawFirBuilder.kt | 14 +++- ...DestructuringWithAnnotation.lazyBodies.txt | 8 +-- ...thAnnotationAsLastStatement.lazyBodies.txt | 8 +-- .../kotlin/fir/builder/Destructuring.kt | 55 +++++++++----- 9 files changed, 135 insertions(+), 67 deletions(-) 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 763ab7b302f..0e7aabdae7a 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 @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.analysis.utils.errors.withPsiEntry import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.builder.BodyBuildingMode import org.jetbrains.kotlin.fir.builder.PsiRawFirBuilder +import org.jetbrains.kotlin.fir.builder.buildDestructuringVariable import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.expressions.FirAnnotation @@ -27,12 +28,15 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry import org.jetbrains.kotlin.name.NameUtils import org.jetbrains.kotlin.psi import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.util.PrivateForInline import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment +import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment +import org.jetbrains.kotlin.utils.exceptions.withPsiEntry internal class RawFirNonLocalDeclarationBuilder private constructor( session: FirSession, @@ -159,6 +163,34 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( } } + fun convertDestructuringDeclarationEntry(element: KtDestructuringDeclarationEntry): FirVariable { + val replacementDeclaration = replacementApplier?.tryReplace(element) ?: element + requireIsInstance(replacementDeclaration) + requireIsInstance(originalDeclaration) + + val container = originalDeclaration.destructuringDeclarationContainerVariable?.fir + requireWithAttachment(container != null, { "Container is not found"}) { + withFirEntry("originalDeclaration", originalDeclaration) + withPsiEntry("element", element) + } + + return buildDestructuringVariable( + moduleData = baseModuleData, + container = container, + element, + isVar = false, + localEntries = false, + index = element.index(), + configure = { configureScriptDestructuringDeclarationEntry(it, container) }, + ) + } + + private fun KtDestructuringDeclarationEntry.index(): Int { + val destructuringDeclaration = parent + requireIsInstance(destructuringDeclaration) + return destructuringDeclaration.entries.indexOf(this) + } + fun convertAnonymousInitializer(element: KtAnonymousInitializer, containingDeclaration: FirDeclaration?): FirAnonymousInitializer { val replacementDeclaration = replacementApplier?.tryReplace(element) ?: element requireIsInstance(replacementDeclaration) @@ -356,6 +388,7 @@ internal class RawFirNonLocalDeclarationBuilder private constructor( } } is KtDestructuringDeclaration -> visitor.convertDestructuringDeclaration(declarationToBuild, containingDeclaration) + is KtDestructuringDeclarationEntry -> visitor.convertDestructuringDeclarationEntry(declarationToBuild) is KtCodeFragment -> { val firFile = visitor.convertElement(declarationToBuild, originalDeclaration) as FirFile firFile.codeFragment diff --git a/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/destructuringAnnotation.txt b/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/destructuringAnnotation.txt index 16685a81702..d1eaf6fad38 100644 --- a/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/destructuringAnnotation.txt +++ b/analysis/low-level-api-fir/testData/getOrBuildFir/annotations/destructuringAnnotation.txt @@ -44,7 +44,7 @@ FILE: [ResolvedTo(IMPORTS)] destructuringAnnotation.kts } @R|DestrAnno|[Types](s = (String(destr 1 ), R|/prop|)) [ResolvedTo(ANNOTATION_ARGUMENTS)] [DestructuringDeclarationContainerVariableMarkerKey=true] lval : R|MyPair| = R|/MyPair.MyPair|(Int(1), Int(2)) - public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val a: = R|/|.component1#() + public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val a: = LAZY_EXPRESSION - public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val b: = R|/|.component2#() + public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val b: = LAZY_EXPRESSION \ No newline at end of file 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 02bf6fa7743..5d4f52c6d8f 100644 --- a/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructionWithNoRValueScript.txt +++ b/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructionWithNoRValueScript.txt @@ -12,7 +12,7 @@ FILE: [ResolvedTo(IMPORTS)] destructionWithNoRValueScript.kts [ResolvedTo(RAW_FIR)] lval args: R|kotlin/Array| [ResolvedTo(BODY_RESOLVE)] [DestructuringDeclarationContainerVariableMarkerKey=true] lval : = ERROR_EXPR(Initializer required for destructuring declaration) - public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val o: = R|/|.component1#() + public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val o: = LAZY_EXPRESSION - public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val r: = R|/|.component2#() + public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val r: = LAZY_EXPRESSION 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 e89f3c063e1..43502e6e841 100644 --- a/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructuringScript.txt +++ b/analysis/low-level-api-fir/testData/getOrBuildFir/declarations/destructuringScript.txt @@ -23,7 +23,7 @@ FILE: [ResolvedTo(IMPORTS)] destructuringScript.kts public [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] get(): R|kotlin/Pair| [ResolvedTo(BODY_RESOLVE)] [DestructuringDeclarationContainerVariableMarkerKey=true] lval : R|kotlin/Pair| = R|/pair| - public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val first: = R|/|.component1#() + public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val first: = LAZY_EXPRESSION - public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val last: = R|/|.component2#() + public final [ResolvedTo(RAW_FIR)] [DestructuringDeclarationContainerVariableKey=/] val last: = LAZY_EXPRESSION diff --git a/analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/scriptStatementLevelAsLastStatement.lazyResolve.txt b/analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/scriptStatementLevelAsLastStatement.lazyResolve.txt index de7ab015002..98f39711528 100644 --- a/analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/scriptStatementLevelAsLastStatement.lazyResolve.txt +++ b/analysis/low-level-api-fir/testData/lazyResolveTypeAnnotations/destructuringDeclaration/scriptStatementLevelAsLastStatement.lazyResolve.txt @@ -42,11 +42,11 @@ FILE: [ResolvedTo(RAW_FIR)] scriptStatementLevelAsLastStatement.kts public final [ResolvedTo(RAW_FIR)] val $$result: = when () { Boolean(true) -> { @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = LAZY_EXPRESSION @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = LAZY_EXPRESSION } } @@ -97,11 +97,11 @@ FILE: [ResolvedTo(IMPORTS)] scriptStatementLevelAsLastStatement.kts public final [ResolvedTo(RAW_FIR)] val $$result: = when () { Boolean(true) -> { @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = LAZY_EXPRESSION @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = LAZY_EXPRESSION } } @@ -152,11 +152,11 @@ FILE: [ResolvedTo(IMPORTS)] scriptStatementLevelAsLastStatement.kts public final [ResolvedTo(COMPILER_REQUIRED_ANNOTATIONS)] val $$result: = when () { Boolean(true) -> { @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = LAZY_EXPRESSION @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = LAZY_EXPRESSION } } @@ -207,11 +207,11 @@ FILE: [ResolvedTo(IMPORTS)] scriptStatementLevelAsLastStatement.kts public final [ResolvedTo(COMPANION_GENERATION)] val $$result: = when () { Boolean(true) -> { @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = LAZY_EXPRESSION @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = LAZY_EXPRESSION } } @@ -262,11 +262,11 @@ FILE: [ResolvedTo(IMPORTS)] scriptStatementLevelAsLastStatement.kts public final [ResolvedTo(SUPER_TYPES)] val $$result: = when () { Boolean(true) -> { @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = LAZY_EXPRESSION @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = LAZY_EXPRESSION } } @@ -317,11 +317,11 @@ FILE: [ResolvedTo(IMPORTS)] scriptStatementLevelAsLastStatement.kts public final [ResolvedTo(TYPES)] val $$result: = when () { Boolean(true) -> { @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = LAZY_EXPRESSION @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = LAZY_EXPRESSION } } @@ -372,11 +372,11 @@ FILE: [ResolvedTo(IMPORTS)] scriptStatementLevelAsLastStatement.kts public final [ResolvedTo(STATUS)] val $$result: = when () { Boolean(true) -> { @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = LAZY_EXPRESSION @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = LAZY_EXPRESSION } } @@ -427,11 +427,11 @@ FILE: [ResolvedTo(IMPORTS)] scriptStatementLevelAsLastStatement.kts public final [ResolvedTo(EXPECT_ACTUAL_MATCHING)] val $$result: = when () { Boolean(true) -> { @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = LAZY_EXPRESSION @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = LAZY_EXPRESSION } } @@ -482,11 +482,11 @@ FILE: [ResolvedTo(IMPORTS)] scriptStatementLevelAsLastStatement.kts public final [ResolvedTo(CONTRACTS)] val $$result: = when () { Boolean(true) -> { @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval a: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval b: = LAZY_EXPRESSION @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval : = Pair#(LAZY_EXPRESSION, LAZY_EXPRESSION) - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = R|/|.component1#() - @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = R|/|.component2#() + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval c: = LAZY_EXPRESSION + @Anno[Unresolved](LAZY_EXPRESSION) [ResolvedTo(RAW_FIR)] lval d: = LAZY_EXPRESSION } } 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 b46911759f2..1eff107080a 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 @@ -198,6 +198,14 @@ open class PsiRawFirBuilder( (this as KtAnnotated).extractAnnotationsTo(target) } + override fun createComponentCall( + container: FirVariable, + entrySource: KtSourceElement?, + index: Int, + ): FirExpression = buildOrLazyExpression(entrySource) { + super.createComponentCall(container, entrySource, index) + } + private inline fun KtElement?.convertSafe(): R? = this?.let { convertElement(it, null) } as? R @@ -1280,6 +1288,10 @@ open class PsiRawFirBuilder( } } + protected fun configureScriptDestructuringDeclarationEntry(declaration: FirVariable, container: FirVariable) { + (declaration as FirProperty).destructuringDeclarationContainerVariable = container.symbol + } + protected fun buildScriptDestructuringDeclaration(destructuringDeclaration: KtDestructuringDeclaration): FirVariable { val initializer = destructuringDeclaration.initializer val firInitializer = buildOrLazyExpression(initializer?.toFirSourceElement()) { @@ -1344,7 +1356,7 @@ open class PsiRawFirBuilder( tmpVariable = false, localEntries = false, ) { - (it as FirProperty).destructuringDeclarationContainerVariable = destructuringContainerVar.symbol + configureScriptDestructuringDeclarationEntry(it, destructuringContainerVar) } } else -> { 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 9e8f3b8e89a..d05dced7c47 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 @@ -2,16 +2,16 @@ FILE: scriptLevelDestructuringWithAnnotation.kts SCRIPT: @DestrAnno(LAZY_EXPRESSION) lval : = LAZY_EXPRESSION - @LeftAnno(LAZY_EXPRESSION) public final val a: = R|/|.component1#() + @LeftAnno(LAZY_EXPRESSION) public final val a: = LAZY_EXPRESSION - @RightAnno(LAZY_EXPRESSION) public final val b: = R|/|.component2#() + @RightAnno(LAZY_EXPRESSION) public final val b: = LAZY_EXPRESSION @Destr2Anno(LAZY_EXPRESSION) lval : = LAZY_EXPRESSION - @SecondLeftAnno(LAZY_EXPRESSION) public final val c: = R|/|.component1#() + @SecondLeftAnno(LAZY_EXPRESSION) public final val c: = LAZY_EXPRESSION - @SecondRightAnno(LAZY_EXPRESSION) public final val d: = R|/|.component2#() + @SecondRightAnno(LAZY_EXPRESSION) public final val d: = LAZY_EXPRESSION diff --git a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/scriptStatementLevelDestructuringWithAnnotationAsLastStatement.lazyBodies.txt b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/scriptStatementLevelDestructuringWithAnnotationAsLastStatement.lazyBodies.txt index eb5eb28bac2..0c1aa7d219e 100644 --- a/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/scriptStatementLevelDestructuringWithAnnotationAsLastStatement.lazyBodies.txt +++ b/compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/scriptStatementLevelDestructuringWithAnnotationAsLastStatement.lazyBodies.txt @@ -5,12 +5,12 @@ FILE: scriptStatementLevelDestructuringWithAnnotationAsLastStatement.kts when () { Boolean(true) -> { @DestrAnno(LAZY_EXPRESSION) lval : = IntegerLiteral(0).to#(IntegerLiteral(1)) - @LeftAnno(LAZY_EXPRESSION) lval a: = R|/|.component1#() - @RightAnno(LAZY_EXPRESSION) lval b: = R|/|.component2#() + @LeftAnno(LAZY_EXPRESSION) lval a: = LAZY_EXPRESSION + @RightAnno(LAZY_EXPRESSION) lval b: = LAZY_EXPRESSION run#( = LAZY_EXPRESSION) @Destr2Anno(LAZY_EXPRESSION) lval : = IntegerLiteral(2).to#(IntegerLiteral(3)) - @SecondLeftAnno(LAZY_EXPRESSION) lval c: = R|/|.component1#() - @SecondRightAnno(LAZY_EXPRESSION) lval d: = R|/|.component2#() + @SecondLeftAnno(LAZY_EXPRESSION) lval c: = LAZY_EXPRESSION + @SecondRightAnno(LAZY_EXPRESSION) lval d: = LAZY_EXPRESSION } } diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Destructuring.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Destructuring.kt index ea9cace1308..bc7c8a111f1 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Destructuring.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/Destructuring.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirVariable import org.jetbrains.kotlin.fir.declarations.builder.buildProperty import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl +import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.types.FirTypeRef @@ -23,6 +24,9 @@ interface DestructuringContext { val T.name: Name val T.source: KtSourceElement fun T.extractAnnotationsTo(target: FirAnnotationContainerBuilder, containerSymbol: FirBasedSymbol<*>) + fun createComponentCall(container: FirVariable, entrySource: KtSourceElement?, index: Int): FirExpression { + return container.toComponentCall(entrySource, index) + } } context(AbstractRawFirBuilder<*>, DestructuringContext) @@ -39,20 +43,39 @@ fun MutableList.addDestructuringVariables( this += container } for ((index, entry) in entries.withIndex()) { - this += buildProperty { - symbol = FirPropertySymbol(entry.name) - withContainerSymbol(symbol, localEntries) { - this.moduleData = moduleData - origin = FirDeclarationOrigin.Source - returnTypeRef = entry.returnTypeRef - name = entry.name - initializer = container.toComponentCall(entry.source, index) - this.isVar = isVar - source = entry.source - isLocal = localEntries - status = FirDeclarationStatusImpl(if (localEntries) Visibilities.Local else Visibilities.Public, Modality.FINAL) - entry.extractAnnotationsTo(this, context.containerSymbol) - } - }.also(configure) + this += buildDestructuringVariable( + moduleData, + container, + entry, + isVar, + localEntries, + index, + configure, + ) } -} \ No newline at end of file +} + +context(AbstractRawFirBuilder<*>, DestructuringContext) +fun buildDestructuringVariable( + moduleData: FirModuleData, + container: FirVariable, + entry: T, + isVar: Boolean, + localEntries: Boolean, + index: Int, + configure: (FirVariable) -> Unit = {} +): FirVariable = buildProperty { + symbol = FirPropertySymbol(entry.name) + withContainerSymbol(symbol, localEntries) { + this.moduleData = moduleData + origin = FirDeclarationOrigin.Source + returnTypeRef = entry.returnTypeRef + name = entry.name + initializer = createComponentCall(container, entry.source, index) + this.isVar = isVar + source = entry.source + isLocal = localEntries + status = FirDeclarationStatusImpl(if (localEntries) Visibilities.Local else Visibilities.Public, Modality.FINAL) + entry.extractAnnotationsTo(this, context.containerSymbol) + } +}.also(configure) \ No newline at end of file