From 18ce21fb1331ed2458723b8e95f6505f3467dd32 Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Mon, 13 Feb 2023 22:12:10 +0100 Subject: [PATCH] [FIR] Extract `mayHaveTopLevelClassifier` from composite symbol provider - The implementation is not trivial and should be usable in other symbol providers. --- .../resolve/providers/FirSymbolProvider.kt | 26 +++++++++++++++++++ .../impl/FirCachingCompositeSymbolProvider.kt | 6 +---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/FirSymbolProvider.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/FirSymbolProvider.kt index d2ddad49197..af6694ba6a0 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/FirSymbolProvider.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/FirSymbolProvider.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.fir.types.functionTypeService @RequiresOptIn annotation class FirSymbolProviderInternals @@ -78,6 +79,31 @@ abstract class FirSymbolProvider(val session: FirSession) : FirSessionComponent * @returns top-level callable names that belong to `packageFqName` or null if it's complicated to compute the set */ abstract fun computeCallableNamesInPackage(packageFqName: FqName): Set? + + /** + * Whether [classId] may be contained in the [knownClassifierNames]. + * + * If it's certain that [classId] cannot be a function class (for example when [classId] is known to come from a package without + * function classes), [mayBeFunctionClass] can be set to `false`. This avoids a hash map access in + * [org.jetbrains.kotlin.builtins.functions.FunctionTypeKindExtractor.getFunctionalClassKindWithArity]. + */ + protected fun mayHaveTopLevelClassifier( + classId: ClassId, + knownClassifierNames: Set, + mayBeFunctionClass: Boolean = true, + ): Boolean { + if (mayBeFunctionClass && isNameForFunctionClass(classId)) return true + + val outerClassId = classId.outerClassId + if (outerClassId == null && classId.shortClassName.asString() !in knownClassifierNames) return false + if (outerClassId != null && classId.outermostClassId.shortClassName.asString() !in knownClassifierNames) return false + + return true + } + + private fun isNameForFunctionClass(classId: ClassId): Boolean { + return session.functionTypeService.getKindByClassNamePrefix(classId.packageFqName, classId.shortClassName.asString()) != null + } } /** diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCachingCompositeSymbolProvider.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCachingCompositeSymbolProvider.kt index 1bb268b6327..2bee23af8d2 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCachingCompositeSymbolProvider.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirCachingCompositeSymbolProvider.kt @@ -106,11 +106,7 @@ class FirCachingCompositeSymbolProvider( override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? { val knownClassifierNames = knownTopLevelClassifierNamesInPackage.getValue(classId.packageFqName) - if (knownClassifierNames != null && !isNameForFunctionClass(classId)) { - val outerClassId = classId.outerClassId - if (outerClassId == null && classId.shortClassName.asString() !in knownClassifierNames) return null - if (outerClassId != null && classId.outermostClassId.shortClassName.asString() !in knownClassifierNames) return null - } + if (knownClassifierNames != null && !mayHaveTopLevelClassifier(classId, knownClassifierNames)) return null return classLikeCache.getValue(classId) }