FIR IDE: improve search of containing declaration for getOrBuildFir
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.fir
|
package org.jetbrains.kotlin.idea.fir
|
||||||
|
|
||||||
|
import com.intellij.openapi.progress.ProcessCanceledException
|
||||||
import com.intellij.openapi.progress.ProgressIndicatorProvider
|
import com.intellij.openapi.progress.ProgressIndicatorProvider
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
@@ -32,7 +33,6 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
import org.jetbrains.kotlin.util.containingNonLocalDeclaration
|
|
||||||
|
|
||||||
private val FirResolvePhase.stubMode: Boolean
|
private val FirResolvePhase.stubMode: Boolean
|
||||||
get() = this <= FirResolvePhase.DECLARATIONS
|
get() = this <= FirResolvePhase.DECLARATIONS
|
||||||
@@ -51,7 +51,8 @@ private fun FirFile.findCallableMember(
|
|||||||
return provider.getClassDeclaredCallableSymbols(ClassId(packageFqName, klassFqName, false), declName)
|
return provider.getClassDeclaredCallableSymbols(ClassId(packageFqName, klassFqName, false), declName)
|
||||||
.find { symbol: FirCallableSymbol<*> ->
|
.find { symbol: FirCallableSymbol<*> ->
|
||||||
symbol.fir.psi == callableMember
|
symbol.fir.psi == callableMember
|
||||||
}?.fir ?: error("Cannot find FIR callable declaration ${CallableId(packageFqName, klassFqName, declName)}")
|
}?.fir
|
||||||
|
?: error("Cannot find FIR callable declaration ${CallableId(packageFqName, klassFqName, declName)}")
|
||||||
}
|
}
|
||||||
// NB: not sure it's correct to use member scope provider from here (because of possible changes)
|
// NB: not sure it's correct to use member scope provider from here (because of possible changes)
|
||||||
val memberScope = FirPackageMemberScope(this.packageFqName, session)
|
val memberScope = FirPackageMemberScope(this.packageFqName, session)
|
||||||
@@ -228,12 +229,30 @@ inline fun <reified E : FirElement> KtElement.getOrBuildFirSafe(
|
|||||||
phase: FirResolvePhase = FirResolvePhase.BODY_RESOLVE
|
phase: FirResolvePhase = FirResolvePhase.BODY_RESOLVE
|
||||||
) = getOrBuildFir(state, phase) as? E
|
) = getOrBuildFir(state, phase) as? E
|
||||||
|
|
||||||
|
|
||||||
|
private fun KtElement.getNonLocalContainingDeclarationWithFqName(): KtDeclaration? {
|
||||||
|
var container = parent
|
||||||
|
while (container != null && container !is KtFile) {
|
||||||
|
if (container is KtDeclaration
|
||||||
|
&& (container is KtClassOrObject || container is KtDeclarationWithBody)
|
||||||
|
&& !KtPsiUtil.isLocal(container)
|
||||||
|
&& container.name != null
|
||||||
|
&& container !is KtEnumEntry
|
||||||
|
&& container.containingClassOrObject !is KtEnumEntry
|
||||||
|
) {
|
||||||
|
return container
|
||||||
|
}
|
||||||
|
container = container.parent
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
fun KtElement.getOrBuildFir(
|
fun KtElement.getOrBuildFir(
|
||||||
state: FirModuleResolveState,
|
state: FirModuleResolveState,
|
||||||
phase: FirResolvePhase = FirResolvePhase.BODY_RESOLVE
|
phase: FirResolvePhase = FirResolvePhase.BODY_RESOLVE
|
||||||
): FirElement {
|
): FirElement {
|
||||||
val containerFir: FirDeclaration =
|
val containerFir: FirDeclaration =
|
||||||
when (val container = this.containingNonLocalDeclaration()) {
|
when (val container = getNonLocalContainingDeclarationWithFqName()) {
|
||||||
is KtCallableDeclaration -> container.getOrBuildFir(state, phase)
|
is KtCallableDeclaration -> container.getOrBuildFir(state, phase)
|
||||||
is KtClassOrObject -> container.getOrBuildFir(state, phase)
|
is KtClassOrObject -> container.getOrBuildFir(state, phase)
|
||||||
null -> containingKtFile.getOrBuildFir(state, phase)
|
null -> containingKtFile.getOrBuildFir(state, phase)
|
||||||
|
|||||||
Reference in New Issue
Block a user