[FIR] Introduce separate getTopLevelFunction/PropertySymbols

This commit is contained in:
Mikhail Glukhikh
2020-12-14 13:23:22 +03:00
parent fd99f2b2cf
commit 4e4293b609
17 changed files with 297 additions and 117 deletions
@@ -237,6 +237,17 @@ class FirBuiltinSymbolProvider(session: FirSession, val kotlinScopeProvider: Kot
}
}
@FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
allPackageFragments[packageFqName]?.flatMapTo(destination) {
it.getTopLevelFunctionSymbols(name)
}
}
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
}
private class BuiltInsPackageFragment(
stream: InputStream, val fqName: FqName, val session: FirSession,
val kotlinScopeProvider: KotlinScopeProvider,
@@ -297,6 +308,10 @@ class FirBuiltinSymbolProvider(session: FirSession, val kotlinScopeProvider: Kot
}
fun getTopLevelCallableSymbols(name: Name): List<FirCallableSymbol<*>> {
return getTopLevelFunctionSymbols(name)
}
fun getTopLevelFunctionSymbols(name: Name): List<FirNamedFunctionSymbol> {
return packageProto.`package`.functionList.filter { nameResolver.getName(it.name) == name }.map {
memberDeserializer.loadFunction(it).symbol
}
@@ -71,6 +71,14 @@ class JavaSymbolProvider(
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
}
@FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
}
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
}
private fun JavaTypeParameter.toFirTypeParameterSymbol(
javaTypeParameterStack: JavaTypeParameterStack
): Pair<FirTypeParameterSymbol, Boolean> {
@@ -363,14 +363,14 @@ class KotlinDeserializedJvmSymbolsProvider(
return symbol
}
private fun loadFunctionsByName(part: PackagePartsCacheData, name: Name): List<FirCallableSymbol<*>> {
private fun loadFunctionsByName(part: PackagePartsCacheData, name: Name): List<FirNamedFunctionSymbol> {
val functionIds = part.topLevelFunctionNameIndex[name] ?: return emptyList()
return functionIds.map {
part.context.memberDeserializer.loadFunction(part.proto.getFunction(it)).symbol
}
}
private fun loadPropertiesByName(part: PackagePartsCacheData, name: Name): List<FirCallableSymbol<*>> {
private fun loadPropertiesByName(part: PackagePartsCacheData, name: Name): List<FirPropertySymbol> {
val propertyIds = part.topLevelPropertyNameIndex[name] ?: return emptyList()
return propertyIds.map {
part.context.memberDeserializer.loadProperty(part.proto.getProperty(it)).symbol
@@ -384,6 +384,20 @@ class KotlinDeserializedJvmSymbolsProvider(
}
}
@FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
getPackageParts(packageFqName).flatMapTo(destination) { part ->
loadFunctionsByName(part, name)
}
}
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
getPackageParts(packageFqName).flatMapTo(destination) { part ->
loadPropertiesByName(part, name)
}
}
private fun getPackageParts(packageFqName: FqName): Collection<PackagePartsCacheData> {
return packagePartsCache.lookupCacheOrCalculate(packageFqName) {
try {
@@ -32,6 +32,22 @@ abstract class FirSymbolProvider(val session: FirSession) : FirSessionComponent
@FirSymbolProviderInternals
abstract fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name)
@OptIn(ExperimentalStdlibApi::class, FirSymbolProviderInternals::class)
open fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List<FirNamedFunctionSymbol> {
return buildList { getTopLevelFunctionSymbolsTo(this, packageFqName, name) }
}
@FirSymbolProviderInternals
abstract fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name)
@OptIn(ExperimentalStdlibApi::class, FirSymbolProviderInternals::class)
open fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List<FirPropertySymbol> {
return buildList { getTopLevelPropertySymbolsTo(this, packageFqName, name) }
}
@FirSymbolProviderInternals
abstract fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name)
abstract fun getPackage(fqName: FqName): FqName? // TODO: Replace to symbol sometime
}
@@ -21,10 +21,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
import org.jetbrains.kotlin.fir.scopes.FirScopeProvider
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -71,7 +68,16 @@ class FirCloneableSymbolProvider(session: FirSession, scopeProvider: FirScopePro
}
@FirSymbolProviderInternals
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {}
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
}
@FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
}
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
}
override fun getPackage(fqName: FqName): FqName? {
return null
@@ -11,6 +11,8 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -27,6 +29,20 @@ class FirCompositeSymbolProvider(session: FirSession, val providers: List<FirSym
destination += getTopLevelCallableSymbols(packageFqName, name)
}
@FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
providers.forEach {
it.getTopLevelFunctionSymbolsTo(destination, packageFqName, name)
}
}
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
providers.forEach {
it.getTopLevelPropertySymbolsTo(destination, packageFqName, name)
}
}
override fun getPackage(fqName: FqName): FqName? {
return providers.firstNotNullResult { it.getPackage(fqName) }
}
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.fir.resolve.providers.SymbolProviderCache
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -23,6 +25,8 @@ import org.jetbrains.kotlin.name.Name
open class FirDependenciesSymbolProviderImpl(session: FirSession) : FirSymbolProvider(session) {
private val classCache = SymbolProviderCache<ClassId, FirClassLikeSymbol<*>>()
private val topLevelCallableCache = SymbolProviderCache<CallableId, List<FirCallableSymbol<*>>>()
private val topLevelFunctionCache = SymbolProviderCache<CallableId, List<FirNamedFunctionSymbol>>()
private val topLevelPropertyCache = SymbolProviderCache<CallableId, List<FirPropertySymbol>>()
private val packageCache = SymbolProviderCache<FqName, FqName>()
protected open val dependencyProviders by lazy {
@@ -32,6 +36,28 @@ open class FirDependenciesSymbolProviderImpl(session: FirSession) : FirSymbolPro
}.toList()
}
@FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
destination += topLevelFunctionCache.lookupCacheOrCalculate(CallableId(packageFqName, null, name)) {
val result = mutableListOf<FirNamedFunctionSymbol>()
dependencyProviders.forEach {
it.getTopLevelFunctionSymbolsTo(result, packageFqName, name)
}
result
} ?: emptyList()
}
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
destination += topLevelPropertyCache.lookupCacheOrCalculate(CallableId(packageFqName, null, name)) {
val result = mutableListOf<FirPropertySymbol>()
dependencyProviders.forEach {
it.getTopLevelPropertySymbolsTo(result, packageFqName, name)
}
result
} ?: emptyList()
}
@FirSymbolProviderInternals
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
destination += getTopLevelCallableSymbols(packageFqName, name)
@@ -18,9 +18,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -60,13 +58,21 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: KotlinSc
return getFirClassifierByFqName(classId)?.symbol
}
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<FirCallableSymbol<*>> {
return (state.callableMap[CallableId(packageFqName, null, name)] ?: emptyList())
@FirSymbolProviderInternals
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
destination += (state.functionMap[CallableId(packageFqName, null, name)] ?: emptyList())
destination += (state.propertyMap[CallableId(packageFqName, null, name)] ?: emptyList())
}
@FirSymbolProviderInternals
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
destination += getTopLevelCallableSymbols(packageFqName, name)
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
destination += (state.functionMap[CallableId(packageFqName, null, name)] ?: emptyList())
}
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
destination += (state.propertyMap[CallableId(packageFqName, null, name)] ?: emptyList())
}
override fun getPackage(fqName: FqName): FqName? {
@@ -121,33 +127,47 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: KotlinSc
state.classifierContainerFileMap[classId] = file
}
override fun <F : FirCallableDeclaration<F>> visitCallableDeclaration(
callableDeclaration: FirCallableDeclaration<F>,
override fun visitPropertyAccessor(
propertyAccessor: FirPropertyAccessor,
data: Pair<State, FirFile>
) {
val symbol = callableDeclaration.symbol
val symbol = propertyAccessor.symbol
val (state, file) = data
state.callableContainerMap[symbol] = file
}
private inline fun <reified D : FirCallableMemberDeclaration<D>, S : FirCallableSymbol<D>> registerCallable(
symbol: S,
data: Pair<State, FirFile>,
map: MutableMap<CallableId, List<S>>
) {
val callableId = symbol.callableId
val (state, file) = data
state.callableMap.merge(callableId, listOf(symbol)) { a, b -> a + b }
map.merge(callableId, listOf(symbol)) { a, b -> a + b }
state.callableContainerMap[symbol] = file
}
override fun visitConstructor(constructor: FirConstructor, data: Pair<State, FirFile>) {
visitCallableDeclaration(constructor, data)
val symbol = constructor.symbol
registerCallable(symbol, data, data.first.constructorMap)
}
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: Pair<State, FirFile>) {
visitCallableDeclaration(simpleFunction, data)
val symbol = simpleFunction.symbol
registerCallable(symbol, data, data.first.functionMap)
}
override fun visitProperty(property: FirProperty, data: Pair<State, FirFile>) {
visitCallableDeclaration(property, data)
property.getter?.let { visitCallableDeclaration(it, data) }
property.setter?.let { visitCallableDeclaration(it, data) }
val symbol = property.symbol
registerCallable(symbol, data, data.first.propertyMap)
property.getter?.let { visitPropertyAccessor(it, data) }
property.setter?.let { visitPropertyAccessor(it, data) }
}
override fun visitEnumEntry(enumEntry: FirEnumEntry, data: Pair<State, FirFile>) {
visitCallableDeclaration(enumEntry, data)
val symbol = enumEntry.symbol
val (state, file) = data
state.callableContainerMap[symbol] = file
}
}
@@ -158,20 +178,26 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: KotlinSc
val classifierMap = mutableMapOf<ClassId, FirClassLikeDeclaration<*>>()
val classifierContainerFileMap = mutableMapOf<ClassId, FirFile>()
val classesInPackage = mutableMapOf<FqName, MutableSet<Name>>()
val callableMap = mutableMapOf<CallableId, List<FirCallableSymbol<*>>>()
val functionMap = mutableMapOf<CallableId, List<FirNamedFunctionSymbol>>()
val propertyMap = mutableMapOf<CallableId, List<FirPropertySymbol>>()
val constructorMap = mutableMapOf<CallableId, List<FirConstructorSymbol>>()
val callableContainerMap = mutableMapOf<FirCallableSymbol<*>, FirFile>()
fun setFrom(other: State) {
fileMap.clear()
classifierMap.clear()
classifierContainerFileMap.clear()
callableMap.clear()
functionMap.clear()
propertyMap.clear()
constructorMap.clear()
callableContainerMap.clear()
fileMap.putAll(other.fileMap)
classifierMap.putAll(other.classifierMap)
classifierContainerFileMap.putAll(other.classifierContainerFileMap)
callableMap.putAll(other.callableMap)
functionMap.putAll(other.functionMap)
propertyMap.putAll(other.propertyMap)
constructorMap.putAll(other.constructorMap)
callableContainerMap.putAll(other.callableContainerMap)
classesInPackage.putAll(other.classesInPackage)
}
@@ -246,7 +272,9 @@ class FirProviderImpl(val session: FirSession, val kotlinScopeProvider: KotlinSc
checkMMapDiff("fileMap", state.fileMap, newState.fileMap)
checkMapDiff("classifierMap", state.classifierMap, newState.classifierMap)
checkMapDiff("classifierContainerFileMap", state.classifierContainerFileMap, newState.classifierContainerFileMap)
checkMMapDiff("callableMap", state.callableMap, newState.callableMap)
checkMMapDiff("callableMap", state.functionMap, newState.functionMap)
checkMMapDiff("callableMap", state.propertyMap, newState.propertyMap)
checkMMapDiff("callableMap", state.constructorMap, newState.constructorMap)
checkMapDiff("callableContainerMap", state.callableContainerMap, newState.callableContainerMap)
if (!rebuildIndex) {
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.declarations.expandedConeType
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerScopeLevel
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedForCalls
import org.jetbrains.kotlin.fir.scopes.FirScope
@@ -53,51 +52,39 @@ abstract class FirAbstractImportingScope(
return getStaticsScope(symbol)
}
protected fun <T : FirCallableSymbol<*>> processCallables(
import: FirResolvedImport,
protected inline fun processFunctionsByNameWithImport(
name: Name,
token: TowerScopeLevel.Token<T>,
processor: (FirCallableSymbol<*>) -> Unit
import: FirResolvedImport,
crossinline processor: (FirNamedFunctionSymbol) -> Unit
) {
val classId = import.resolvedClassId
if (classId != null) {
val scope = getStaticsScope(classId) ?: return
when (token) {
TowerScopeLevel.Token.Functions -> scope.processFunctionsByName(name, processor)
TowerScopeLevel.Token.Properties -> scope.processPropertiesByName(name, processor)
}
} else if (name.isSpecial || name.identifier.isNotEmpty()) {
val symbols = provider.getTopLevelCallableSymbols(import.packageFqName, name)
if (symbols.isEmpty()) {
return
}
for (symbol in symbols) {
symbol.ensureResolvedForCalls(session)
processor(symbol)
import.resolvedClassId?.let { classId ->
getStaticsScope(classId)?.processFunctionsByName(name) { processor(it) }
} ?: run {
if (name.isSpecial || name.identifier.isNotEmpty()) {
val symbols = provider.getTopLevelFunctionSymbols(import.packageFqName, name)
for (symbol in symbols) {
symbol.ensureResolvedForCalls(session)
processor(symbol)
}
}
}
}
abstract fun <T : FirCallableSymbol<*>> processCallables(
protected inline fun processPropertiesByNameWithImport(
name: Name,
token: TowerScopeLevel.Token<T>,
processor: (FirCallableSymbol<*>) -> Unit
)
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
return processCallables(
name,
TowerScopeLevel.Token.Functions
) { if (it is FirNamedFunctionSymbol) processor(it) }
import: FirResolvedImport,
crossinline processor: (FirVariableSymbol<*>) -> Unit
) {
import.resolvedClassId?.let { classId ->
getStaticsScope(classId)?.processPropertiesByName(name) { processor(it) }
} ?: run {
if (name.isSpecial || name.identifier.isNotEmpty()) {
val symbols = provider.getTopLevelPropertySymbols(import.packageFqName, name)
for (symbol in symbols) {
symbol.ensureResolvedForCalls(session)
processor(symbol)
}
}
}
}
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
return processCallables(
name,
TowerScopeLevel.Token.Properties
) { if (it is FirVariableSymbol<*>) processor(it) }
}
}
@@ -8,11 +8,11 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerScopeLevel
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
@@ -38,16 +38,17 @@ abstract class FirAbstractSimpleImportingScope(
}
}
override fun <T : FirCallableSymbol<*>> processCallables(
name: Name,
token: TowerScopeLevel.Token<T>,
processor: (FirCallableSymbol<*>) -> Unit
) {
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
val imports = simpleImports[name] ?: return
if (imports.isEmpty()) return
for (import in imports) {
processCallables(import, import.importedName!!, token, processor)
processFunctionsByNameWithImport(import.importedName!!, import, processor)
}
}
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
val imports = simpleImports[name] ?: return
for (import in imports) {
processPropertiesByNameWithImport(import.importedName!!, import, processor)
}
}
}
@@ -8,10 +8,10 @@ package org.jetbrains.kotlin.fir.scopes.impl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerScopeLevel
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
@@ -47,17 +47,15 @@ abstract class FirAbstractStarImportingScope(
}
}
override fun <T : FirCallableSymbol<*>> processCallables(
name: Name,
token: TowerScopeLevel.Token<T>,
processor: (FirCallableSymbol<*>) -> Unit
) {
if (starImports.isEmpty()) {
return
}
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
for (import in starImports) {
processCallables(import, name, token, processor)
processFunctionsByNameWithImport(name, import, processor)
}
}
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
for (import in starImports) {
processPropertiesByNameWithImport(name, import, processor)
}
}
}
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.builder.buildImport
import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerScopeLevel
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.name.Name
@@ -39,16 +38,22 @@ class FirDefaultStarImportingScope(
}
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
processCallables(
name,
TowerScopeLevel.Token.Functions
) { if (it is FirNamedFunctionSymbol) processor(it) }
if (name.isSpecial || name.identifier.isNotEmpty()) {
for (import in starImports) {
for (symbol in provider.getTopLevelFunctionSymbols(import.packageFqName, name)) {
processor(symbol)
}
}
}
}
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
processCallables(
name,
TowerScopeLevel.Token.Properties
) { if (it is FirVariableSymbol<*>) processor(it) }
if (name.isSpecial || name.identifier.isNotEmpty()) {
for (import in starImports) {
for (symbol in provider.getTopLevelPropertySymbols(import.packageFqName, name)) {
processor(symbol)
}
}
}
}
}
@@ -18,7 +18,8 @@ import org.jetbrains.kotlin.name.Name
class FirPackageMemberScope(val fqName: FqName, val session: FirSession) : FirScope() {
private val symbolProvider = session.firSymbolProvider
private val classifierCache: MutableMap<Name, FirClassifierSymbol<*>?> = mutableMapOf()
private val callableCache: MutableMap<Name, List<FirCallableSymbol<*>>> = mutableMapOf()
private val functionCache: MutableMap<Name, List<FirNamedFunctionSymbol>> = mutableMapOf()
private val propertyCache: MutableMap<Name, List<FirPropertySymbol>> = mutableMapOf()
override fun processClassifiersByNameWithSubstitution(
name: Name,
@@ -37,25 +38,22 @@ class FirPackageMemberScope(val fqName: FqName, val session: FirSession) : FirSc
}
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
processCallables(name, processor)
val symbols = functionCache.getOrPut(name) {
symbolProvider.getTopLevelFunctionSymbols(fqName, name)
}
for (symbol in symbols) {
symbol.ensureResolvedForCalls(session)
processor(symbol)
}
}
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
processCallables(name, processor)
}
private inline fun <reified D : FirCallableSymbol<*>> processCallables(
name: Name,
processor: (D) -> Unit
) {
val symbols = callableCache.getOrPut(name) {
symbolProvider.getTopLevelCallableSymbols(fqName, name)
val symbols = propertyCache.getOrPut(name) {
symbolProvider.getTopLevelPropertySymbols(fqName, name)
}
for (symbol in symbols) {
if (symbol is D) {
symbol.ensureResolvedForCalls(session)
processor(symbol)
}
symbol.ensureResolvedForCalls(session)
processor(symbol)
}
}
}
@@ -19,9 +19,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirProviderInternals
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
import org.jetbrains.kotlin.fir.scopes.KotlinScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.FirAccessorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
import org.jetbrains.kotlin.idea.fir.low.level.api.PackageExistenceCheckerForSingleModule
@@ -131,6 +129,22 @@ internal class FirIdeProvider(
destination += getTopLevelCallableSymbols(packageFqName, name)
}
override fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List<FirNamedFunctionSymbol> =
providerHelper.getTopLevelFunctionSymbols(packageFqName, name)
@FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
destination += getTopLevelFunctionSymbols(packageFqName, name)
}
override fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List<FirPropertySymbol> =
providerHelper.getTopLevelPropertySymbols(packageFqName, name)
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
destination += getTopLevelPropertySymbols(packageFqName, name)
}
override fun getPackage(fqName: FqName): FqName? =
providerHelper.getPackage(fqName)
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -35,6 +37,22 @@ internal class FirModuleWithDependenciesSymbolProvider(
}
}
@FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
providers.forEach { it.getTopLevelFunctionSymbolsTo(destination, packageFqName, name) }
withDependent {
dependentProviders.forEach { it.getTopLevelFunctionSymbolsTo(destination, packageFqName, name) }
}
}
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
providers.forEach { it.getTopLevelPropertySymbolsTo(destination, packageFqName, name) }
withDependent {
dependentProviders.forEach { it.getTopLevelPropertySymbolsTo(destination, packageFqName, name) }
}
}
override fun getPackage(fqName: FqName): FqName? =
providers.firstNotNullResult { it.getPackage(fqName) }
?: withDependent(default = null) {
@@ -11,6 +11,8 @@ import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.idea.fir.low.level.api.IndexHelper
import org.jetbrains.kotlin.idea.fir.low.level.api.PackageExistenceChecker
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
@@ -67,6 +69,14 @@ internal class FirProviderHelper(
}
}
fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List<FirNamedFunctionSymbol> {
return getTopLevelCallableSymbols(packageFqName, name).filterIsInstance<FirNamedFunctionSymbol>()
}
fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List<FirPropertySymbol> {
return getTopLevelCallableSymbols(packageFqName, name).filterIsInstance<FirPropertySymbol>()
}
private fun FirFile.collectCallableDeclarationsTo(list: MutableList<FirCallableSymbol<*>>, name: Name) {
declarations.mapNotNullTo(list) { declaration ->
if (declaration is FirCallableDeclaration<*> && declaration.symbol.callableId.callableName == name) {
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.PrivateForInline
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -34,11 +36,29 @@ internal class FirThreadSafeSymbolProviderWrapper(private val provider: FirSymbo
provider.getTopLevelCallableSymbols(packageFqName, name)
} ?: emptyList()
override fun getTopLevelFunctionSymbols(packageFqName: FqName, name: Name): List<FirNamedFunctionSymbol> {
return getTopLevelCallableSymbols(packageFqName, name).filterIsInstance<FirNamedFunctionSymbol>()
}
override fun getTopLevelPropertySymbols(packageFqName: FqName, name: Name): List<FirPropertySymbol> {
return getTopLevelCallableSymbols(packageFqName, name).filterIsInstance<FirPropertySymbol>()
}
@FirSymbolProviderInternals
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
error("Should not be called for wrapper")
}
@FirSymbolProviderInternals
override fun getTopLevelFunctionSymbolsTo(destination: MutableList<FirNamedFunctionSymbol>, packageFqName: FqName, name: Name) {
destination += getTopLevelFunctionSymbols(packageFqName, name)
}
@FirSymbolProviderInternals
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
destination += getTopLevelPropertySymbols(packageFqName, name)
}
override fun getPackage(fqName: FqName): FqName? =
packages.getOrCompute(fqName) { provider.getPackage(fqName) }
}