org.jetbrains.kotlin.fir.serialization.FirProvidedDeclarationsForMetadataService.kt Maven / Gradle / Ivy
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
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.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.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.name.FqName
abstract class FirProvidedDeclarationsForMetadataService : FirSessionComponent {
companion object {
fun create(session: FirSession): FirProvidedDeclarationsForMetadataService {
val extensionProviders = session.extensionService.declarationForMetadataProviders
return if (extensionProviders.isEmpty()) Empty else FirProvidedDeclarationsForMetadataServiceImpl(session, extensionProviders)
}
}
abstract fun getProvidedTopLevelDeclarations(packageFqName: FqName, scopeSession: ScopeSession): List
abstract fun getProvidedConstructors(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List
abstract fun getProvidedCallables(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List
abstract fun getProvidedNestedClassifiers(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List>
private object Empty : FirProvidedDeclarationsForMetadataService() {
override fun getProvidedTopLevelDeclarations(packageFqName: FqName, scopeSession: ScopeSession): List {
return emptyList()
}
override fun getProvidedConstructors(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List {
return emptyList()
}
override fun getProvidedCallables(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List {
return emptyList()
}
override fun getProvidedNestedClassifiers(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List> {
return emptyList()
}
}
}
private class FirProvidedDeclarationsForMetadataServiceImpl(
session: FirSession,
private val extensionDeclarationProviders: List
) : FirProvidedDeclarationsForMetadataService() {
private val cachesFactory = session.firCachesFactory
private val topLevelsCache: FirCache, ScopeSession> =
cachesFactory.createCache(::computeTopLevelDeclarations)
private val membersCache: FirCache, ClassDeclarations, ScopeSession> =
cachesFactory.createCache(::computeMemberDeclarations)
private fun computeTopLevelDeclarations(packageFqName: FqName, scopeSession: ScopeSession): List {
return buildList {
for (extensionProvider in extensionDeclarationProviders) {
for (declaration in extensionProvider.provideTopLevelDeclarations(packageFqName, scopeSession)) {
add(declaration)
}
}
}
}
override fun getProvidedTopLevelDeclarations(packageFqName: FqName, scopeSession: ScopeSession): List {
return topLevelsCache.getValue(packageFqName, scopeSession)
}
override fun getProvidedConstructors(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List {
return membersCache.getValue(owner, scopeSession).providedConstructors
}
override fun getProvidedCallables(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List {
return membersCache.getValue(owner, scopeSession).providedCallables
}
override fun getProvidedNestedClassifiers(owner: FirClassSymbol<*>, scopeSession: ScopeSession): List> {
return membersCache.getValue(owner, scopeSession).providedNestedClasses
}
private data class ClassDeclarations(
val providedCallables: List,
val providedConstructors: List,
val providedNestedClasses: List>,
)
private fun computeMemberDeclarations(symbol: FirClassSymbol<*>, scopeSession: ScopeSession): ClassDeclarations {
val providedCallables = mutableListOf()
val providedConstructors = mutableListOf()
val providedNestedClassifiers = mutableListOf>()
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)
}
}
val FirSession.providedDeclarationsForMetadataService: FirProvidedDeclarationsForMetadataService by FirSession.sessionComponentAccessor()
© 2015 - 2024 Weber Informatics LLC | Privacy Policy