FIR IDE: fix lazy resolve for non local declaration without containing class

This commit is contained in:
Ilya Kirillov
2020-08-31 19:27:20 +03:00
parent 87898021a1
commit 162a2ac7b0
2 changed files with 54 additions and 24 deletions
@@ -100,6 +100,7 @@ internal open class FirModuleResolveStateImpl(
) { ) {
firLazyDeclarationResolver.runLazyResolveWithoutLock( firLazyDeclarationResolver.runLazyResolveWithoutLock(
firFunction, firFunction,
fileCache,
containerFirFile, containerFirFile,
firIdeProvider, firIdeProvider,
toPhase, toPhase,
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.util.checkCanceled
import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
import org.jetbrains.kotlin.idea.fir.low.level.api.util.getContainingFile import org.jetbrains.kotlin.idea.fir.low.level.api.util.getContainingFile
import org.jetbrains.kotlin.idea.util.classIdIfNonLocal import org.jetbrains.kotlin.idea.util.classIdIfNonLocal
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
@@ -40,12 +41,28 @@ internal class FirLazyDeclarationResolver(
val provider = firFile.session.firIdeProvider val provider = firFile.session.firIdeProvider
if (checkPCE) { if (checkPCE) {
firFileBuilder.runCustomResolveWithPCECheck(firFile, moduleFileCache) { firFileBuilder.runCustomResolveWithPCECheck(firFile, moduleFileCache) {
runLazyResolveWithoutLock(declaration, firFile, provider, toPhase, towerDataContextCollector, checkPCE = true) runLazyResolveWithoutLock(
declaration,
moduleFileCache,
firFile,
provider,
toPhase,
towerDataContextCollector,
checkPCE = true
)
} }
} else { } else {
firFileBuilder.runCustomResolveUnderLock(firFile, moduleFileCache) { firFileBuilder.runCustomResolveUnderLock(firFile, moduleFileCache) {
executeWithoutPCE { executeWithoutPCE {
runLazyResolveWithoutLock(declaration, firFile, provider, toPhase, towerDataContextCollector, checkPCE = false) runLazyResolveWithoutLock(
declaration,
moduleFileCache,
firFile,
provider,
toPhase,
towerDataContextCollector,
checkPCE = false
)
} }
} }
} }
@@ -53,6 +70,7 @@ internal class FirLazyDeclarationResolver(
fun runLazyResolveWithoutLock( fun runLazyResolveWithoutLock(
firDeclarationToResolve: FirDeclaration, firDeclarationToResolve: FirDeclaration,
moduleFileCache: ModuleFileCache,
containerFirFile: FirFile, containerFirFile: FirFile,
provider: FirProvider, provider: FirProvider,
toPhase: FirResolvePhase, toPhase: FirResolvePhase,
@@ -70,17 +88,18 @@ internal class FirLazyDeclarationResolver(
} }
if (toPhase <= nonLazyPhase) return if (toPhase <= nonLazyPhase) return
if (checkPCE) checkCanceled() if (checkPCE) checkCanceled()
runLazyResolvePhase(firDeclarationToResolve, containerFirFile, provider, toPhase, towerDataContextCollector) runLazyResolvePhase(firDeclarationToResolve, containerFirFile, moduleFileCache, provider, toPhase, towerDataContextCollector)
} }
private fun runLazyResolvePhase( private fun runLazyResolvePhase(
firDeclarationToResolve: FirDeclaration, firDeclarationToResolve: FirDeclaration,
containerFirFile: FirFile, containerFirFile: FirFile,
moduleFileCache: ModuleFileCache,
provider: FirProvider, provider: FirProvider,
toPhase: FirResolvePhase, toPhase: FirResolvePhase,
towerDataContextCollector: FirTowerDataContextCollector?, towerDataContextCollector: FirTowerDataContextCollector?,
) { ) {
val nonLocalDeclarationToResolve = firDeclarationToResolve.getNonLocalDeclarationToResolve(provider) val nonLocalDeclarationToResolve = firDeclarationToResolve.getNonLocalDeclarationToResolve(provider, moduleFileCache)
val designation = mutableListOf<FirDeclaration>(containerFirFile) val designation = mutableListOf<FirDeclaration>(containerFirFile)
if (nonLocalDeclarationToResolve !is FirFile) { if (nonLocalDeclarationToResolve !is FirFile) {
@@ -113,27 +132,37 @@ internal class FirLazyDeclarationResolver(
) )
containerFirFile.transform<FirFile, ResolutionMode>(transformer, ResolutionMode.ContextDependent) containerFirFile.transform<FirFile, ResolutionMode>(transformer, ResolutionMode.ContextDependent)
} }
}
private fun FirDeclaration.getNonLocalDeclarationToResolve(provider: FirProvider, moduleFileCache: ModuleFileCache): FirDeclaration {
private fun FirDeclaration.getNonLocalDeclarationToResolve(provider: FirProvider): FirDeclaration { if (this is FirFile) return this
if (this is FirFile) return this val ktDeclaration = psi as? KtDeclaration ?: error("FirDeclaration should have a PSI of type KtDeclaration")
val ktDeclaration = psi as? KtDeclaration ?: error("FirDeclaration should have a PSI of type KtDeclaration") if (!KtPsiUtil.isLocal(ktDeclaration)) return this
if (!KtPsiUtil.isLocal(ktDeclaration)) return this return when (val nonLocalPsi = ktDeclaration.getNonLocalContainingDeclarationWithFqName()) {
return when (val nonLocalPsi = ktDeclaration.getNonLocalContainingDeclarationWithFqName()) { is KtClassOrObject -> provider.getFirClassifierByFqName(
is KtClassOrObject -> provider.getFirClassifierByFqName( nonLocalPsi.classIdIfNonLocal()
nonLocalPsi.classIdIfNonLocal() ?: error("Container classId should not be null for non-local declaration")
?: error("Container classId should not be null for non-local declaration") ) ?: error("Could not find class ${nonLocalPsi.classIdIfNonLocal()}")
) ?: error("Could not find class ${nonLocalPsi.classIdIfNonLocal()}") is KtProperty, is KtNamedFunction -> {
is KtProperty, is KtNamedFunction -> { val containerClass = nonLocalPsi.containingClassOrObject
val containerClass = nonLocalPsi.containingClassOrObject if (containerClass != null) {
?: error("Container class should not be null for non-local declaration") val containerClassId = containerClass.classIdIfNonLocal()
val containerClassId = containerClass.classIdIfNonLocal() ?: error("Container classId should not be null for non-local declaration")
?: error("Container classId should not be null for non-local declaration") val containingFir = provider.getFirClassifierByFqName(containerClassId) as? FirRegularClass
val containingFir = provider.getFirClassifierByFqName(containerClassId) as? FirRegularClass ?: error("Could not find class $containerClassId")
?: error("Could not find class $containerClassId") containingFir.declarations.first { it.psi === nonLocalPsi }
containingFir.declarations.first { it.psi === nonLocalPsi } } else {
val packageFqName = ktDeclaration.containingKtFile.packageFqName
provider.symbolProvider.getTopLevelCallableSymbols(packageFqName, nonLocalPsi.nameAsSafeName)
.firstOrNull { it.fir.psi === nonLocalPsi }
val ktFile = ktDeclaration.containingKtFile
val firFile = firFileBuilder.buildRawFirFileWithCaching(ktFile, moduleFileCache)
firFile.declarations.firstOrNull { it.psi === nonLocalPsi }
?: error("Cannot find FIR for\n${nonLocalPsi.getElementTextInContext()}")
}
}
else -> error("Invalid container ${nonLocalPsi?.let { it::class } ?: "null"}")
} }
else -> error("Invalid container ${nonLocalPsi?.let { it::class } ?: "null"}")
} }
} }