From 9a562a029389dad8bfdf798541778ad08b93a9d2 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Sun, 17 Apr 2022 19:00:43 +0200 Subject: [PATCH] [analysis api] optimize search for declarations in IDE --- .../api/fir/FirDeserializedDeclarationSourceProvider.kt | 4 ++-- .../analysis/providers/KotlinDeclarationProvider.kt | 6 ++++-- .../providers/impl/KotlinStaticDeclarationProvider.kt | 9 +++++++-- .../api/fir/providers/LLFirIdePredicateBasedProvider.kt | 2 +- .../low/level/api/fir/providers/LLFirProviderHelper.kt | 7 +++---- .../light/classes/symbol/KotlinAsJavaFirSupport.kt | 4 ++-- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirDeserializedDeclarationSourceProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirDeserializedDeclarationSourceProvider.kt index 7bfab0bc061..476d3a2d9bd 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirDeserializedDeclarationSourceProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/FirDeserializedDeclarationSourceProvider.kt @@ -67,7 +67,7 @@ internal object FirDeserializedDeclarationSourceProvider { classByClassId(klass.symbol.classId, klass.scope(project), project) private fun provideSourceForTypeAlias(alias: FirTypeAlias, project: Project): PsiElement? { - val candidates = project.createDeclarationProvider(alias.scope(project)).getTypeAliasesByClassId(alias.symbol.classId) + val candidates = project.createDeclarationProvider(alias.scope(project)).getAllTypeAliasesByClassId(alias.symbol.classId) return candidates.firstOrNull(KtElement::isCompiled) } @@ -120,7 +120,7 @@ internal object FirDeserializedDeclarationSourceProvider { private fun classByClassId(classId: ClassId, scope: GlobalSearchScope, project: Project): KtClassOrObject? { val correctedClassId = classIdMapping[classId] ?: classId return project.createDeclarationProvider(scope) - .getClassesByClassId(correctedClassId) + .getAllClassesByClassId(correctedClassId) .firstOrNull(KtElement::isCompiled) } diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt index 13bcc50e214..ee7366a4e50 100644 --- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt +++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinDeclarationProvider.kt @@ -19,8 +19,10 @@ import org.jetbrains.kotlin.psi.* * May be called frequently, so for implementations it is better to cache results. */ public abstract class KotlinDeclarationProvider { - public abstract fun getClassesByClassId(classId: ClassId): Collection - public abstract fun getTypeAliasesByClassId(classId: ClassId): Collection + public abstract fun getClassLikeDeclarationByClassId(classId: ClassId): KtClassLikeDeclaration? + + public abstract fun getAllClassesByClassId(classId: ClassId): Collection + public abstract fun getAllTypeAliasesByClassId(classId: ClassId): Collection public abstract fun getClassNamesInPackage(packageFqName: FqName): Set public abstract fun getTypeAliasNamesInPackage(packageFqName: FqName): Set diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt index fe428ec6b36..380fa55c8d2 100644 --- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt +++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticDeclarationProvider.kt @@ -32,14 +32,19 @@ public class KotlinStaticDeclarationProvider internal constructor( private val KtElement.inScope: Boolean get() = containingKtFile.virtualFile in scope - override fun getClassesByClassId(classId: ClassId): Collection = + override fun getClassLikeDeclarationByClassId(classId: ClassId): KtClassLikeDeclaration? { + return getAllClassesByClassId(classId).firstOrNull() + ?: getAllTypeAliasesByClassId(classId).firstOrNull() + } + + override fun getAllClassesByClassId(classId: ClassId): Collection = index.classMap[classId.packageFqName] ?.filter { ktClassOrObject -> ktClassOrObject.getClassId() == classId && ktClassOrObject.inScope } ?: emptyList() - override fun getTypeAliasesByClassId(classId: ClassId): Collection = + override fun getAllTypeAliasesByClassId(classId: ClassId): Collection = index.typeAliasMap[classId.packageFqName] ?.filter { ktTypeAlias -> ktTypeAlias.getClassId() == classId && ktTypeAlias.inScope diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdePredicateBasedProvider.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdePredicateBasedProvider.kt index 33c4d48e5d5..9e6d5be3757 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdePredicateBasedProvider.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/providers/LLFirIdePredicateBasedProvider.kt @@ -158,7 +158,7 @@ internal class LLFirIdePredicateBasedProvider( val directAnnotations = annotationsOnDeclaration(declaration) val metaAnnotations = directAnnotations .asSequence() - .mapNotNull { declarationProvider.getClassesByClassId(ClassId.topLevel(it)).singleOrNull() } + .mapNotNull { declarationProvider.getAllClassesByClassId(ClassId.topLevel(it)).singleOrNull() } .flatMap { annotationsResolver.annotationsOnDeclaration(it) } .toSet() 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 5c9324610ce..110be791679 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 @@ -35,10 +35,9 @@ internal class LLFirProviderHelper( if (classId.isLocal) return null return executeOrReturnDefaultValueOnPCE(null) { cache.classifierByClassId.computeIfAbsent(classId) { - val ktClass = when (val klass = declarationProvider.getClassesByClassId(classId).firstOrNull()) { - null -> declarationProvider.getTypeAliasesByClassId(classId).firstOrNull() - else -> if (klass.getClassId() == null) null else klass - } ?: return@computeIfAbsent Optional.empty() + val ktClass = declarationProvider.getClassLikeDeclarationByClassId(classId) + ?: return@computeIfAbsent Optional.empty() + if (ktClass.getClassId() == null) return@computeIfAbsent Optional.empty() val firFile = firFileBuilder.buildRawFirFileWithCaching(ktClass.containingKtFile) val classifier = FirElementFinder.findElementIn(firFile) { classifier -> classifier.symbol.classId == classId diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/KotlinAsJavaFirSupport.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/KotlinAsJavaFirSupport.kt index 02aabba806e..2a97d2270a7 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/KotlinAsJavaFirSupport.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/KotlinAsJavaFirSupport.kt @@ -34,7 +34,7 @@ class KotlinAsJavaFirSupport(private val project: Project) : KotlinAsJavaSupport searchScope: GlobalSearchScope ): Collection = project.createDeclarationProvider(searchScope).run { getClassNamesInPackage(packageFqName).flatMap { - getClassesByClassId(ClassId.topLevel(packageFqName.child(it))) + getAllClassesByClassId(ClassId.topLevel(packageFqName.child(it))) } } @@ -66,7 +66,7 @@ class KotlinAsJavaFirSupport(private val project: Project) : KotlinAsJavaSupport override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection = fqName.toClassIdSequence().flatMap { - project.createDeclarationProvider(searchScope).getClassesByClassId(it) + project.createDeclarationProvider(searchScope).getAllClassesByClassId(it) } .filter { it.isFromSourceOrLibraryBinary(project) } .toSet()