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