[LL FIR] reanalyse declarations on the air for incremental analysis

We cannot do it inplace now as we do not have a lock to do
it under after analysis started to use declaration-level lock

This part is mostly covered by the plugin tests
(which failed after the previous commit)

^KT-56543
This commit is contained in:
Dmitrii Gridin
2023-04-04 17:56:47 +02:00
committed by Space Team
parent 72def186a3
commit 332cdc514b
4 changed files with 233 additions and 95 deletions
@@ -8,23 +8,22 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession import org.jetbrains.kotlin.analysis.low.level.api.fir.api.*
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LowLevelFirApiFacadeForResolveOnAir
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.ClassDiagnosticRetriever import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.ClassDiagnosticRetriever
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.FileDiagnosticRetriever import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.FileDiagnosticRetriever
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.FileStructureElementDiagnostics import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.FileStructureElementDiagnostics
import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.SingleNonLocalDeclarationDiagnosticRetriever import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostics.SingleNonLocalDeclarationDiagnosticRetriever
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.RawFirNonLocalDeclarationBuilder import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.RawFirNonLocalDeclarationBuilder
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withInvalidationOnException
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.FirBackingFieldBuilder
import org.jetbrains.kotlin.fir.declarations.builder.FirFunctionBuilder
import org.jetbrains.kotlin.fir.declarations.builder.FirPropertyBuilder
import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor import org.jetbrains.kotlin.fir.declarations.impl.FirPrimaryConstructor
import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@@ -108,42 +107,33 @@ internal class ReanalyzableFunctionStructureElement(
override fun reanalyze(newKtDeclaration: KtNamedFunction): ReanalyzableFunctionStructureElement { override fun reanalyze(newKtDeclaration: KtNamedFunction): ReanalyzableFunctionStructureElement {
val originalFunction = firSymbol.fir as FirSimpleFunction val originalFunction = firSymbol.fir as FirSimpleFunction
val designation = originalFunction.collectDesignation() val originalDesignation = originalFunction.collectDesignation()
val temporaryFunction = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( val newFunction = RawFirNonLocalDeclarationBuilder.buildNewSimpleFunction(
session = originalFunction.moduleData.session, session = originalFunction.moduleData.session,
scopeProvider = originalFunction.moduleData.session.kotlinScopeProvider, scopeProvider = originalFunction.moduleData.session.kotlinScopeProvider,
designation = designation, designation = originalDesignation,
rootNonLocalDeclaration = newKtDeclaration, newFunction = newKtDeclaration,
) as FirSimpleFunction additionalFunctionInit = {
copyUnmodifiableFieldsForFunction(originalFunction)
},
)
return moduleComponents.globalResolveComponents.lockProvider.withGlobalLock(firFile) { newFunction.apply {
val upgradedPhase = minOf(originalFunction.resolvePhase, FirResolvePhase.DECLARATIONS) copyAllExceptBodyForFunction(originalFunction)
withInvalidationOnException(moduleComponents.session) { @OptIn(ResolveStateAccess::class)
with(originalFunction) { resolveState = FirResolvePhase.STATUS.asResolveState()
replaceBody(temporaryFunction.body)
replaceContractDescription(temporaryFunction.contractDescription)
@OptIn(ResolveStateAccess::class)
resolveState = upgradedPhase.asResolveState()
}
designation.toSequence(includeTarget = true).forEach {
@OptIn(ResolveStateAccess::class)
it.resolveState = minOf(it.resolvePhase, upgradedPhase).asResolveState()
}
originalFunction.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
ReanalyzableFunctionStructureElement(
firFile,
newKtDeclaration,
originalFunction.symbol,
newKtDeclaration.modificationStamp,
moduleComponents,
)
}
} }
newFunction.bodyResolveOnAir(originalDesignation, firFile, moduleComponents)
return ReanalyzableFunctionStructureElement(
firFile,
newKtDeclaration,
newFunction.symbol,
newKtDeclaration.modificationStamp,
moduleComponents,
)
} }
} }
@@ -158,43 +148,67 @@ internal class ReanalyzablePropertyStructureElement(
override fun reanalyze(newKtDeclaration: KtProperty): ReanalyzablePropertyStructureElement { override fun reanalyze(newKtDeclaration: KtProperty): ReanalyzablePropertyStructureElement {
val originalProperty = firSymbol.fir val originalProperty = firSymbol.fir
val designation = originalProperty.collectDesignation() val originalDesignation = originalProperty.collectDesignation()
val temporaryProperty = RawFirNonLocalDeclarationBuilder.buildWithFunctionSymbolRebind( val newProperty = RawFirNonLocalDeclarationBuilder.buildNewProperty(
session = originalProperty.moduleData.session, session = originalProperty.moduleData.session,
scopeProvider = originalProperty.moduleData.session.kotlinScopeProvider, scopeProvider = originalProperty.moduleData.session.kotlinScopeProvider,
designation = designation, designation = originalDesignation,
rootNonLocalDeclaration = newKtDeclaration, newProperty = newKtDeclaration,
) as FirProperty additionalPropertyInit = {
copyUnmodifiableFieldsForProperty(originalProperty)
return moduleComponents.globalResolveComponents.lockProvider.withGlobalLock(firFile) { },
val getterPhase = originalProperty.getter?.resolvePhase ?: originalProperty.resolvePhase additionalAccessorInit = {
val setterPhase = originalProperty.setter?.resolvePhase ?: originalProperty.resolvePhase copyUnmodifiableFieldsForFunction(
val upgradedPhase = minOf(originalProperty.resolvePhase, getterPhase, setterPhase, FirResolvePhase.DECLARATIONS) if (isGetter) {
originalProperty.getter!!
withInvalidationOnException(moduleComponents.session) { } else {
@OptIn(ResolveStateAccess::class) originalProperty.setter!!
with(originalProperty) { }
getter?.replaceBody(temporaryProperty.getter?.body)
setter?.replaceBody(temporaryProperty.setter?.body)
replaceInitializer(temporaryProperty.initializer)
getter?.resolveState = upgradedPhase.asResolveState()
setter?.resolveState = upgradedPhase.asResolveState()
resolveState = upgradedPhase.asResolveState()
replaceBodyResolveState(FirPropertyBodyResolveState.NOTHING_RESOLVED)
}
originalProperty.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
ReanalyzablePropertyStructureElement(
firFile,
newKtDeclaration,
originalProperty.symbol,
newKtDeclaration.modificationStamp,
moduleComponents,
) )
},
additionalBackingFieldInit = {
copyUnmodifiableFieldsForBackingField(originalProperty.backingField!!)
},
)
newProperty.apply {
copyAllExceptBodyFromCallable(originalProperty)
replaceBodyResolveState(FirPropertyBodyResolveState.NOTHING_RESOLVED)
@OptIn(ResolveStateAccess::class)
resolveState = FirResolvePhase.STATUS.asResolveState()
getter?.let { getter ->
getter.copyAllExceptBodyForFunction(originalProperty.getter!!)
@OptIn(ResolveStateAccess::class)
getter.resolveState = FirResolvePhase.STATUS.asResolveState()
}
setter?.let { setter ->
setter.copyAllExceptBodyForFunction(originalProperty.setter!!)
@OptIn(ResolveStateAccess::class)
setter.resolveState = FirResolvePhase.STATUS.asResolveState()
}
backingField?.let { backingField ->
backingField.copyAllExceptBodyFromCallable(originalProperty.backingField!!)
@OptIn(ResolveStateAccess::class)
backingField.resolveState = FirResolvePhase.STATUS.asResolveState()
} }
} }
newProperty.bodyResolveOnAir(originalDesignation, firFile, moduleComponents)
return ReanalyzablePropertyStructureElement(
firFile,
newKtDeclaration,
newProperty.symbol,
newKtDeclaration.modificationStamp,
moduleComponents,
)
} }
} }
@@ -297,3 +311,55 @@ internal class RootStructureElement(
} }
} }
} }
private fun <C : FirCallableDeclaration> C.bodyResolveOnAir(
originalDesignation: FirDesignation,
firFile: FirFile,
moduleComponents: LLFirModuleResolveComponents
) {
val designationToResolveOnAir = FirDesignationWithFile(originalDesignation.path, this, firFile)
moduleComponents.firModuleLazyDeclarationResolver.runLazyDesignatedOnAirResolveToBodyWithoutLock(
designationToResolveOnAir,
onAirCreatedDeclaration = false,
towerDataContextCollector = null
)
}
private fun FirPropertyBuilder.copyUnmodifiableFieldsForProperty(prototype: FirProperty) {
attributes = prototype.attributes
dispatchReceiverType = prototype.dispatchReceiverType
}
private fun FirFunctionBuilder.copyUnmodifiableFieldsForFunction(prototype: FirFunction) {
attributes = prototype.attributes
dispatchReceiverType = prototype.dispatchReceiverType
}
private fun FirBackingFieldBuilder.copyUnmodifiableFieldsForBackingField(prototype: FirBackingField) {
attributes = prototype.attributes
dispatchReceiverType = prototype.dispatchReceiverType
}
private fun <F : FirFunction> F.copyAllExceptBodyForFunction(prototype: F) {
this.copyAllExceptBodyFromCallable(prototype)
this.replaceValueParameters(prototype.valueParameters)
if (this is FirContractDescriptionOwner) {
this.replaceContractDescription((prototype as FirContractDescriptionOwner).contractDescription)
}
}
private fun <C : FirCallableDeclaration> C.copyAllExceptBodyFromCallable(prototype: C) {
this.replaceAnnotations(prototype.annotations)
this.replaceReturnTypeRef(prototype.returnTypeRef)
this.replaceReceiverParameter(prototype.receiverParameter)
this.replaceStatus(prototype.status)
this.replaceDeprecationsProvider(prototype.deprecationsProvider)
this.replaceContextReceivers(prototype.contextReceivers)
// TODO add replaceTypeParameter to FirCallableDeclaration instead of this unsafe case
(this.typeParameters as MutableList<FirTypeParameterRef>).apply {
clear()
addAll(prototype.typeParameters)
}
}
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFil
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirClassWithAllMembersResolveTarget import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirClassWithAllMembersResolveTarget
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirSingleResolveTarget import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirSingleResolveTarget
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.forEachPathElementAndTarget
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyResolverRunner import org.jetbrains.kotlin.analysis.low.level.api.fir.transformers.LLFirLazyResolverRunner
@@ -55,6 +54,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
targets = LLFirResolveMultiDesignationCollector.getDesignationsToResolve(target), targets = LLFirResolveMultiDesignationCollector.getDesignationsToResolve(target),
scopeSession = scopeSession, scopeSession = scopeSession,
toPhase = toPhase, toPhase = toPhase,
towerDataContextCollector = null,
) )
} catch (e: Exception) { } catch (e: Exception) {
handleExceptionFromResolve(e, target, fromPhase, toPhase) handleExceptionFromResolve(e, target, fromPhase, toPhase)
@@ -84,6 +84,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
targets = LLFirResolveMultiDesignationCollector.getDesignationsToResolveWithCallableMembers(target), targets = LLFirResolveMultiDesignationCollector.getDesignationsToResolveWithCallableMembers(target),
scopeSession = scopeSession, scopeSession = scopeSession,
toPhase = toPhase, toPhase = toPhase,
towerDataContextCollector = null,
) )
} catch (e: Exception) { } catch (e: Exception) {
handleExceptionFromResolve(e, target, fromPhase, toPhase) handleExceptionFromResolve(e, target, fromPhase, toPhase)
@@ -105,45 +106,41 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
toPhase: FirResolvePhase toPhase: FirResolvePhase
) { ) {
try { try {
lazyResolveTargets(listOf(target), moduleComponents.scopeSessionProvider.getScopeSession(), toPhase) lazyResolveTargets(
targets = listOf(target),
moduleComponents.scopeSessionProvider.getScopeSession(),
toPhase,
towerDataContextCollector = null,
)
} catch (e: Exception) { } catch (e: Exception) {
handleExceptionFromResolve(e, target, toPhase) handleExceptionFromResolve(e, target, toPhase)
} }
} }
internal fun runLazyDesignatedOnAirResolveToBodyWithoutLock( fun runLazyDesignatedOnAirResolveToBodyWithoutLock(
designation: FirDesignationWithFile, designation: FirDesignationWithFile,
onAirCreatedDeclaration: Boolean, onAirCreatedDeclaration: Boolean,
towerDataContextCollector: FirTowerDataContextCollector?, towerDataContextCollector: FirTowerDataContextCollector?,
) { ) {
resolveFileToImportsWithoutLock(designation.firFile) resolveFileToImportsWithoutLock(designation.firFile)
val resolveTarget = when (designation.target) { val target = when (designation.target) {
is FirRegularClass -> LLFirClassWithAllMembersResolveTarget(designation.firFile, designation.path, designation.target) is FirRegularClass -> LLFirClassWithAllMembersResolveTarget(designation.firFile, designation.path, designation.target)
else -> LLFirSingleResolveTarget(designation.firFile, designation.path, designation.target) else -> LLFirSingleResolveTarget(designation.firFile, designation.path, designation.target)
} }
fun runTransformation() { fun runTransformation() {
val scopeSession = ScopeSession() val scopeSession = ScopeSession()
var currentPhase = maxOf(designation.target.resolvePhase, FirResolvePhase.IMPORTS) lazyResolveTargets(listOf(target), scopeSession, FirResolvePhase.BODY_RESOLVE, towerDataContextCollector)
while (currentPhase < FirResolvePhase.BODY_RESOLVE) {
currentPhase = currentPhase.next
checkCanceled()
LLFirLazyResolverRunner.runLazyResolverByPhase(
phase = currentPhase,
target = resolveTarget,
scopeSession = scopeSession,
lockProvider = moduleComponents.globalResolveComponents.lockProvider,
towerDataContextCollector = towerDataContextCollector,
)
}
} }
if (onAirCreatedDeclaration) { try {
withOnAirDesignation(designation, ::runTransformation) if (onAirCreatedDeclaration) {
} else { withOnAirDesignation(designation, ::runTransformation)
runTransformation() } else {
runTransformation()
}
} catch (e: Exception) {
handleExceptionFromResolve(e, target, FirResolvePhase.BODY_RESOLVE)
} }
} }
@@ -166,6 +163,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
targets: List<LLFirResolveTarget>, targets: List<LLFirResolveTarget>,
scopeSession: ScopeSession, scopeSession: ScopeSession,
toPhase: FirResolvePhase, toPhase: FirResolvePhase,
towerDataContextCollector: FirTowerDataContextCollector?,
) { ) {
if (targets.isEmpty()) return if (targets.isEmpty()) return
var currentPhase = getMinResolvePhase(targets).coerceAtLeast(FirResolvePhase.IMPORTS) var currentPhase = getMinResolvePhase(targets).coerceAtLeast(FirResolvePhase.IMPORTS)
@@ -181,7 +179,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
target = target, target = target,
scopeSession = scopeSession, scopeSession = scopeSession,
lockProvider = moduleComponents.globalResolveComponents.lockProvider, lockProvider = moduleComponents.globalResolveComponents.lockProvider,
towerDataContextCollector = null towerDataContextCollector = towerDataContextCollector,
) )
} }
} }
@@ -191,7 +189,7 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
var min = FirResolvePhase.BODY_RESOLVE var min = FirResolvePhase.BODY_RESOLVE
for (designation in designations) { for (designation in designations) {
if (min == FirResolvePhase.RAW_FIR) break if (min == FirResolvePhase.RAW_FIR) break
designation.forEachPathElementAndTarget { target -> designation.forEachTarget { target ->
min = minOf(min, target.resolvePhase) min = minOf(min, target.resolvePhase)
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2021 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. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -14,6 +14,10 @@ import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.builder.BodyBuildingMode import org.jetbrains.kotlin.fir.builder.BodyBuildingMode
import org.jetbrains.kotlin.fir.builder.RawFirBuilder import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.FirBackingFieldBuilder
import org.jetbrains.kotlin.fir.declarations.builder.FirFunctionBuilder
import org.jetbrains.kotlin.fir.declarations.builder.FirPropertyAccessorBuilder
import org.jetbrains.kotlin.fir.declarations.builder.FirPropertyBuilder
import org.jetbrains.kotlin.fir.declarations.utils.isInner import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.references.FirSuperReference
@@ -24,9 +28,7 @@ import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.psi import org.jetbrains.kotlin.psi
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
internal class RawFirNonLocalDeclarationBuilder private constructor( internal class RawFirNonLocalDeclarationBuilder private constructor(
@@ -35,9 +37,71 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
private val originalDeclaration: FirDeclaration, private val originalDeclaration: FirDeclaration,
private val declarationToBuild: KtDeclaration, private val declarationToBuild: KtDeclaration,
private val functionsToRebind: Set<FirFunction>? = null, private val functionsToRebind: Set<FirFunction>? = null,
private val replacementApplier: RawFirReplacement.Applier? = null private val replacementApplier: RawFirReplacement.Applier? = null,
private val additionalFunctionInit: FirFunctionBuilder.() -> Unit = {},
private val additionalPropertyInit: FirPropertyBuilder.() -> Unit = {},
private val additionalAccessorInit: FirPropertyAccessorBuilder.() -> Unit = {},
private val additionalBackingFieldInit: FirBackingFieldBuilder.() -> Unit = {},
) : RawFirBuilder(session, baseScopeProvider, bodyBuildingMode = BodyBuildingMode.NORMAL) { ) : RawFirBuilder(session, baseScopeProvider, bodyBuildingMode = BodyBuildingMode.NORMAL) {
override fun FirFunctionBuilder.additionalFunctionInit() {
additionalFunctionInit.invoke(this)
}
override fun FirPropertyBuilder.additionalPropertyInit() {
additionalPropertyInit.invoke(this)
}
override fun FirPropertyAccessorBuilder.additionalPropertyAccessorInit() {
additionalAccessorInit.invoke(this)
}
override fun FirBackingFieldBuilder.additionalBackingFieldInit() {
additionalBackingFieldInit.invoke(this)
}
companion object { companion object {
fun buildNewSimpleFunction(
session: FirSession,
scopeProvider: FirScopeProvider,
designation: FirDesignation,
newFunction: KtNamedFunction,
additionalFunctionInit: FirFunctionBuilder.() -> Unit,
): FirSimpleFunction {
val builder = RawFirNonLocalDeclarationBuilder(
session = session,
baseScopeProvider = scopeProvider,
originalDeclaration = designation.target as FirDeclaration,
declarationToBuild = newFunction,
additionalFunctionInit = additionalFunctionInit,
)
builder.context.packageFqName = newFunction.containingKtFile.packageFqName
return builder.moveNext(designation.path.iterator(), containingClass = null) as FirSimpleFunction
}
fun buildNewProperty(
session: FirSession,
scopeProvider: FirScopeProvider,
designation: FirDesignation,
newProperty: KtProperty,
additionalPropertyInit: FirPropertyBuilder.() -> Unit,
additionalAccessorInit: FirPropertyAccessorBuilder.() -> Unit,
additionalBackingFieldInit: FirBackingFieldBuilder.() -> Unit,
): FirProperty {
val builder = RawFirNonLocalDeclarationBuilder(
session = session,
baseScopeProvider = scopeProvider,
originalDeclaration = designation.target as FirDeclaration,
declarationToBuild = newProperty,
additionalPropertyInit = additionalPropertyInit,
additionalAccessorInit = additionalAccessorInit,
additionalBackingFieldInit = additionalBackingFieldInit,
)
builder.context.packageFqName = newProperty.containingKtFile.packageFqName
return builder.moveNext(designation.path.iterator(), containingClass = null) as FirProperty
}
fun buildWithReplacement( fun buildWithReplacement(
session: FirSession, session: FirSession,
scopeProvider: FirScopeProvider, scopeProvider: FirScopeProvider,
@@ -1,5 +1,5 @@
/* /*
* 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. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@@ -57,6 +57,10 @@ open class RawFirBuilder(
bodyBuildingMode: BodyBuildingMode = BodyBuildingMode.NORMAL bodyBuildingMode: BodyBuildingMode = BodyBuildingMode.NORMAL
) : BaseFirBuilder<PsiElement>(session) { ) : BaseFirBuilder<PsiElement>(session) {
protected open fun bindFunctionTarget(target: FirFunctionTarget, function: FirFunction) = target.bind(function) protected open fun bindFunctionTarget(target: FirFunctionTarget, function: FirFunction) = target.bind(function)
protected open fun FirFunctionBuilder.additionalFunctionInit() {}
protected open fun FirPropertyBuilder.additionalPropertyInit() {}
protected open fun FirPropertyAccessorBuilder.additionalPropertyAccessorInit() {}
protected open fun FirBackingFieldBuilder.additionalBackingFieldInit() {}
var mode: BodyBuildingMode = bodyBuildingMode var mode: BodyBuildingMode = bodyBuildingMode
private set private set
@@ -479,6 +483,8 @@ open class RawFirBuilder(
this.contractDescription = it this.contractDescription = it
} }
this.propertySymbol = propertySymbol this.propertySymbol = propertySymbol
additionalPropertyAccessorInit()
}.also { }.also {
it.initContainingClassAttr() it.initContainingClassAttr()
bindFunctionTarget(accessorTarget, it) bindFunctionTarget(accessorTarget, it)
@@ -558,6 +564,8 @@ open class RawFirBuilder(
this.initializer = backingFieldInitializer this.initializer = backingFieldInitializer
this.isVar = property.isVar this.isVar = property.isVar
this.isVal = !property.isVar this.isVal = !property.isVar
additionalBackingFieldInit()
} }
} else { } else {
FirDefaultPropertyBackingField( FirDefaultPropertyBackingField(
@@ -1497,6 +1505,7 @@ open class RawFirBuilder(
} }
} }
context.firFunctionTargets.removeLast() context.firFunctionTargets.removeLast()
additionalFunctionInit()
}.build().also { }.build().also {
bindFunctionTarget(target, it) bindFunctionTarget(target, it)
if (it is FirSimpleFunction) { if (it is FirSimpleFunction) {
@@ -1847,6 +1856,7 @@ open class RawFirBuilder(
} }
contextReceivers.addAll(convertContextReceivers(this@toFirProperty.contextReceivers)) contextReceivers.addAll(convertContextReceivers(this@toFirProperty.contextReceivers))
additionalPropertyInit()
}.also { }.also {
if (!isLocal) { if (!isLocal) {
fillDanglingConstraintsTo(it) fillDanglingConstraintsTo(it)