[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
This commit is contained in:
Dmitrii Gridin
2024-02-09 23:14:50 +01:00
committed by Space Team
parent c0f4f7fefd
commit 312feb3dca
9 changed files with 135 additions and 67 deletions
@@ -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 <reified R : FirElement> 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 -> {
@@ -2,16 +2,16 @@ FILE: scriptLevelDestructuringWithAnnotation.kts
SCRIPT: <script-scriptLevelDestructuringWithAnnotation.kts>
@DestrAnno(LAZY_EXPRESSION) lval <destruct>: <implicit> = LAZY_EXPRESSION
@LeftAnno(LAZY_EXPRESSION) public final val a: <implicit> = R|<local>/<destruct>|.component1#()
@LeftAnno(LAZY_EXPRESSION) public final val a: <implicit> = LAZY_EXPRESSION
@RightAnno(LAZY_EXPRESSION) public final val b: <implicit> = R|<local>/<destruct>|.component2#()
@RightAnno(LAZY_EXPRESSION) public final val b: <implicit> = LAZY_EXPRESSION
@Destr2Anno(LAZY_EXPRESSION) lval <destruct>: <implicit> = LAZY_EXPRESSION
@SecondLeftAnno(LAZY_EXPRESSION) public final val c: <implicit> = R|<local>/<destruct>|.component1#()
@SecondLeftAnno(LAZY_EXPRESSION) public final val c: <implicit> = LAZY_EXPRESSION
@SecondRightAnno(LAZY_EXPRESSION) public final val d: <implicit> = R|<local>/<destruct>|.component2#()
@SecondRightAnno(LAZY_EXPRESSION) public final val d: <implicit> = LAZY_EXPRESSION
@@ -5,12 +5,12 @@ FILE: scriptStatementLevelDestructuringWithAnnotationAsLastStatement.kts
when () {
Boolean(true) -> {
@DestrAnno(LAZY_EXPRESSION) lval <destruct>: <implicit> = IntegerLiteral(0).to#(IntegerLiteral(1))
@LeftAnno(LAZY_EXPRESSION) lval a: <implicit> = R|<local>/<destruct>|.component1#()
@RightAnno(LAZY_EXPRESSION) lval b: <implicit> = R|<local>/<destruct>|.component2#()
@LeftAnno(LAZY_EXPRESSION) lval a: <implicit> = LAZY_EXPRESSION
@RightAnno(LAZY_EXPRESSION) lval b: <implicit> = LAZY_EXPRESSION
run#(<L> = LAZY_EXPRESSION)
@Destr2Anno(LAZY_EXPRESSION) lval <destruct>: <implicit> = IntegerLiteral(2).to#(IntegerLiteral(3))
@SecondLeftAnno(LAZY_EXPRESSION) lval c: <implicit> = R|<local>/<destruct>|.component1#()
@SecondRightAnno(LAZY_EXPRESSION) lval d: <implicit> = R|<local>/<destruct>|.component2#()
@SecondLeftAnno(LAZY_EXPRESSION) lval c: <implicit> = LAZY_EXPRESSION
@SecondRightAnno(LAZY_EXPRESSION) lval d: <implicit> = LAZY_EXPRESSION
}
}
@@ -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<T> {
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<T>)
@@ -39,20 +43,39 @@ fun <T> MutableList<in FirVariable>.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,
)
}
}
}
context(AbstractRawFirBuilder<*>, DestructuringContext<T>)
fun <T> 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)