From a8f547d080724fae3a45d675a16c5b3fc2f13b17 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Wed, 1 Feb 2023 16:51:06 +0100 Subject: [PATCH] [AA LL] LLFirProvider: avoid index search if class declaration presents ^KT-55669 Fixed --- .../level/api/fir/providers/LLFirProvider.kt | 16 +++++++++--- .../api/fir/providers/LLFirProviderHelper.kt | 25 +++++++++++-------- .../level/api/fir/util/declarationUtils.kt | 13 +++++++--- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt index a4f001fef2e..8bb6b3ae8ff 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirProvider.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtClassLikeDeclaration @ThreadSafeMutableState internal class LLFirProvider( @@ -45,11 +46,20 @@ internal class LLFirProvider( override val isPhasedFirAllowed: Boolean get() = true - override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? { - return SyntheticFirClassProvider.getInstance(session).getFirClassifierByFqName(classId) - ?: providerHelper.getFirClassifierByFqName(classId) + override fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? = + getFirClassifierByFqNameAndDeclaration(classId, classLikeDeclaration = null) + + fun getFirClassifierByDeclaration(classLikeDeclaration: KtClassLikeDeclaration): FirClassLikeDeclaration? { + val classId = classLikeDeclaration.getClassId() ?: return null + return getFirClassifierByFqNameAndDeclaration(classId, classLikeDeclaration) } + private fun getFirClassifierByFqNameAndDeclaration( + classId: ClassId, + classLikeDeclaration: KtClassLikeDeclaration?, + ): FirClassLikeDeclaration? = SyntheticFirClassProvider.getInstance(session).getFirClassifierByFqName(classId) + ?: providerHelper.getFirClassifierByFqNameAndDeclaration(classId, classLikeDeclaration) + override fun getFirClassifierContainerFile(fqName: ClassId): FirFile { return getFirClassifierContainerFileIfAny(fqName) ?: error("Couldn't find container for $fqName") 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 9abe6251b75..0f48583c325 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 @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtClassLikeDeclaration internal class LLFirProviderHelper( firSession: FirSession, @@ -37,14 +38,15 @@ internal class LLFirProviderHelper( private val allowKotlinPackage = canContainKotlinPackage || firSession.languageVersionSettings.getFlag(AnalysisFlags.allowKotlinPackage) - private val classifierByClassId = firSession.firCachesFactory.createCache { classId -> - val ktClass = declarationProvider.getClassLikeDeclarationByClassId(classId) - ?: return@createCache null - if (ktClass.getClassId() == null) return@createCache null - val firFile = firFileBuilder.buildRawFirFileWithCaching(ktClass.containingKtFile) - FirElementFinder.findClassifierWithClassId(firFile, classId) - ?: error("Classifier $classId was found in file ${ktClass.containingKtFile.virtualFilePath} but was not found in FirFile") - } + private val classifierByClassId = + firSession.firCachesFactory.createCache { classId, context -> + val ktClass = context ?: declarationProvider.getClassLikeDeclarationByClassId(classId) ?: return@createCache null + + if (ktClass.getClassId() == null) return@createCache null + val firFile = firFileBuilder.buildRawFirFileWithCaching(ktClass.containingKtFile) + FirElementFinder.findClassifierWithClassId(firFile, classId) + ?: error("Classifier $classId was found in file ${ktClass.containingKtFile.virtualFilePath} but was not found in FirFile") + } private val callablesByCallableId = firSession.firCachesFactory.createCache>> { callableId -> @@ -57,10 +59,13 @@ internal class LLFirProviderHelper( } } - fun getFirClassifierByFqName(classId: ClassId): FirClassLikeDeclaration? { + fun getFirClassifierByFqNameAndDeclaration( + classId: ClassId, + classLikeDeclaration: KtClassLikeDeclaration?, + ): FirClassLikeDeclaration? { if (classId.isLocal) return null if (!allowKotlinPackage && classId.isKotlinPackage()) return null - return classifierByClassId.getValue(classId) + return classifierByClassId.getValue(classId, classLikeDeclaration) } fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List> { 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 719dcb114c8..2c5f529967e 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 @@ -1,5 +1,5 @@ /* - * Copyright 2010-2020 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. */ @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.util import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError import org.jetbrains.kotlin.analysis.low.level.api.fir.element.builder.getNonLocalContainingOrThisDeclaration import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirFileBuilder +import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirProvider import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirFile @@ -117,8 +118,14 @@ var KtFile.originalKtFile by UserDataProperty(ORIGINAL_KT_FILE_KEY) private fun KtClassLikeDeclaration.findFir(provider: FirProvider): FirClassLikeDeclaration? { - val classId = getClassId() ?: return null - return provider.getFirClassifierByFqName(classId) as? FirRegularClass + val declaration = if (provider is LLFirProvider) { + provider.getFirClassifierByDeclaration(this) + } else { + val classId = getClassId() ?: return null + provider.getFirClassifierByFqName(classId) + } + + return declaration as? FirRegularClass }