[LL FIR] rewrite on-air resolve
Now we will resolve declarations only ones and to the minimal required phase to get a fully resolved element depends on an insert position, because not all elements require body resolution A side change: `getOnAirGetTowerContextProvider` now won't do rebind to the original declaration. In the future, this part will be rewritten to avoid on-air resolution, so it is not a problem ^KT-59685 Fixed
This commit is contained in:
committed by
Space Team
parent
61acd2b6f5
commit
6867dffff1
-118
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.analysis.low.level.api.fir
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
|
||||
internal object DeclarationCopyBuilder {
|
||||
fun FirSimpleFunction.withBodyFrom(
|
||||
functionWithBody: FirSimpleFunction,
|
||||
): FirSimpleFunction = buildSimpleFunctionCopy(this) {
|
||||
body = functionWithBody.body
|
||||
symbol = functionWithBody.symbol
|
||||
initDeclaration(this@withBodyFrom, functionWithBody)
|
||||
}.apply { reassignAllReturnTargets(functionWithBody) }
|
||||
|
||||
fun FirRegularClass.withBodyFrom(
|
||||
classWithBody: FirRegularClass,
|
||||
): FirRegularClass = buildRegularClassCopy(this) {
|
||||
declarations.clear()
|
||||
declarations.addAll(classWithBody.declarations)
|
||||
symbol = classWithBody.symbol
|
||||
initDeclaration(this@withBodyFrom, classWithBody)
|
||||
}
|
||||
|
||||
fun FirScript.withBodyFrom(
|
||||
scriptWithBody: FirScript
|
||||
): FirScript = buildScriptCopy(this) {
|
||||
statements.clear()
|
||||
statements.addAll(scriptWithBody.statements)
|
||||
symbol = scriptWithBody.symbol
|
||||
initDeclaration(this@withBodyFrom, scriptWithBody)
|
||||
}
|
||||
|
||||
fun FirProperty.withBodyFrom(propertyWithBody: FirProperty): FirProperty {
|
||||
val newSetter = getAccessorToUse(this, propertyWithBody) { it.setter }
|
||||
val newGetter = getAccessorToUse(this, propertyWithBody) { it.getter }
|
||||
|
||||
val propertyResolvePhase = minOf(
|
||||
this@withBodyFrom.resolvePhase,
|
||||
FirResolvePhase.DECLARATIONS,
|
||||
newGetter?.resolvePhase ?: FirResolvePhase.BODY_RESOLVE,
|
||||
newSetter?.resolvePhase ?: FirResolvePhase.BODY_RESOLVE,
|
||||
propertyWithBody.getter?.resolvePhase ?: FirResolvePhase.BODY_RESOLVE,
|
||||
propertyWithBody.setter?.resolvePhase ?: FirResolvePhase.BODY_RESOLVE,
|
||||
)
|
||||
|
||||
return buildPropertyCopy(this@withBodyFrom) {
|
||||
symbol = propertyWithBody.symbol
|
||||
initializer = propertyWithBody.initializer
|
||||
|
||||
getter = newGetter
|
||||
setter = newSetter
|
||||
|
||||
if (propertyResolvePhase < FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) {
|
||||
bodyResolveState = FirPropertyBodyResolveState.NOTHING_RESOLVED
|
||||
}
|
||||
|
||||
initDeclaration(this@withBodyFrom, propertyWithBody)
|
||||
resolvePhase = propertyResolvePhase
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun getAccessorToUse(
|
||||
originalProperty: FirProperty,
|
||||
replacementProperty: FirProperty,
|
||||
getAccessor: (FirProperty) -> FirPropertyAccessor?
|
||||
): FirPropertyAccessor? {
|
||||
val originalAccessor = getAccessor(originalProperty)
|
||||
val replacementAccessor = getAccessor(replacementProperty)
|
||||
|
||||
// accessor has a header type, and we want it type to be resolved
|
||||
return if (originalAccessor != null && replacementAccessor != null) {
|
||||
buildPropertyAccessorCopy(originalAccessor) {
|
||||
body = replacementAccessor.body
|
||||
symbol = replacementAccessor.symbol
|
||||
initDeclaration(originalAccessor, replacementAccessor)
|
||||
}.apply { reassignAllReturnTargets(replacementAccessor) }
|
||||
} else {
|
||||
replacementAccessor
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirDeclarationBuilder.initDeclaration(
|
||||
originalDeclaration: FirDeclaration,
|
||||
builtDeclaration: FirDeclaration,
|
||||
) {
|
||||
resolvePhase = minOf(originalDeclaration.resolvePhase, FirResolvePhase.DECLARATIONS)
|
||||
source = builtDeclaration.source
|
||||
moduleData = originalDeclaration.moduleData
|
||||
}
|
||||
|
||||
private fun FirScriptBuilder.initDeclaration(
|
||||
originalDeclaration: FirDeclaration,
|
||||
builtDeclaration: FirDeclaration,
|
||||
) {
|
||||
resolvePhase = minOf(originalDeclaration.resolvePhase, FirResolvePhase.DECLARATIONS)
|
||||
source = builtDeclaration.source
|
||||
moduleData = originalDeclaration.moduleData
|
||||
}
|
||||
|
||||
private fun FirFunction.reassignAllReturnTargets(from: FirFunction) {
|
||||
this.accept(object : FirVisitorVoid() {
|
||||
override fun visitElement(element: FirElement) {
|
||||
if (element is FirReturnExpression && element.target.labeledElement == from) {
|
||||
element.target.bind(this@reassignAllReturnTargets)
|
||||
}
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+133
-83
@@ -7,12 +7,11 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.api
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.DeclarationCopyBuilder.withBodyFrom
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirResolveSessionDepended
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirWholeFileResolveTarget
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FileTowerProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerContextProvider
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.FirTowerDataContextAllElementsCollector
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.canBePartOfParentDeclaration
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.FirElementsRecorder
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.KtToFirMapping
|
||||
@@ -23,11 +22,11 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirResolvableM
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirResolvableSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.state.LLFirResolvableResolveSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirElementFinder
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.withPsiEntry
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.parentsOfType
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
@@ -41,27 +40,19 @@ import org.jetbrains.kotlin.fir.scopes.createImportingScopes
|
||||
import org.jetbrains.kotlin.fir.scopes.kotlinScopeProvider
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
|
||||
object LowLevelFirApiFacadeForResolveOnAir {
|
||||
private fun PsiElement.onAirGetNonLocalContainingOrThisDeclarationFor(): KtDeclaration? {
|
||||
private fun KtDeclaration.isApplicableForOnAirResolve(): Boolean = when (this) {
|
||||
is KtDestructuringDeclaration -> false
|
||||
else -> true
|
||||
}
|
||||
|
||||
private fun PsiElement.onAirGetNonLocalContainingOrThisDeclaration(): KtDeclaration? {
|
||||
return getNonLocalContainingOrThisDeclaration { declaration ->
|
||||
when (declaration) {
|
||||
is KtNamedFunction,
|
||||
is KtProperty,
|
||||
is KtTypeAlias,
|
||||
is KtScript -> {
|
||||
true
|
||||
}
|
||||
|
||||
is KtClassOrObject -> {
|
||||
declaration !is KtEnumEntry
|
||||
}
|
||||
|
||||
else -> {
|
||||
false
|
||||
}
|
||||
}
|
||||
declaration.isApplicableForOnAirResolve() && !declaration.canBePartOfParentDeclaration
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,8 +74,9 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
||||
|
||||
val declaration = runBodyResolveOnAir(
|
||||
firResolveSession = firResolveSession,
|
||||
replacement = RawFirReplacement(place, elementToResolve),
|
||||
onAirCreatedDeclaration = true
|
||||
originalPlace = place,
|
||||
replacementElement = elementToResolve,
|
||||
collector = null,
|
||||
)
|
||||
|
||||
val expressionLocator = object : FirVisitorVoid() {
|
||||
@@ -114,9 +106,12 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
||||
val moduleComponents = session.moduleComponents
|
||||
|
||||
val onAirFirFile = RawFirNonLocalDeclarationBuilder.buildNewFile(session, session.kotlinScopeProvider, ktFile)
|
||||
val target = LLFirWholeFileResolveTarget(onAirFirFile)
|
||||
val collector = FirTowerDataContextAllElementsCollector()
|
||||
moduleComponents.firModuleLazyDeclarationResolver.lazyResolveTarget(target, FirResolvePhase.BODY_RESOLVE, collector)
|
||||
moduleComponents.firModuleLazyDeclarationResolver.runLazyDesignatedOnAirResolve(
|
||||
FirDesignationWithFile(emptyList(), onAirFirFile, onAirFirFile),
|
||||
collector,
|
||||
)
|
||||
|
||||
return collector
|
||||
}
|
||||
|
||||
@@ -137,8 +132,8 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
||||
runBodyResolveOnAir(
|
||||
firResolveSession = firResolveSession,
|
||||
collector = it,
|
||||
onAirCreatedDeclaration = false,
|
||||
replacement = RawFirReplacement(validPlace, validPlace),
|
||||
originalPlace = validPlace,
|
||||
replacementElement = validPlace,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -164,39 +159,48 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
||||
return FirTowerDataContext().addNonLocalTowerDataElements(fileScopeElements)
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of the original fir declaration and resolves it to the minimum required phase
|
||||
* depends on [elementToAnalyze] position inside a non-local containing declaration.
|
||||
*
|
||||
* If [elementToAnalyze] is non-local declaration then resolves it to [FirResolvePhase.BODY_RESOLVE].
|
||||
*
|
||||
* Resulted [LLFirResolveSession] have [FirTowerDataContext] for elements from the copy.
|
||||
*/
|
||||
fun getFirResolveSessionForDependentCopy(
|
||||
originalFirResolveSession: LLFirResolveSession,
|
||||
originalKtFile: KtFile,
|
||||
elementToAnalyze: KtElement
|
||||
elementToAnalyze: KtElement,
|
||||
): LLFirResolveSession {
|
||||
require(originalFirResolveSession is LLFirResolvableResolveSession)
|
||||
require(elementToAnalyze !is KtFile) { "KtFile for dependency element not supported" }
|
||||
|
||||
val dependencyNonLocalDeclaration = elementToAnalyze.onAirGetNonLocalContainingOrThisDeclarationFor() as? KtNamedDeclaration
|
||||
val minimalCopiedDeclaration = elementToAnalyze.getNonLocalContainingOrThisDeclaration {
|
||||
it.isApplicableForOnAirResolve()
|
||||
}
|
||||
|
||||
if (dependencyNonLocalDeclaration == null) {
|
||||
val copiedNonLocalDeclaration = minimalCopiedDeclaration?.onAirGetNonLocalContainingOrThisDeclaration()
|
||||
if (copiedNonLocalDeclaration == null) {
|
||||
val towerDataContext = onAirGetTowerContextForFile(originalFirResolveSession, originalKtFile)
|
||||
val fileTowerProvider = FileTowerProvider(elementToAnalyze.containingKtFile, towerDataContext)
|
||||
return LLFirResolveSessionDepended(originalFirResolveSession, fileTowerProvider, ktToFirMapping = null)
|
||||
}
|
||||
|
||||
val sameDeclarationInOriginalFile = PsiTreeUtil.findSameElementInCopy(dependencyNonLocalDeclaration, originalKtFile)
|
||||
val originalNonLocalDeclaration = PsiTreeUtil.findSameElementInCopy(copiedNonLocalDeclaration, originalKtFile)
|
||||
?: buildErrorWithAttachment("Cannot find original function matching") {
|
||||
withPsiEntry("matchingPsi", dependencyNonLocalDeclaration, originalFirResolveSession::getModule)
|
||||
withPsiEntry("matchingPsi", elementToAnalyze, originalFirResolveSession::getModule)
|
||||
withPsiEntry("originalFile", originalKtFile, originalFirResolveSession::getModule)
|
||||
}
|
||||
|
||||
recordOriginalDeclaration(
|
||||
targetDeclaration = dependencyNonLocalDeclaration,
|
||||
originalDeclaration = sameDeclarationInOriginalFile
|
||||
)
|
||||
recordOriginalDeclaration(targetDeclaration = copiedNonLocalDeclaration, originalDeclaration = originalNonLocalDeclaration)
|
||||
|
||||
val collector = FirTowerDataContextAllElementsCollector()
|
||||
val copiedFirDeclaration = runBodyResolveOnAir(
|
||||
originalFirResolveSession,
|
||||
replacement = RawFirReplacement(sameDeclarationInOriginalFile, dependencyNonLocalDeclaration),
|
||||
onAirCreatedDeclaration = true,
|
||||
originalPlace = originalNonLocalDeclaration,
|
||||
replacementElement = copiedNonLocalDeclaration,
|
||||
collector = collector,
|
||||
forcedResolvePhase = requiredResolvePhase(minimalCopiedDeclaration, elementToAnalyze),
|
||||
)
|
||||
|
||||
val mapping = KtToFirMapping(copiedFirDeclaration, FirElementsRecorder())
|
||||
@@ -229,10 +233,9 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
||||
}
|
||||
|
||||
val declarationResolver = llFirResolvableSession.moduleComponents.firModuleLazyDeclarationResolver
|
||||
declarationResolver.runLazyDesignatedOnAirResolveToBodyWithoutLock(
|
||||
declarationResolver.runLazyDesignatedOnAirResolve(
|
||||
FirDesignationWithFile(path = emptyList(), target = fileAnnotationsContainer, firFile),
|
||||
onAirCreatedDeclaration = true,
|
||||
collector
|
||||
collector,
|
||||
)
|
||||
|
||||
collector?.addFileContext(firFile, firFile.createTowerDataContext(firResolveSession.getScopeSessionFor(llFirResolvableSession)))
|
||||
@@ -241,70 +244,117 @@ object LowLevelFirApiFacadeForResolveOnAir {
|
||||
return fileAnnotationsContainer.annotations.single()
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new fir declaration from closer non-local declaration based on [originalPlace] position.
|
||||
* The resulted [FirResolvePhase] depends on [forcedResolvePhase] or the position of [originalPlace] inside the non-local declaration.
|
||||
*
|
||||
* Note: the new declaration and its content won't be rebinded to the original.
|
||||
*
|
||||
* @see requiredResolvePhase
|
||||
*/
|
||||
private fun runBodyResolveOnAir(
|
||||
firResolveSession: LLFirResolvableResolveSession,
|
||||
replacement: RawFirReplacement,
|
||||
onAirCreatedDeclaration: Boolean,
|
||||
collector: FirResolveContextCollector? = null,
|
||||
originalPlace: KtElement,
|
||||
replacementElement: KtElement,
|
||||
collector: FirResolveContextCollector?,
|
||||
forcedResolvePhase: FirResolvePhase? = null,
|
||||
): FirElement {
|
||||
val nonLocalDeclaration = replacement.from.onAirGetNonLocalContainingOrThisDeclarationFor()
|
||||
val originalFirFile = firResolveSession.getOrBuildFirFile(replacement.from.containingKtFile)
|
||||
val minimalOriginalDeclarationToReplace = originalPlace.getNonLocalContainingOrThisDeclaration {
|
||||
it.isApplicableForOnAirResolve()
|
||||
}
|
||||
|
||||
if (nonLocalDeclaration == null) {
|
||||
val originalFirFile = firResolveSession.getOrBuildFirFile(originalPlace.containingKtFile)
|
||||
|
||||
val originalDeclaration = minimalOriginalDeclarationToReplace?.onAirGetNonLocalContainingOrThisDeclaration()
|
||||
if (originalDeclaration == null) {
|
||||
//It is possible that it is file annotation is going to resolve
|
||||
val annotationCall = replacement.from.parentOfType<KtAnnotationEntry>(withSelf = true)
|
||||
val annotationCall = originalPlace.parentOfType<KtAnnotationEntry>(withSelf = true)
|
||||
if (annotationCall != null) {
|
||||
return tryResolveAsFileAnnotation(
|
||||
annotationEntry = annotationCall,
|
||||
replacement = replacement,
|
||||
replacement = RawFirReplacement(from = originalPlace, to = replacementElement),
|
||||
firFile = originalFirFile,
|
||||
collector = collector,
|
||||
firResolveSession = firResolveSession,
|
||||
)
|
||||
} else {
|
||||
error("Cannot find enclosing declaration for ${replacement.from.getElementTextInContext()}")
|
||||
errorWithFirSpecificEntries(
|
||||
"Cannot find enclosing declaration for ${originalPlace::class.simpleName}",
|
||||
psi = originalPlace,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val originalDeclaration = nonLocalDeclaration.getOrBuildFirOfType<FirDeclaration>(firResolveSession)
|
||||
val originalDesignation = originalDeclaration.collectDesignation()
|
||||
val newDeclarationWithReplacement = RawFirNonLocalDeclarationBuilder.buildWithReplacement(
|
||||
session = originalDeclaration.moduleData.session,
|
||||
scopeProvider = originalDeclaration.moduleData.session.kotlinScopeProvider,
|
||||
designation = originalDesignation,
|
||||
rootNonLocalDeclaration = nonLocalDeclaration,
|
||||
val originalDesignationPath = FirElementFinder.collectDesignationPath(originalFirFile, originalDeclaration)
|
||||
?: errorWithFirSpecificEntries(message = "Impossible to collect designation", fir = originalFirFile, psi = originalDeclaration)
|
||||
|
||||
val originalFirDeclaration = originalDesignationPath.target
|
||||
val session = originalFirDeclaration.llFirResolvableSession ?: error("Expected resolvable session")
|
||||
|
||||
/**
|
||||
* Special case for [getOnAirGetTowerContextProvider]. Can be dropped after KT-59498
|
||||
*/
|
||||
val replacement = if (originalPlace === replacementElement) {
|
||||
RawFirReplacement(from = originalDeclaration, to = originalDeclaration)
|
||||
} else {
|
||||
RawFirReplacement(from = originalPlace, to = replacementElement)
|
||||
}
|
||||
|
||||
val newFirDeclaration = RawFirNonLocalDeclarationBuilder.buildWithReplacement(
|
||||
session = session,
|
||||
scopeProvider = session.kotlinScopeProvider,
|
||||
designation = FirDesignation(originalDesignationPath.path, originalFirDeclaration),
|
||||
rootNonLocalDeclaration = originalDeclaration,
|
||||
replacement = replacement,
|
||||
)
|
||||
|
||||
val isInBodyReplacement = isInBodyReplacement(nonLocalDeclaration, replacement)
|
||||
val copiedFirDeclaration = if (isInBodyReplacement) {
|
||||
when (originalDeclaration) {
|
||||
is FirSimpleFunction -> originalDeclaration.withBodyFrom(newDeclarationWithReplacement as FirSimpleFunction)
|
||||
is FirProperty -> originalDeclaration.withBodyFrom(newDeclarationWithReplacement as FirProperty)
|
||||
is FirRegularClass -> originalDeclaration.withBodyFrom(newDeclarationWithReplacement as FirRegularClass)
|
||||
is FirScript -> originalDeclaration.withBodyFrom(newDeclarationWithReplacement as FirScript)
|
||||
is FirTypeAlias -> newDeclarationWithReplacement
|
||||
else -> error("Not supported type ${originalDeclaration::class.simpleName}")
|
||||
}
|
||||
} else {
|
||||
newDeclarationWithReplacement
|
||||
session.moduleComponents.firModuleLazyDeclarationResolver.runLazyDesignatedOnAirResolve(
|
||||
FirDesignationWithFile(originalDesignationPath.path, newFirDeclaration, originalFirFile),
|
||||
collector,
|
||||
forcedResolvePhase ?: requiredResolvePhase(minimalOriginalDeclarationToReplace, originalPlace),
|
||||
)
|
||||
|
||||
return newFirDeclaration
|
||||
}
|
||||
|
||||
private fun requiredResolvePhase(
|
||||
container: KtDeclaration,
|
||||
elementToReplace: PsiElement,
|
||||
): FirResolvePhase = when {
|
||||
bodyResolveRequired(container, elementToReplace) -> FirResolvePhase.BODY_RESOLVE
|
||||
annotationMappingRequired(container, elementToReplace) -> FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING
|
||||
|
||||
/**
|
||||
* Currently it is a minimal phase there we can collect [FirResolveContextCollector]
|
||||
*/
|
||||
else -> FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS
|
||||
}
|
||||
|
||||
private fun annotationMappingRequired(
|
||||
container: KtDeclaration,
|
||||
elementToReplace: PsiElement,
|
||||
): Boolean = elementToReplace.parentsWithSelf.takeWhile { it != container }.any {
|
||||
it is KtAnnotationEntry
|
||||
} || elementToReplace.anyDescendantOfType<KtAnnotationEntry>(
|
||||
canGoInside = {
|
||||
// We shouldn't go inside a class body, because class resolution won't process such elements
|
||||
// In case of container is class, we are interested only in elements outside its body
|
||||
it !is KtClassBody
|
||||
},
|
||||
)
|
||||
|
||||
private fun bodyResolveRequired(container: KtDeclaration, elementToReplace: PsiElement): Boolean = when {
|
||||
container == elementToReplace -> true
|
||||
container is KtDeclarationWithBody -> container.bodyExpression?.isAncestor(elementToReplace)
|
||||
container is KtProperty -> container.delegateExpressionOrInitializer?.isAncestor(elementToReplace)
|
||||
container is KtParameter -> container.defaultValue?.isAncestor(elementToReplace)
|
||||
container is KtEnumEntry -> {
|
||||
container.initializerList?.isAncestor(elementToReplace) == true || container.body?.isAncestor(elementToReplace) == true
|
||||
}
|
||||
|
||||
val onAirDesignation = FirDesignationWithFile(
|
||||
path = originalDesignation.path,
|
||||
target = copiedFirDeclaration,
|
||||
firFile = originalFirFile
|
||||
)
|
||||
|
||||
val resolvableSession = onAirDesignation.target.llFirResolvableSession ?: error("Expected resolvable session")
|
||||
resolvableSession.moduleComponents.firModuleLazyDeclarationResolver.runLazyDesignatedOnAirResolveToBodyWithoutLock(
|
||||
designation = onAirDesignation,
|
||||
onAirCreatedDeclaration = onAirCreatedDeclaration,
|
||||
towerDataContextCollector = collector,
|
||||
)
|
||||
|
||||
return copiedFirDeclaration
|
||||
}
|
||||
container is KtScript || container is KtAnonymousInitializer -> true
|
||||
else -> false
|
||||
} == true
|
||||
|
||||
private fun isInBodyReplacement(ktDeclaration: KtDeclaration, replacement: RawFirReplacement): Boolean {
|
||||
fun check(container: KtElement?): Boolean {
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.analysis.low.level.api.fir.api.targets
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolveState
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
|
||||
/**
|
||||
* [LLFirResolveTarget] representing all declarations in a class (including nested classes).
|
||||
* All of them are going to be resolved.
|
||||
*/
|
||||
class LLFirWholeClassResolveTarget(
|
||||
override val firFile: FirFile,
|
||||
override val path: List<FirRegularClass>,
|
||||
val target: FirRegularClass,
|
||||
) : LLFirResolveTarget() {
|
||||
override fun forEachTarget(action: (FirElementWithResolveState) -> Unit) {
|
||||
action(target)
|
||||
|
||||
fun goInside(target: FirElementWithResolveState) {
|
||||
action(target)
|
||||
if (target is FirRegularClass) {
|
||||
target.declarations.forEach(::goInside)
|
||||
}
|
||||
}
|
||||
|
||||
forEachDeclaration(::goInside)
|
||||
}
|
||||
|
||||
inline fun forEachDeclaration(action: (FirElementWithResolveState) -> Unit) {
|
||||
for (member in target.declarations) {
|
||||
action(member)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toStringForTarget(): String = "*"
|
||||
}
|
||||
+25
-17
@@ -7,9 +7,10 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve
|
||||
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFile
|
||||
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.LLFirSingleResolveTarget
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirWholeClassResolveTarget
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirWholeFileResolveTarget
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.InvalidSessionException
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
|
||||
@@ -106,6 +107,9 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
||||
towerDataContextCollector: FirResolveContextCollector?,
|
||||
) {
|
||||
try {
|
||||
resolveFileToImportsWithLock(target.firFile)
|
||||
if (toPhase == FirResolvePhase.IMPORTS) return
|
||||
|
||||
lazyResolveTargets(
|
||||
targets = listOf(target),
|
||||
moduleComponents.scopeSessionProvider.getScopeSession(),
|
||||
@@ -117,31 +121,35 @@ internal class LLFirModuleLazyDeclarationResolver(val moduleComponents: LLFirMod
|
||||
}
|
||||
}
|
||||
|
||||
fun runLazyDesignatedOnAirResolveToBodyWithoutLock(
|
||||
/**
|
||||
* Resolve on-air created declaration in a context of real [FirDesignationWithFile.firFile] and [FirDesignationWithFile.path].
|
||||
* If target declaration is [FirFile] then the entire file will be resolved.
|
||||
* The same for [FirRegularClass] if [resolvePhase] is [FirResolvePhase.BODY_RESOLVE].
|
||||
*/
|
||||
fun runLazyDesignatedOnAirResolve(
|
||||
designation: FirDesignationWithFile,
|
||||
onAirCreatedDeclaration: Boolean,
|
||||
towerDataContextCollector: FirResolveContextCollector?,
|
||||
resolvePhase: FirResolvePhase = FirResolvePhase.BODY_RESOLVE,
|
||||
) {
|
||||
resolveFileToImportsWithLock(designation.firFile)
|
||||
|
||||
val target = when (designation.target) {
|
||||
is FirRegularClass -> LLFirClassWithAllMembersResolveTarget(designation.firFile, designation.path, designation.target)
|
||||
val target = when {
|
||||
designation.target is FirFile -> LLFirWholeFileResolveTarget(designation.firFile)
|
||||
resolvePhase == FirResolvePhase.BODY_RESOLVE && designation.target is FirRegularClass -> {
|
||||
LLFirWholeClassResolveTarget(designation.firFile, designation.path, designation.target)
|
||||
}
|
||||
|
||||
else -> LLFirSingleResolveTarget(designation.firFile, designation.path, designation.target)
|
||||
}
|
||||
|
||||
fun runTransformation() {
|
||||
val scopeSession = ScopeSession()
|
||||
lazyResolveTargets(listOf(target), scopeSession, FirResolvePhase.BODY_RESOLVE, towerDataContextCollector)
|
||||
}
|
||||
|
||||
try {
|
||||
if (onAirCreatedDeclaration) {
|
||||
withOnAirDesignation(designation, ::runTransformation)
|
||||
} else {
|
||||
runTransformation()
|
||||
withOnAirDesignation(designation) {
|
||||
// New session to avoid garbage in the original session
|
||||
val scopeSession = ScopeSession()
|
||||
lazyResolveTargets(listOf(target), scopeSession, resolvePhase, towerDataContextCollector)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
handleExceptionFromResolve(e, target, FirResolvePhase.BODY_RESOLVE)
|
||||
handleExceptionFromResolve(e, target, resolvePhase)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +208,7 @@ private fun handleExceptionFromResolve(
|
||||
exception: Exception,
|
||||
firDeclarationToResolve: FirElementWithResolveState,
|
||||
fromPhase: FirResolvePhase,
|
||||
toPhase: FirResolvePhase
|
||||
toPhase: FirResolvePhase,
|
||||
): Nothing {
|
||||
if (exception is InvalidSessionException) {
|
||||
throw exception
|
||||
@@ -235,7 +243,7 @@ private fun handleExceptionFromResolve(
|
||||
private fun handleExceptionFromResolve(
|
||||
exception: Exception,
|
||||
designation: LLFirResolveTarget,
|
||||
toPhase: FirResolvePhase
|
||||
toPhase: FirResolvePhase,
|
||||
): Nothing {
|
||||
if (exception is InvalidSessionException) {
|
||||
throw exception
|
||||
|
||||
+37
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.llFirModuleData
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.withPsiEntry
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.builder.BodyBuildingMode
|
||||
@@ -23,6 +24,7 @@ import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
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.name.NameUtils
|
||||
@@ -111,6 +113,12 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
|
||||
}
|
||||
|
||||
private inner class VisitorWithReplacement(private val containingClass: FirRegularClass?) : Visitor() {
|
||||
fun convertDestructuringDeclaration(element: KtDestructuringDeclaration): FirVariable {
|
||||
val replacementDeclaration = replacementApplier?.tryReplace(element) ?: element
|
||||
requireIsInstance<KtDestructuringDeclaration>(replacementDeclaration)
|
||||
return buildErrorTopLevelDestructuringDeclaration(replacementDeclaration.toFirSourceElement())
|
||||
}
|
||||
|
||||
override fun convertElement(element: KtElement, original: FirElement?): FirElement? =
|
||||
super.convertElement(replacementApplier?.tryReplace(element) ?: element, original)
|
||||
|
||||
@@ -128,6 +136,34 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
|
||||
)
|
||||
}
|
||||
|
||||
override fun convertPropertyAccessor(
|
||||
accessor: KtPropertyAccessor?,
|
||||
property: KtProperty,
|
||||
propertyTypeRef: FirTypeRef,
|
||||
propertySymbol: FirPropertySymbol,
|
||||
isGetter: Boolean,
|
||||
accessorAnnotationsFromProperty: List<FirAnnotation>,
|
||||
parameterAnnotationsFromProperty: List<FirAnnotation>,
|
||||
): FirPropertyAccessor? {
|
||||
val replacementAccessor = if (accessor != null) {
|
||||
val replacementAccessor = replacementApplier?.tryReplace(accessor) ?: accessor
|
||||
check(replacementAccessor is KtPropertyAccessor)
|
||||
replacementAccessor
|
||||
} else {
|
||||
accessor
|
||||
}
|
||||
|
||||
return super.convertPropertyAccessor(
|
||||
replacementAccessor,
|
||||
property,
|
||||
propertyTypeRef,
|
||||
propertySymbol,
|
||||
isGetter,
|
||||
accessorAnnotationsFromProperty,
|
||||
parameterAnnotationsFromProperty
|
||||
)
|
||||
}
|
||||
|
||||
override fun convertValueParameter(
|
||||
valueParameter: KtParameter,
|
||||
functionSymbol: FirFunctionSymbol<*>,
|
||||
@@ -273,6 +309,7 @@ internal class RawFirNonLocalDeclarationBuilder private constructor(
|
||||
else -> visitor.convertElement(declarationToBuild, originalDeclaration)
|
||||
}
|
||||
}
|
||||
is KtDestructuringDeclaration -> visitor.convertDestructuringDeclaration(declarationToBuild)
|
||||
else -> visitor.convertElement(declarationToBuild, originalDeclaration)
|
||||
} as FirDeclaration
|
||||
}
|
||||
|
||||
+4
-3
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
internal data class RawFirReplacement(val from: KtElement, val to: KtElement) {
|
||||
companion object {
|
||||
fun isApplicableForReplacement(element: KtElement) = when (element) {
|
||||
is KtFile, is KtScript, is KtClassInitializer, is KtClassOrObject, is KtObjectLiteralExpression, is KtTypeAlias,
|
||||
is KtFile, is KtScript, is KtClassInitializer, is KtPropertyAccessor, is KtConstructor<*>, is KtClassOrObject, is KtObjectLiteralExpression, is KtTypeAlias,
|
||||
is KtNamedFunction, is KtLambdaExpression, is KtAnonymousInitializer, is KtProperty, is KtTypeReference,
|
||||
is KtAnnotationEntry, is KtTypeParameter, is KtTypeProjection, is KtParameter, is KtBlockExpression,
|
||||
is KtSimpleNameExpression, is KtConstantExpression, is KtStringTemplateExpression, is KtReturnExpression,
|
||||
@@ -19,7 +19,8 @@ internal data class RawFirReplacement(val from: KtElement, val to: KtElement) {
|
||||
is KtIsExpression, is KtUnaryExpression, is KtCallExpression, is KtArrayAccessExpression, is KtQualifiedExpression,
|
||||
is KtThisExpression, is KtSuperExpression, is KtParenthesizedExpression, is KtLabeledExpression, is KtAnnotatedExpression,
|
||||
is KtThrowExpression, is KtDestructuringDeclaration, is KtClassLiteralExpression, is KtCallableReferenceExpression,
|
||||
is KtCollectionLiteralExpression -> true
|
||||
is KtCollectionLiteralExpression,
|
||||
-> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
+10
-2
@@ -29,12 +29,12 @@ internal abstract class LLFirAbstractBodyTargetResolver(
|
||||
isJumpingPhase: Boolean = false
|
||||
) : LLFirTargetResolver(resolveTarget, lockProvider, resolvePhase, isJumpingPhase) {
|
||||
protected fun createReturnTypeCalculator(
|
||||
towerDataContextCollector: FirResolveContextCollector?,
|
||||
firResolveContextCollector: FirResolveContextCollector?,
|
||||
): ReturnTypeCalculator = LLFirReturnTypeCalculatorWithJump(
|
||||
scopeSession,
|
||||
implicitBodyResolveComputationSession,
|
||||
lockProvider,
|
||||
towerDataContextCollector,
|
||||
firResolveContextCollector,
|
||||
)
|
||||
|
||||
abstract val transformer: FirAbstractBodyResolveTransformerDispatcher
|
||||
@@ -47,6 +47,10 @@ internal abstract class LLFirAbstractBodyTargetResolver(
|
||||
|
||||
override fun withFile(firFile: FirFile, action: () -> Unit) {
|
||||
transformer.context.withFile(firFile, transformer.components) {
|
||||
transformer.firResolveContextCollector?.let { collector ->
|
||||
collector.addFileContext(firFile, transformer.context.towerDataContext)
|
||||
}
|
||||
|
||||
action()
|
||||
}
|
||||
}
|
||||
@@ -55,6 +59,10 @@ internal abstract class LLFirAbstractBodyTargetResolver(
|
||||
override fun withRegularClassImpl(firClass: FirRegularClass, action: () -> Unit) {
|
||||
transformer.declarationsTransformer.context.withContainingClass(firClass) {
|
||||
transformer.declarationsTransformer.withRegularClass(firClass) {
|
||||
transformer.firResolveContextCollector?.let { collector ->
|
||||
collector.addDeclarationContext(firClass, transformer.context)
|
||||
}
|
||||
|
||||
action()
|
||||
firClass
|
||||
}
|
||||
|
||||
+4
-2
@@ -32,7 +32,7 @@ internal object LLFirAnnotationArgumentMappingLazyResolver : LLFirLazyResolver(F
|
||||
scopeSession: ScopeSession,
|
||||
towerDataContextCollector: FirResolveContextCollector?,
|
||||
) {
|
||||
val resolver = LLFirAnnotationArgumentsMappingTargetResolver(target, lockProvider, session, scopeSession)
|
||||
val resolver = LLFirAnnotationArgumentsMappingTargetResolver(target, lockProvider, session, scopeSession, towerDataContextCollector)
|
||||
resolver.resolveDesignation()
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ private class LLFirAnnotationArgumentsMappingTargetResolver(
|
||||
lockProvider: LLFirLockProvider,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
firResolveContextCollector: FirResolveContextCollector?,
|
||||
) : LLFirAbstractBodyTargetResolver(
|
||||
resolveTarget,
|
||||
lockProvider,
|
||||
@@ -67,7 +68,8 @@ private class LLFirAnnotationArgumentsMappingTargetResolver(
|
||||
session,
|
||||
scopeSession,
|
||||
resolverPhase,
|
||||
returnTypeCalculator = createReturnTypeCalculator(towerDataContextCollector = null)
|
||||
returnTypeCalculator = createReturnTypeCalculator(firResolveContextCollector = firResolveContextCollector),
|
||||
firResolveContextCollector = firResolveContextCollector,
|
||||
)
|
||||
|
||||
override fun doLazyResolveUnderLock(target: FirElementWithResolveState) {
|
||||
|
||||
+47
-2
@@ -17,9 +17,11 @@ import org.jetbrains.kotlin.fir.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolveState
|
||||
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.PrivateForInline
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirAnnotationArgumentsResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
@@ -33,7 +35,7 @@ internal object LLFirAnnotationArgumentsLazyResolver : LLFirLazyResolver(FirReso
|
||||
scopeSession: ScopeSession,
|
||||
towerDataContextCollector: FirResolveContextCollector?,
|
||||
) {
|
||||
val resolver = LLFirAnnotationArgumentsTargetResolver(target, lockProvider, session, scopeSession)
|
||||
val resolver = LLFirAnnotationArgumentsTargetResolver(target, lockProvider, session, scopeSession, towerDataContextCollector)
|
||||
resolver.resolveDesignation()
|
||||
}
|
||||
|
||||
@@ -68,6 +70,7 @@ private class LLFirAnnotationArgumentsTargetResolver(
|
||||
lockProvider: LLFirLockProvider,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
firResolveContextCollector: FirResolveContextCollector?,
|
||||
) : LLFirAbstractBodyTargetResolver(
|
||||
target,
|
||||
lockProvider,
|
||||
@@ -78,13 +81,55 @@ private class LLFirAnnotationArgumentsTargetResolver(
|
||||
session,
|
||||
scopeSession,
|
||||
resolverPhase,
|
||||
returnTypeCalculator = createReturnTypeCalculator(towerDataContextCollector = null)
|
||||
returnTypeCalculator = createReturnTypeCalculator(firResolveContextCollector = firResolveContextCollector),
|
||||
firResolveContextCollector = firResolveContextCollector,
|
||||
)
|
||||
|
||||
override fun doLazyResolveUnderLock(target: FirElementWithResolveState) {
|
||||
collectTowerDataContext(target)
|
||||
|
||||
FirLazyBodiesCalculator.calculateAnnotations(target)
|
||||
transformAnnotations(target)
|
||||
}
|
||||
|
||||
private fun collectTowerDataContext(target: FirElementWithResolveState) {
|
||||
val contextCollector = transformer.firResolveContextCollector
|
||||
if (contextCollector == null || target !is FirDeclaration) return
|
||||
|
||||
val bodyResolveContext = transformer.context
|
||||
withTypeParametersIfMemberDeclaration(bodyResolveContext, target) {
|
||||
when (target) {
|
||||
is FirRegularClass -> {
|
||||
contextCollector.addClassHeaderContext(target, bodyResolveContext.towerDataContext)
|
||||
}
|
||||
|
||||
is FirFunction -> bodyResolveContext.forFunctionBody(target, transformer.components) {
|
||||
contextCollector.addDeclarationContext(target, bodyResolveContext)
|
||||
}
|
||||
|
||||
else -> contextCollector.addDeclarationContext(target, bodyResolveContext)
|
||||
}
|
||||
}
|
||||
|
||||
if (target is FirRegularClass) {
|
||||
withRegularClass(target) {
|
||||
contextCollector.addDeclarationContext(target, bodyResolveContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun withTypeParametersIfMemberDeclaration(
|
||||
context: BodyResolveContext,
|
||||
target: FirElementWithResolveState,
|
||||
action: () -> Unit,
|
||||
) {
|
||||
if (target is FirMemberDeclaration) {
|
||||
@OptIn(PrivateForInline::class)
|
||||
context.withTypeParametersOf(target, action)
|
||||
} else {
|
||||
action()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun LLFirAbstractBodyTargetResolver.transformAnnotations(target: FirElementWithResolveState) {
|
||||
|
||||
+3
-28
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.analysis.utils.errors.checkWithAttachmentBuilder
|
||||
import org.jetbrains.kotlin.fir.FirElementWithResolveState
|
||||
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.PrivateForInline
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.getExplicitBackingField
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
@@ -75,7 +74,7 @@ private class LLFirBodyTargetResolver(
|
||||
lockProvider: LLFirLockProvider,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
towerDataContextCollector: FirResolveContextCollector?,
|
||||
firResolveContextCollector: FirResolveContextCollector?,
|
||||
) : LLFirAbstractBodyTargetResolver(
|
||||
target,
|
||||
lockProvider,
|
||||
@@ -87,8 +86,8 @@ private class LLFirBodyTargetResolver(
|
||||
phase = resolverPhase,
|
||||
implicitTypeOnly = false,
|
||||
scopeSession = scopeSession,
|
||||
returnTypeCalculator = createReturnTypeCalculator(towerDataContextCollector = towerDataContextCollector),
|
||||
firResolveContextCollector = towerDataContextCollector,
|
||||
returnTypeCalculator = createReturnTypeCalculator(firResolveContextCollector = firResolveContextCollector),
|
||||
firResolveContextCollector = firResolveContextCollector,
|
||||
) {
|
||||
override val preserveCFGForClasses: Boolean get() = false
|
||||
}
|
||||
@@ -130,12 +129,7 @@ private class LLFirBodyTargetResolver(
|
||||
}
|
||||
|
||||
private fun resolveMembersForControlFlowGraph(target: FirRegularClass) {
|
||||
withTypeArguments(target) {
|
||||
transformer.firResolveContextCollector?.addClassHeaderContext(target, transformer.context.towerDataContext)
|
||||
}
|
||||
withRegularClass(target) {
|
||||
transformer.firResolveContextCollector?.addDeclarationContext(target, transformer.context)
|
||||
|
||||
for (member in target.declarations) {
|
||||
if (member is FirControlFlowGraphOwner && member.isUsedInControlFlowGraphBuilderForClass) {
|
||||
member.lazyResolveToPhase(resolverPhase.previous)
|
||||
@@ -146,18 +140,6 @@ private class LLFirBodyTargetResolver(
|
||||
}
|
||||
|
||||
override fun doLazyResolveUnderLock(target: FirElementWithResolveState) {
|
||||
val contextCollector = transformer.firResolveContextCollector
|
||||
if (contextCollector != null && target is FirDeclaration) {
|
||||
val bodyResolveContext = transformer.context
|
||||
if (target is FirFunction) {
|
||||
bodyResolveContext.forFunctionBody(target, transformer.components) {
|
||||
contextCollector.addDeclarationContext(target, bodyResolveContext)
|
||||
}
|
||||
} else {
|
||||
contextCollector.addDeclarationContext(target, bodyResolveContext)
|
||||
}
|
||||
}
|
||||
|
||||
when (target) {
|
||||
is FirRegularClass -> error("Should have been resolved in ${::doResolveWithoutLock.name}")
|
||||
is FirConstructor -> resolve(target, BodyStateKeepers.CONSTRUCTOR)
|
||||
@@ -175,13 +157,6 @@ private class LLFirBodyTargetResolver(
|
||||
else -> throwUnexpectedFirElementError(target)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun withTypeArguments(regularClass: FirRegularClass, action: () -> Unit) {
|
||||
@OptIn(PrivateForInline::class)
|
||||
transformer.declarationsTransformer.context.withTypeParametersOf(regularClass) {
|
||||
action()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal object BodyStateKeepers {
|
||||
|
||||
+3
-3
@@ -56,7 +56,7 @@ internal class LLFirImplicitBodyTargetResolver(
|
||||
lockProvider: LLFirLockProvider,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
towerDataContextCollector: FirResolveContextCollector?,
|
||||
firResolveContextCollector: FirResolveContextCollector?,
|
||||
implicitBodyResolveComputationSession: ImplicitBodyResolveComputationSession? = null,
|
||||
) : LLFirAbstractBodyTargetResolver(
|
||||
target,
|
||||
@@ -72,8 +72,8 @@ internal class LLFirImplicitBodyTargetResolver(
|
||||
phase = resolverPhase,
|
||||
implicitTypeOnly = true,
|
||||
scopeSession = scopeSession,
|
||||
firResolveContextCollector = towerDataContextCollector,
|
||||
returnTypeCalculator = createReturnTypeCalculator(towerDataContextCollector = towerDataContextCollector),
|
||||
firResolveContextCollector = firResolveContextCollector,
|
||||
returnTypeCalculator = createReturnTypeCalculator(firResolveContextCollector = firResolveContextCollector),
|
||||
) {
|
||||
override val preserveCFGForClasses: Boolean get() = false
|
||||
}
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ internal class LLFirReturnTypeCalculatorWithJump(
|
||||
lockProvider = lockProvider,
|
||||
session = declaration.moduleData.session,
|
||||
scopeSession = scopeSession,
|
||||
towerDataContextCollector = towerDataContextCollector,
|
||||
firResolveContextCollector = towerDataContextCollector,
|
||||
implicitBodyResolveComputationSession = implicitBodyResolveComputationSession,
|
||||
)
|
||||
|
||||
|
||||
+6
@@ -79,6 +79,12 @@ internal abstract class LLFirTargetResolver(
|
||||
is LLFirWholeFileResolveTarget -> {
|
||||
resolveTarget.forEachTopLevelDeclaration(::resolveTargetWithNestedDeclarations)
|
||||
}
|
||||
is LLFirWholeClassResolveTarget -> {
|
||||
performResolve(resolveTarget.target)
|
||||
withRegularClass(resolveTarget.target) {
|
||||
resolveTarget.forEachDeclaration(::resolveTargetWithNestedDeclarations)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -48,14 +48,14 @@ internal object FirElementFinder {
|
||||
nonLocalDeclaration = nonLocalDeclaration,
|
||||
)?.pathWithTarget
|
||||
|
||||
private class FirDeclarationDesignation(
|
||||
class FirDeclarationDesignation(
|
||||
val path: List<FirRegularClass>,
|
||||
val target: FirDeclaration,
|
||||
) {
|
||||
val pathWithTarget: List<FirDeclaration> get() = path + target
|
||||
}
|
||||
|
||||
private fun collectDesignationPath(
|
||||
fun collectDesignationPath(
|
||||
firFile: FirFile,
|
||||
nonLocalDeclaration: KtDeclaration,
|
||||
): FirDeclarationDesignation? = collectDesignationPath(
|
||||
|
||||
+22
-2
@@ -228,6 +228,23 @@ open class PsiRawFirBuilder(
|
||||
context
|
||||
)
|
||||
|
||||
open fun convertPropertyAccessor(
|
||||
accessor: KtPropertyAccessor?,
|
||||
property: KtProperty,
|
||||
propertyTypeRef: FirTypeRef,
|
||||
propertySymbol: FirPropertySymbol,
|
||||
isGetter: Boolean,
|
||||
accessorAnnotationsFromProperty: List<FirAnnotation>,
|
||||
parameterAnnotationsFromProperty: List<FirAnnotation>,
|
||||
): FirPropertyAccessor? = accessor.toFirPropertyAccessor(
|
||||
property,
|
||||
propertyTypeRef,
|
||||
propertySymbol,
|
||||
isGetter,
|
||||
accessorAnnotationsFromProperty,
|
||||
parameterAnnotationsFromProperty,
|
||||
)
|
||||
|
||||
open fun convertValueParameter(
|
||||
valueParameter: KtParameter,
|
||||
functionSymbol: FirFunctionSymbol<*>,
|
||||
@@ -1914,7 +1931,8 @@ open class PsiRawFirBuilder(
|
||||
propertyAnnotations.filter { it.useSiteTarget == FIELD || it.useSiteTarget == PROPERTY_DELEGATE_FIELD },
|
||||
)
|
||||
|
||||
getter = this@toFirProperty.getter.toFirPropertyAccessor(
|
||||
getter = convertPropertyAccessor(
|
||||
this@toFirProperty.getter,
|
||||
this@toFirProperty,
|
||||
propertyType,
|
||||
propertySymbol = symbol,
|
||||
@@ -1922,7 +1940,9 @@ open class PsiRawFirBuilder(
|
||||
accessorAnnotationsFromProperty = propertyAnnotations.filterUseSiteTarget(PROPERTY_GETTER),
|
||||
parameterAnnotationsFromProperty = emptyList()
|
||||
)
|
||||
setter = this@toFirProperty.setter.toFirPropertyAccessor(
|
||||
|
||||
setter = convertPropertyAccessor(
|
||||
this@toFirProperty.setter,
|
||||
this@toFirProperty,
|
||||
propertyType,
|
||||
propertySymbol = symbol,
|
||||
|
||||
+4
@@ -19,6 +19,8 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveCon
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformerDispatcher
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
|
||||
open class FirAnnotationArgumentsMappingTransformer(
|
||||
@@ -27,6 +29,7 @@ open class FirAnnotationArgumentsMappingTransformer(
|
||||
resolvePhase: FirResolvePhase,
|
||||
outerBodyResolveContext: BodyResolveContext? = null,
|
||||
returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve,
|
||||
firResolveContextCollector: FirResolveContextCollector? = null,
|
||||
) : FirAbstractBodyResolveTransformerDispatcher(
|
||||
session,
|
||||
resolvePhase,
|
||||
@@ -34,6 +37,7 @@ open class FirAnnotationArgumentsMappingTransformer(
|
||||
scopeSession,
|
||||
outerBodyResolveContext = outerBodyResolveContext,
|
||||
returnTypeCalculator = returnTypeCalculator,
|
||||
firResolveContextCollector = firResolveContextCollector,
|
||||
) {
|
||||
final override val expressionsTransformer: FirExpressionsResolveTransformer =
|
||||
FirExpressionTransformerForAnnotationArgumentsMapping(this)
|
||||
|
||||
+3
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguouslyResolvedAnnotationArgument
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -38,6 +39,7 @@ open class FirAnnotationArgumentsResolveTransformer(
|
||||
resolvePhase: FirResolvePhase,
|
||||
outerBodyResolveContext: BodyResolveContext? = null,
|
||||
returnTypeCalculator: ReturnTypeCalculator = ReturnTypeCalculatorForFullBodyResolve,
|
||||
firResolveContextCollector: FirResolveContextCollector? = null,
|
||||
) : FirAbstractBodyResolveTransformerDispatcher(
|
||||
session,
|
||||
resolvePhase,
|
||||
@@ -45,6 +47,7 @@ open class FirAnnotationArgumentsResolveTransformer(
|
||||
scopeSession,
|
||||
outerBodyResolveContext = outerBodyResolveContext,
|
||||
returnTypeCalculator = returnTypeCalculator,
|
||||
firResolveContextCollector = firResolveContextCollector,
|
||||
) {
|
||||
final override val expressionsTransformer: FirExpressionsResolveTransformer =
|
||||
FirExpressionsResolveTransformerForSpecificAnnotations(this)
|
||||
|
||||
Reference in New Issue
Block a user