[FIR] Extract mayHaveTopLevelClassifier from composite symbol provider

- The implementation is not trivial and should be usable in other symbol
  providers.
This commit is contained in:
Marco Pennekamp
2023-02-13 22:12:10 +01:00
committed by Space Team
parent 343deeec1c
commit 18ce21fb13
2 changed files with 27 additions and 5 deletions
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.types.coneTypeSafe
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.fir.types.functionTypeService
@RequiresOptIn @RequiresOptIn
annotation class FirSymbolProviderInternals 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 * @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<Name>? abstract fun computeCallableNamesInPackage(packageFqName: FqName): Set<Name>?
/**
* 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<String>,
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
}
} }
/** /**
@@ -106,11 +106,7 @@ class FirCachingCompositeSymbolProvider(
override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? { override fun getClassLikeSymbolByClassId(classId: ClassId): FirClassLikeSymbol<*>? {
val knownClassifierNames = knownTopLevelClassifierNamesInPackage.getValue(classId.packageFqName) val knownClassifierNames = knownTopLevelClassifierNamesInPackage.getValue(classId.packageFqName)
if (knownClassifierNames != null && !isNameForFunctionClass(classId)) { if (knownClassifierNames != null && !mayHaveTopLevelClassifier(classId, knownClassifierNames)) return null
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
}
return classLikeCache.getValue(classId) return classLikeCache.getValue(classId)
} }