diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt index 2a3b629d1d1..0d556e50a4d 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProviderHelper.kt @@ -72,6 +72,7 @@ internal class LLFirProviderHelper( private val classifierByClassId = firSession.firCachesFactory.createCache { classId, context -> + require(context == null || context.isPhysical) val ktClass = context ?: declarationProvider.getClassLikeDeclarationByClassId(classId) ?: return@createCache null if (ktClass.getClassId() == null) return@createCache null @@ -82,6 +83,7 @@ internal class LLFirProviderHelper( private val callablesByCallableId = firSession.firCachesFactory.createCache>, Collection?> { callableId, context -> + require(context == null || context.all { it.isPhysical }) val files = context ?: declarationProvider.getTopLevelCallableFiles(callableId).ifEmpty { return@createCache emptyList() } buildList { files.forEach { ktFile -> diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt index 1b19f780b43..89ef3e7443a 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/util/declarationUtils.kt @@ -32,7 +32,12 @@ internal fun KtDeclaration.findSourceNonLocalFirDeclaration( //TODO test what way faster findSourceNonLocalFirDeclarationByProvider(firFileBuilder, provider, containerFirFile)?.let { return it } findSourceByTraversingWholeTree(firFileBuilder, containerFirFile)?.let { return it } - errorWithFirSpecificEntries("No fir element was found for", psi = this) + errorWithFirSpecificEntries( + "No fir element was found for", + psi = this, + fir = containerFirFile ?: firFileBuilder.buildRawFirFileWithCaching(containingKtFile), + additionalInfos = { withEntry("isPhysical", isPhysical.toString()) } + ) } internal fun KtDeclaration.findFirDeclarationForAnyFirSourceDeclaration( @@ -68,7 +73,7 @@ internal fun KtElement.findSourceByTraversingWholeTree( val isDeclaration = this is KtDeclaration return FirElementFinder.findElementIn( firFile, - canGoInside = { it is FirRegularClass || it is FirScript }, + canGoInside = { it is FirRegularClass || it is FirScript || it is FirFunction }, predicate = { firDeclaration -> firDeclaration.psi == this || isDeclaration && firDeclaration.psi == originalDeclaration } @@ -80,6 +85,11 @@ private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider( provider: FirProvider, containerFirFile: FirFile?, ): FirDeclaration? { + if (!isPhysical) { + //do not request providers with non-physical psi in order not to leak them there and + //to avoid inconsistency between physical psi and its copy during completion + return null + } val candidate = when { this is KtClassOrObject -> findFir(provider) this is KtNamedDeclaration && (this is KtProperty || this is KtNamedFunction) -> { @@ -97,19 +107,18 @@ private fun KtDeclaration.findSourceNonLocalFirDeclarationByProvider( firFile.declarations } } - val original = originalDeclaration /* It is possible that we will not be able to find needed declaration here when the code is invalid, e.g, we have two conflicting declarations with the same name and we are searching in the wrong one */ - declarations?.firstOrNull { it.psi == this || it.psi == original } + declarations?.firstOrNull { it.psi == this } } this is KtConstructor<*> || this is KtClassInitializer -> { val containingClass = containingClassOrObject ?: errorWithFirSpecificEntries("Container class should be not null for KtConstructor", psi = this) val containerClassFir = containingClass.findFir(provider) as? FirRegularClass ?: return null - containerClassFir.declarations.firstOrNull { it.psi === this } + containerClassFir.declarations.firstOrNull { it.psi == this } } this is KtTypeAlias -> findFir(provider) this is KtDestructuringDeclaration -> {