[IR] Introduce API to register generated IR declaration to be present in metatada
KT-63881
This commit is contained in:
+33
-43
@@ -7,17 +7,18 @@ package org.jetbrains.kotlin.fir.serialization
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||
import org.jetbrains.kotlin.fir.caches.FirCache
|
||||
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.extensions.FirDeclarationsForMetadataProviderExtension
|
||||
import org.jetbrains.kotlin.fir.extensions.declarationForMetadataProviders
|
||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.getOrPut
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
|
||||
|
||||
abstract class FirProvidedDeclarationsForMetadataService : FirSessionComponent {
|
||||
companion object {
|
||||
@@ -32,6 +33,8 @@ abstract class FirProvidedDeclarationsForMetadataService : FirSessionComponent {
|
||||
abstract fun getProvidedCallables(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List<FirCallableDeclaration>
|
||||
abstract fun getProvidedNestedClassifiers(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List<FirClassLikeSymbol<*>>
|
||||
|
||||
abstract fun registerDeclaration(declaration: FirCallableDeclaration)
|
||||
|
||||
private object Empty : FirProvidedDeclarationsForMetadataService() {
|
||||
override fun getProvidedTopLevelDeclarations(packageFqName: FqName, scopeSession: ScopeSession): List<FirDeclaration> {
|
||||
return emptyList()
|
||||
@@ -48,70 +51,57 @@ abstract class FirProvidedDeclarationsForMetadataService : FirSessionComponent {
|
||||
override fun getProvidedNestedClassifiers(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List<FirClassLikeSymbol<*>> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun registerDeclaration(declaration: FirCallableDeclaration) {
|
||||
shouldNotBeCalled()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FirProvidedDeclarationsForMetadataServiceImpl(
|
||||
session: FirSession,
|
||||
private val session: FirSession,
|
||||
private val extensionDeclarationProviders: List<FirDeclarationsForMetadataProviderExtension>
|
||||
) : FirProvidedDeclarationsForMetadataService() {
|
||||
private val cachesFactory = session.firCachesFactory
|
||||
private val topLevelsCache: MutableMap<FqName, MutableList<FirDeclaration>> =
|
||||
mutableMapOf()
|
||||
|
||||
private val topLevelsCache: FirCache<FqName, List<FirDeclaration>, ScopeSession> =
|
||||
cachesFactory.createCache(::computeTopLevelDeclarations)
|
||||
private val memberCache: MutableMap<FirClassSymbol<*>, ClassDeclarations> =
|
||||
mutableMapOf()
|
||||
|
||||
private val membersCache: FirCache<FirClassSymbol<*>, ClassDeclarations, ScopeSession> =
|
||||
cachesFactory.createCache(::computeMemberDeclarations)
|
||||
|
||||
private fun computeTopLevelDeclarations(packageFqName: FqName, scopeSession: ScopeSession): List<FirDeclaration> {
|
||||
return buildList {
|
||||
for (extensionProvider in extensionDeclarationProviders) {
|
||||
for (declaration in extensionProvider.provideTopLevelDeclarations(packageFqName, scopeSession)) {
|
||||
add(declaration)
|
||||
}
|
||||
override fun registerDeclaration(declaration: FirCallableDeclaration) {
|
||||
val containingClass = declaration.containingClassLookupTag()?.toFirRegularClass(session)
|
||||
if (containingClass == null) {
|
||||
val list = topLevelsCache.getOrPut(declaration.symbol.callableId.packageName) { mutableListOf() }
|
||||
list += declaration
|
||||
} else {
|
||||
val declarations = memberCache.getOrPut(containingClass.symbol) { ClassDeclarations() }
|
||||
when (declaration) {
|
||||
is FirConstructor -> declarations.providedConstructors += declaration
|
||||
else -> declarations.providedCallables += declaration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getProvidedTopLevelDeclarations(packageFqName: FqName, scopeSession: ScopeSession): List<FirDeclaration> {
|
||||
return topLevelsCache.getValue(packageFqName, scopeSession)
|
||||
return topLevelsCache[packageFqName] ?: emptyList()
|
||||
}
|
||||
|
||||
override fun getProvidedConstructors(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List<FirConstructor> {
|
||||
return membersCache.getValue(owner, scopeSession).providedConstructors
|
||||
return memberCache[owner]?.providedConstructors ?: emptyList()
|
||||
}
|
||||
|
||||
override fun getProvidedCallables(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List<FirCallableDeclaration> {
|
||||
return membersCache.getValue(owner, scopeSession).providedCallables
|
||||
return memberCache[owner]?.providedCallables ?: emptyList()
|
||||
}
|
||||
|
||||
override fun getProvidedNestedClassifiers(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List<FirClassLikeSymbol<*>> {
|
||||
return membersCache.getValue(owner, scopeSession).providedNestedClasses
|
||||
// TODO: remove
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
private data class ClassDeclarations(
|
||||
val providedCallables: List<FirCallableDeclaration>,
|
||||
val providedConstructors: List<FirConstructor>,
|
||||
val providedNestedClasses: List<FirClassLikeSymbol<*>>,
|
||||
)
|
||||
|
||||
private fun computeMemberDeclarations(symbol: FirClassSymbol<*>, scopeSession: ScopeSession): ClassDeclarations {
|
||||
val providedCallables = mutableListOf<FirCallableDeclaration>()
|
||||
val providedConstructors = mutableListOf<FirConstructor>()
|
||||
val providedNestedClassifiers = mutableListOf<FirClassLikeSymbol<*>>()
|
||||
|
||||
for (extensionProvider in extensionDeclarationProviders) {
|
||||
for (declaration in extensionProvider.provideDeclarationsForClass(symbol.fir, scopeSession)) {
|
||||
when (declaration) {
|
||||
is FirConstructor -> providedConstructors += declaration
|
||||
is FirCallableDeclaration -> providedCallables += declaration
|
||||
is FirClassLikeDeclaration -> providedNestedClassifiers += declaration.symbol
|
||||
else -> error("Unsupported declaration type in: $symbol ${declaration.render()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ClassDeclarations(providedCallables, providedConstructors, providedNestedClassifiers)
|
||||
private class ClassDeclarations {
|
||||
val providedCallables: MutableList<FirCallableDeclaration> = mutableListOf()
|
||||
val providedConstructors: MutableList<FirConstructor> = mutableListOf()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user