[FIR IDE] Fix invalid collecting designation for local declarations

This commit is contained in:
Igor Yakovlev
2021-06-14 18:54:03 +02:00
parent 41c42a5016
commit c17a67ba61
5 changed files with 25 additions and 16 deletions
@@ -11,9 +11,11 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseManager
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.idea.fir.low.level.api.api.tryCollectDesignation
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirSessionInvalidator
import org.jetbrains.kotlin.idea.fir.low.level.api.util.isLocalDeclaration
@ThreadSafeMutableState
internal class IdeFirPhaseManager(
@@ -26,6 +28,7 @@ internal class IdeFirPhaseManager(
requiredPhase: FirResolvePhase
) {
val fir = symbol.fir as FirDeclaration
if (fir.isLocalDeclaration) return
try {
if (fir.resolvePhase < requiredPhase) { //TODO Make thread safe
lazyDeclarationResolver.lazyResolveDeclaration(
@@ -5,16 +5,16 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.api
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.containingClassForLocal
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.idea.fir.low.level.api.util.getContainingFile
import org.jetbrains.kotlin.idea.fir.low.level.api.util.isLocalDeclaration
import org.jetbrains.kotlin.idea.util.ifFalse
import org.jetbrains.kotlin.idea.util.ifTrue
class FirDeclarationDesignationWithFile(
path: List<FirDeclaration>,
@@ -55,13 +55,17 @@ private fun FirRegularClass.collectForNonLocal(): List<FirDeclaration> {
}
private fun collectDesignationPath(declaration: FirDeclaration): List<FirDeclaration>? {
if (declaration.isLocalDeclaration) return null
val containingClass = when (declaration) {
is FirCallableDeclaration<*> ->
is FirCallableDeclaration<*> -> {
val isLocalMember = (declaration as? FirCallableMemberDeclaration<*>)?.status?.visibility == Visibilities.Local
if (isLocalMember) return null
when (declaration) {
is FirSimpleFunction, is FirProperty, is FirField, is FirConstructor ->
declaration.containingClass()?.toFirRegularClass(declaration.moduleData.session)
else -> return null
}
}
is FirClassLikeDeclaration<*> -> {
if (declaration.isLocal) return null
declaration.symbol.classId.outerClassId?.let(declaration.moduleData.session.firProvider::getFirClassifierByFqName)
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.transformers.FirProviderInter
import org.jetbrains.kotlin.idea.fir.low.level.api.transformers.LazyTransformerFactory
import org.jetbrains.kotlin.idea.fir.low.level.api.util.checkCanceled
import org.jetbrains.kotlin.idea.fir.low.level.api.util.ensurePhase
import org.jetbrains.kotlin.idea.util.ifFalse
import org.jetbrains.kotlin.idea.util.ifTrue
internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBuilder) {
@@ -207,19 +206,15 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
}
val provider = firDeclarationToResolve.moduleData.session.firIdeProvider
val (designation, wasInLocalDeclaration) =
firDeclarationToResolve.getNonLocalDeclarationToResolveAndInLocal(provider, moduleFileCache, firFileBuilder)
val (designation, forceToBody) =
firDeclarationToResolve.getNonLocalDeclarationToResolveAndForceUpgradeToBodyPhase(provider, moduleFileCache, firFileBuilder)
val neededPhase = if (forceToBody) FirResolvePhase.BODY_RESOLVE else toPhase
//TODO Should be synchronised
if (!designation.declaration.isValidForResolve()) return
//TODO Should be synchronised
val resolvePhase = designation.resolvePhaseForAllDeclarations(includeDeclarationPhase = declarationPhaseDowngraded)
val neededPhase = if (wasInLocalDeclaration) {
if (toPhase >= FirResolvePhase.CONTRACTS) FirResolvePhase.BODY_RESOLVE else maxOf(FirResolvePhase.CONTRACTS, toPhase)
} else toPhase
if (resolvePhase >= neededPhase) return
moduleFileCache.firFileLockProvider.runCustomResolveUnderLock(designation.firFile, checkPCE) {
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
internal fun FirDeclaration.getNonLocalDeclarationToResolveAndInLocal(
internal fun FirDeclaration.getNonLocalDeclarationToResolveAndForceUpgradeToBodyPhase(
provider: FirProvider,
moduleFileCache: ModuleFileCache,
firFileBuilder: FirFileBuilder
@@ -5,10 +5,8 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.util
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.realPsi
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
@@ -128,3 +126,12 @@ private fun KtClassLikeDeclaration.findFir(firSymbolProvider: FirSymbolProvider)
val FirDeclaration.isGeneratedDeclaration
get() = realPsi == null
internal val FirDeclaration.isLocalDeclaration: Boolean
get() = when (this) {
is FirCallableDeclaration<*> ->
((this as? FirCallableMemberDeclaration<*>)?.status?.visibility == Visibilities.Local)
is FirClassLikeDeclaration<*> -> isLocal
else -> true
}