All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.kotlin.analysis.api.fir.KaFirSession.kt Maven / Gradle / Ivy

/*
 * Copyright 2010-2024 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.analysis.api.fir

import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.api.fir.components.*
import org.jetbrains.kotlin.analysis.api.fir.symbols.KaFirSymbolProvider
import org.jetbrains.kotlin.analysis.api.impl.base.KaBaseSession
import org.jetbrains.kotlin.analysis.api.impl.base.components.KaAnalysisScopeProviderImpl
import org.jetbrains.kotlin.analysis.api.impl.base.components.KaRendererImpl
import org.jetbrains.kotlin.analysis.api.impl.base.sessions.KaGlobalSearchScope
import org.jetbrains.kotlin.analysis.api.impl.base.util.createSession
import org.jetbrains.kotlin.analysis.api.lifetime.KaLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.platform.declarations.KotlinCompositeDeclarationProvider
import org.jetbrains.kotlin.analysis.api.platform.declarations.KotlinDeclarationProvider
import org.jetbrains.kotlin.analysis.api.platform.declarations.createDeclarationProvider
import org.jetbrains.kotlin.analysis.api.platform.packages.KotlinCompositePackageProvider
import org.jetbrains.kotlin.analysis.api.platform.packages.KotlinPackageProvider
import org.jetbrains.kotlin.analysis.api.platform.packages.createPackageProvider
import org.jetbrains.kotlin.analysis.api.projectStructure.KaModule
import org.jetbrains.kotlin.analysis.api.projectStructure.allDirectDependencies
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.LLFirResolveExtensionTool
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.llResolveExtensionTool
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.utils.addIfNotNull

/**
 * The lifetime and validity of a cached [KaFirSession] depends on the lifetime of the underlying
 * [LLFirSession][org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession]. This requires the [KaFirSession] to keep a
 * strong reference to the `LLFirSession`. See the documentation of [LLFirSession][org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession]
 * for more information.
 */
@Suppress("AnalysisApiMissingLifetimeCheck")
internal class KaFirSession
private constructor(
    val project: Project,
    val firResolveSession: LLFirResolveSession,
    val extensionTools: List,
    token: KaLifetimeToken,
    analysisSessionProvider: () -> KaFirSession,
    useSiteScope: KaGlobalSearchScope
) : KaBaseSession(
    token,
    resolver = KaFirResolver(analysisSessionProvider),
    symbolRelationProvider = KaFirSymbolRelationProvider(analysisSessionProvider),
    diagnosticProvider = KaFirDiagnosticProvider(analysisSessionProvider),
    scopeProvider = KaFirScopeProvider(analysisSessionProvider),
    completionCandidateChecker = KaFirCompletionCandidateChecker(analysisSessionProvider),
    expressionTypeProvider = KaFirExpressionTypeProvider(analysisSessionProvider),
    typeProvider = KaFirTypeProvider(analysisSessionProvider),
    typeInformationProvider = KaFirTypeInformationProvider(analysisSessionProvider),
    symbolProvider = KaFirSymbolProvider(analysisSessionProvider, firResolveSession.useSiteFirSession.symbolProvider),
    javaInteroperabilityComponent = KaFirJavaInteroperabilityComponent(analysisSessionProvider),
    symbolInformationProvider = KaFirSymbolInformationProvider(analysisSessionProvider),
    typeRelationChecker = KaFirTypeRelationChecker(analysisSessionProvider),
    expressionInformationProvider = KaFirExpressionInformationProvider(analysisSessionProvider),
    evaluator = KaFirEvaluator(analysisSessionProvider),
    referenceShortener = KaFirReferenceShortener(analysisSessionProvider),
    importOptimizer = KaFirImportOptimizer(analysisSessionProvider),
    renderer = KaRendererImpl(analysisSessionProvider),
    visibilityChecker = KaFirVisibilityChecker(analysisSessionProvider),
    originalPsiProvider = KaFirOriginalPsiProvider(analysisSessionProvider),
    typeCreator = KaFirTypeCreator(analysisSessionProvider),
    analysisScopeProvider = KaAnalysisScopeProviderImpl(analysisSessionProvider, useSiteScope),
    signatureSubstitutor = KaFirSignatureSubstitutor(analysisSessionProvider),
    resolveExtensionInfoProvider = KaFirResolveExtensionInfoProvider(analysisSessionProvider),
    compilerPluginGeneratedDeclarationsProvider = KaFirCompilerPluginGeneratedDeclarationsProvider(analysisSessionProvider),
    compilerFacility = KaFirCompilerFacility(analysisSessionProvider),
    metadataCalculator = KaFirMetadataCalculator(analysisSessionProvider),
    substitutorProvider = KaFirSubstitutorProvider(analysisSessionProvider),
    dataFlowProvider = KaFirDataFlowProvider(analysisSessionProvider),
    sourceProvider = KaFirSourceProvider(analysisSessionProvider)
) {
    internal val firSymbolBuilder: KaSymbolByFirBuilder by lazy {
        KaSymbolByFirBuilder(project, this, token)
    }

    @Suppress("AnalysisApiMissingLifetimeCheck")
    override val useSiteModule: KaModule get() = firResolveSession.useSiteKtModule

    internal val firSession: LLFirSession get() = firResolveSession.useSiteFirSession
    internal val targetPlatform: TargetPlatform get() = firSession.moduleData.platform

    val useSiteScopeDeclarationProvider: KotlinDeclarationProvider
    val useSitePackageProvider: KotlinPackageProvider


    init {
        useSiteScopeDeclarationProvider = KotlinCompositeDeclarationProvider.create(
            buildList {
                add(project.createDeclarationProvider(useSiteScope, useSiteModule))
                extensionTools.mapTo(this) { it.declarationProvider }
            }
        )

        useSitePackageProvider = KotlinCompositePackageProvider.create(
            buildList {
                add(project.createPackageProvider(useSiteScope))
                extensionTools.mapTo(this) { it.packageProvider }
            }
        )
    }

    fun getScopeSessionFor(session: FirSession): ScopeSession = withValidityAssertion { firResolveSession.getScopeSessionFor(session) }

    companion object {
        internal fun createAnalysisSessionByFirResolveSession(
            firResolveSession: LLFirResolveSession,
            token: KaLifetimeToken,
        ): KaFirSession {
            val useSiteModule = firResolveSession.useSiteKtModule
            val useSiteSession = firResolveSession.useSiteFirSession

            val extensionTools = buildList {
                addIfNotNull(useSiteSession.llResolveExtensionTool)
                useSiteModule.allDirectDependencies().mapNotNullTo(this) { dependency ->
                    firResolveSession.getSessionFor(dependency).llResolveExtensionTool
                }
            }

            val shadowedScope = GlobalSearchScope.union(
                buildSet {
                    // Add an empty scope to the shadowed set to give GlobalSearchScope.union something
                    // to work with if there are no extension tools.
                    // If there are extension tools, any empty scopes, whether from shadowedSearchScope
                    // on the extension tools or from this add() call, will be ignored.
                    add(GlobalSearchScope.EMPTY_SCOPE)
                    extensionTools.mapTo(this) { it.shadowedSearchScope }
                }
            )

            val resolutionScope = KaGlobalSearchScope(shadowedScope, useSiteModule)

            return createSession {
                KaFirSession(
                    firResolveSession.project,
                    firResolveSession,
                    extensionTools,
                    token,
                    analysisSessionProvider,
                    resolutionScope
                )
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy