[fir low level] extract library session caching to a separate class
This commit is contained in:
+83
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.low.level.api.fir.project.structure
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createPackagePartProviderForLibrary
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirJavaFacadeForBinaries
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.KtBinaryModule
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.allDirectDependenciesOfType
|
||||||
|
import org.jetbrains.kotlin.analysis.utils.errors.checkIsInstance
|
||||||
|
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||||
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
|
import org.jetbrains.kotlin.fir.deserialization.EmptyModuleDataProvider
|
||||||
|
import org.jetbrains.kotlin.fir.deserialization.LibraryPathFilter
|
||||||
|
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||||
|
import org.jetbrains.kotlin.fir.deserialization.MultipleModuleDataProvider
|
||||||
|
import org.jetbrains.kotlin.fir.java.deserialization.JvmClassFileBasedSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.java.deserialization.OptionalAnnotationClassesProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||||
|
import org.jetbrains.kotlin.load.java.createJavaClassFinder
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||||
|
|
||||||
|
internal object LLFirLibraryProviderFactory {
|
||||||
|
fun createProvidersByModuleLibraryDependencies(
|
||||||
|
session: LLFirSession,
|
||||||
|
module: KtModule,
|
||||||
|
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||||
|
project: Project,
|
||||||
|
builtinTypes: BuiltinTypes,
|
||||||
|
createSearchScopeForModules: (List<KtBinaryModule>) -> GlobalSearchScope
|
||||||
|
): List<FirSymbolProvider> = buildList {
|
||||||
|
module
|
||||||
|
.allDirectDependenciesOfType<KtBinaryModule>()
|
||||||
|
.groupBy { it.platform }
|
||||||
|
.forEach { (_, binaryDependencies) ->
|
||||||
|
val moduleDataProvider = createModuleDataProviderWithLibraryDependencies(module, binaryDependencies, session)
|
||||||
|
val scope = createSearchScopeForModules(binaryDependencies)
|
||||||
|
val packagePartProvider = project.createPackagePartProviderForLibrary(scope)
|
||||||
|
add(
|
||||||
|
JvmClassFileBasedSymbolProvider(
|
||||||
|
session,
|
||||||
|
moduleDataProvider,
|
||||||
|
kotlinScopeProvider,
|
||||||
|
packagePartProvider,
|
||||||
|
VirtualFileFinderFactory.getInstance(project).create(scope),
|
||||||
|
LLFirJavaFacadeForBinaries(session, builtinTypes, project.createJavaClassFinder(scope), moduleDataProvider)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
add(OptionalAnnotationClassesProvider(session, moduleDataProvider, kotlinScopeProvider, packagePartProvider))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createModuleDataProviderWithLibraryDependencies(
|
||||||
|
sourceModule: KtModule,
|
||||||
|
binaryDependencies: List<KtBinaryModule>,
|
||||||
|
session: LLFirSession
|
||||||
|
): ModuleDataProvider {
|
||||||
|
val moduleDatas = binaryDependencies.map { LLFirKtModuleBasedModuleData(it) }
|
||||||
|
|
||||||
|
if (moduleDatas.isEmpty()) {
|
||||||
|
return EmptyModuleDataProvider(sourceModule.platform, sourceModule.analyzerServices)
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleDatas.forEach { it.bindSession(session) }
|
||||||
|
|
||||||
|
val moduleDataWithFilters: Map<FirModuleData, LibraryPathFilter.LibraryList> =
|
||||||
|
moduleDatas.associateWith { moduleData ->
|
||||||
|
checkIsInstance<LLFirKtModuleBasedModuleData>(moduleData)
|
||||||
|
val ktBinaryModule = moduleData.ktModule as KtBinaryModule
|
||||||
|
val moduleBinaryRoots = ktBinaryModule.getBinaryRoots().mapTo(mutableSetOf()) { it.toAbsolutePath() }
|
||||||
|
LibraryPathFilter.LibraryList(moduleBinaryRoots)
|
||||||
|
}
|
||||||
|
|
||||||
|
return MultipleModuleDataProvider(moduleDataWithFilters)
|
||||||
|
}
|
||||||
|
}
|
||||||
+111
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.low.level.api.fir.project.structure
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirBuiltinSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirBuiltinsAndCloneableSessionProvider
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirLibrariesSessionProvider
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirBuiltinsAndCloneableSession
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirLibrariesSession
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||||
|
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||||
|
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||||
|
import org.jetbrains.kotlin.fir.SessionConfiguration
|
||||||
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseCheckingPhaseManager
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||||
|
import org.jetbrains.kotlin.fir.session.registerCommonComponents
|
||||||
|
import org.jetbrains.kotlin.fir.session.registerCommonJavaComponents
|
||||||
|
import org.jetbrains.kotlin.fir.session.registerJavaSpecificResolveComponents
|
||||||
|
import org.jetbrains.kotlin.fir.session.registerModuleData
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.FirPhaseManager
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
@OptIn(PrivateSessionConstructor::class, SessionConfiguration::class)
|
||||||
|
internal class LLFirLibrarySessionFactory(
|
||||||
|
private val project: Project,
|
||||||
|
private val useSiteModule: KtModule,
|
||||||
|
private val useSiteLanguageVersionSettings: LanguageVersionSettings,
|
||||||
|
) {
|
||||||
|
val builtInTypes = BuiltinTypes()
|
||||||
|
val builtinsAndCloneableSession = createBuiltinsAndCloneableSession()
|
||||||
|
|
||||||
|
private val librarySessionByModule = ConcurrentHashMap<KtModule, LLFirLibrariesSession>()
|
||||||
|
|
||||||
|
fun getLibrarySessionForSourceModule(ktModule: KtSourceModule): LLFirLibrariesSession {
|
||||||
|
return librarySessionByModule.getOrPut(ktModule) { createModuleLibrariesSession(ktModule) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createModuleLibrariesSession(
|
||||||
|
sourceModule: KtSourceModule,
|
||||||
|
): LLFirLibrariesSession {
|
||||||
|
return LLFirLibrariesSession(project, builtInTypes).apply session@{
|
||||||
|
registerModuleData(LLFirKtModuleBasedModuleData(sourceModule).apply { bindSession(this@session) })
|
||||||
|
registerIdeComponents(project)
|
||||||
|
register(FirPhaseManager::class, FirPhaseCheckingPhaseManager)
|
||||||
|
registerCommonComponents(sourceModule.languageVersionSettings)
|
||||||
|
registerCommonJavaComponents(JavaModuleResolver.getInstance(project))
|
||||||
|
registerJavaSpecificResolveComponents()
|
||||||
|
|
||||||
|
val kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||||
|
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
|
||||||
|
|
||||||
|
val providers = LLFirLibraryProviderFactory.createProvidersByModuleLibraryDependencies(
|
||||||
|
this,
|
||||||
|
sourceModule,
|
||||||
|
kotlinScopeProvider,
|
||||||
|
project,
|
||||||
|
builtinTypes
|
||||||
|
) { binaryDependencies ->
|
||||||
|
GlobalSearchScope.union(binaryDependencies.map { it.contentScope })
|
||||||
|
}
|
||||||
|
|
||||||
|
val symbolProvider = createCompositeSymbolProvider(this) {
|
||||||
|
addAll(providers)
|
||||||
|
add(builtinsAndCloneableSession.symbolProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
register(FirProvider::class, LLFirLibrariesSessionProvider(symbolProvider))
|
||||||
|
register(FirSymbolProvider::class, symbolProvider)
|
||||||
|
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun createBuiltinsAndCloneableSession(): LLFirBuiltinsAndCloneableSession {
|
||||||
|
return LLFirBuiltinsAndCloneableSession(project, builtInTypes).apply session@{
|
||||||
|
val moduleData = LLFirBuiltinsModuleData(useSiteModule).apply {
|
||||||
|
bindSession(this@session)
|
||||||
|
}
|
||||||
|
registerIdeComponents(project)
|
||||||
|
register(FirPhaseManager::class, FirPhaseCheckingPhaseManager)
|
||||||
|
registerCommonComponents(useSiteLanguageVersionSettings)
|
||||||
|
registerModuleData(moduleData)
|
||||||
|
|
||||||
|
val kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||||
|
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
|
||||||
|
val symbolProvider = createCompositeSymbolProvider(this) {
|
||||||
|
add(LLFirBuiltinSymbolProvider(this@session, moduleData, kotlinScopeProvider))
|
||||||
|
add(FirCloneableSymbolProvider(this@session, moduleData, kotlinScopeProvider))
|
||||||
|
}
|
||||||
|
|
||||||
|
register(FirSymbolProvider::class, symbolProvider)
|
||||||
|
register(FirProvider::class, LLFirBuiltinsAndCloneableSessionProvider(symbolProvider))
|
||||||
|
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 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.low.level.api.fir.project.structure
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.IdeSessionComponents
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createSealedInheritorsProvider
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.fir.caches.FirThreadSafeCachesFactory
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.SessionConfiguration
|
||||||
|
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider
|
||||||
|
|
||||||
|
@OptIn(SessionConfiguration::class)
|
||||||
|
internal fun LLFirSession.registerIdeComponents(project: Project) {
|
||||||
|
register(IdeSessionComponents::class, IdeSessionComponents.create(this))
|
||||||
|
register(FirCachesFactory::class, FirThreadSafeCachesFactory)
|
||||||
|
register(SealedClassInheritorsProvider::class, project.createSealedInheritorsProvider())
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun createCompositeSymbolProvider(
|
||||||
|
session: FirSession,
|
||||||
|
builderAction: MutableList<FirSymbolProvider>.() -> Unit
|
||||||
|
): FirCompositeSymbolProvider =
|
||||||
|
FirCompositeSymbolProvider(session, buildList(builderAction))
|
||||||
+17
-176
@@ -8,56 +8,37 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.sessions
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.search.ProjectScope
|
import com.intellij.psi.search.ProjectScope
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseManager
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.IdeSessionComponents
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirModuleResolveComponents
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createPackagePartProviderForLibrary
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseManager
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.createSealedInheritorsProvider
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.fir.caches.FirThreadSafeCachesFactory
|
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirKtModuleBasedModuleData
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirKtModuleBasedModuleData
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirBuiltinsModuleData
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibraryProviderFactory
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySessionFactory
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.registerIdeComponents
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.*
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.*
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkCanceled
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.*
|
import org.jetbrains.kotlin.analysis.project.structure.*
|
||||||
import org.jetbrains.kotlin.analysis.providers.createAnnotationResolver
|
import org.jetbrains.kotlin.analysis.providers.createAnnotationResolver
|
||||||
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
|
import org.jetbrains.kotlin.analysis.providers.createDeclarationProvider
|
||||||
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
|
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
|
||||||
import org.jetbrains.kotlin.analysis.utils.errors.checkIsInstance
|
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper
|
||||||
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
|
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
|
|
||||||
import org.jetbrains.kotlin.fir.deserialization.EmptyModuleDataProvider
|
|
||||||
import org.jetbrains.kotlin.fir.deserialization.LibraryPathFilter
|
|
||||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
|
||||||
import org.jetbrains.kotlin.fir.deserialization.MultipleModuleDataProvider
|
|
||||||
import org.jetbrains.kotlin.fir.extensions.*
|
import org.jetbrains.kotlin.fir.extensions.*
|
||||||
import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
|
|
||||||
import org.jetbrains.kotlin.fir.java.FirJavaFacadeForSource
|
import org.jetbrains.kotlin.fir.java.FirJavaFacadeForSource
|
||||||
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.java.deserialization.JvmClassFileBasedSymbolProvider
|
|
||||||
import org.jetbrains.kotlin.fir.java.deserialization.OptionalAnnotationClassesProvider
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseCheckingPhaseManager
|
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
|
||||||
import org.jetbrains.kotlin.fir.session.*
|
import org.jetbrains.kotlin.fir.session.*
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirPhaseManager
|
import org.jetbrains.kotlin.fir.symbols.FirPhaseManager
|
||||||
import org.jetbrains.kotlin.load.java.createJavaClassFinder
|
import org.jetbrains.kotlin.load.java.createJavaClassFinder
|
||||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||||
@@ -69,13 +50,11 @@ internal object LLFirSessionFactory {
|
|||||||
fun createSourcesSession(
|
fun createSourcesSession(
|
||||||
project: Project,
|
project: Project,
|
||||||
module: KtSourceModule,
|
module: KtSourceModule,
|
||||||
builtinsAndCloneableSession: LLFirBuiltinsAndCloneableSession,
|
|
||||||
globalResolveComponents: LLFirGlobalResolveComponents,
|
globalResolveComponents: LLFirGlobalResolveComponents,
|
||||||
sessionInvalidator: LLFirSessionInvalidator,
|
sessionInvalidator: LLFirSessionInvalidator,
|
||||||
builtinTypes: BuiltinTypes,
|
|
||||||
sessionsCache: MutableMap<KtModule, LLFirResolvableModuleSession>,
|
sessionsCache: MutableMap<KtModule, LLFirResolvableModuleSession>,
|
||||||
isRootModule: Boolean,
|
isRootModule: Boolean,
|
||||||
librariesCache: LibrariesCache,
|
librariesSessionFactory: LLFirLibrarySessionFactory,
|
||||||
configureSession: (LLFirSession.() -> Unit)? = null
|
configureSession: (LLFirSession.() -> Unit)? = null
|
||||||
): LLFirSourcesSession {
|
): LLFirSourcesSession {
|
||||||
sessionsCache[module]?.let { return it as LLFirSourcesSession }
|
sessionsCache[module]?.let { return it as LLFirSourcesSession }
|
||||||
@@ -96,7 +75,7 @@ internal object LLFirSessionFactory {
|
|||||||
|
|
||||||
val contentScope = module.contentScope
|
val contentScope = module.contentScope
|
||||||
val dependentModules = module.directRegularDependenciesOfType<KtSourceModule>()
|
val dependentModules = module.directRegularDependenciesOfType<KtSourceModule>()
|
||||||
val session = LLFirSourcesSession(module, project, components, builtinTypes)
|
val session = LLFirSourcesSession(module, project, components, librariesSessionFactory.builtInTypes)
|
||||||
sessionsCache[module] = session
|
sessionsCache[module] = session
|
||||||
components.session = session
|
components.session = session
|
||||||
|
|
||||||
@@ -126,28 +105,18 @@ internal object LLFirSessionFactory {
|
|||||||
@OptIn(ExperimentalStdlibApi::class)
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
val dependentProviders = buildList {
|
val dependentProviders = buildList {
|
||||||
add(
|
add(
|
||||||
createModuleLibrariesSession(
|
librariesSessionFactory.getLibrarySessionForSourceModule(module).symbolProvider
|
||||||
module,
|
|
||||||
project,
|
|
||||||
builtinsAndCloneableSession,
|
|
||||||
builtinTypes,
|
|
||||||
librariesCache,
|
|
||||||
languageVersionSettings = languageVersionSettings,
|
|
||||||
configureSession = configureSession,
|
|
||||||
).symbolProvider
|
|
||||||
)
|
)
|
||||||
dependentModules
|
dependentModules
|
||||||
.mapTo(this) {
|
.mapTo(this) {
|
||||||
createSourcesSession(
|
createSourcesSession(
|
||||||
project,
|
project,
|
||||||
it,
|
it,
|
||||||
builtinsAndCloneableSession,
|
|
||||||
globalResolveComponents,
|
globalResolveComponents,
|
||||||
sessionInvalidator,
|
sessionInvalidator,
|
||||||
builtinTypes,
|
|
||||||
sessionsCache,
|
sessionsCache,
|
||||||
isRootModule = false,
|
isRootModule = false,
|
||||||
librariesCache = librariesCache,
|
librariesSessionFactory = librariesSessionFactory,
|
||||||
configureSession = configureSession,
|
configureSession = configureSession,
|
||||||
).symbolProvider
|
).symbolProvider
|
||||||
}
|
}
|
||||||
@@ -210,136 +179,6 @@ internal object LLFirSessionFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createModuleLibrariesSession(
|
|
||||||
sourceModule: KtSourceModule,
|
|
||||||
project: Project,
|
|
||||||
builtinsAndCloneableSession: LLFirBuiltinsAndCloneableSession,
|
|
||||||
builtinTypes: BuiltinTypes,
|
|
||||||
librariesCache: LibrariesCache,
|
|
||||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
|
||||||
configureSession: (LLFirSession.() -> Unit)?,
|
|
||||||
): LLFirLibrariesSession = librariesCache.cached(sourceModule) {
|
|
||||||
checkCanceled()
|
|
||||||
LLFirLibrariesSession(project, builtinTypes).apply session@{
|
|
||||||
registerModuleData(LLFirKtModuleBasedModuleData(sourceModule).apply { bindSession(this@session) })
|
|
||||||
registerIdeComponents(project)
|
|
||||||
register(FirPhaseManager::class, FirPhaseCheckingPhaseManager)
|
|
||||||
registerCommonComponents(languageVersionSettings)
|
|
||||||
registerCommonJavaComponents(JavaModuleResolver.getInstance(project))
|
|
||||||
registerJavaSpecificResolveComponents()
|
|
||||||
|
|
||||||
val kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
|
|
||||||
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
|
|
||||||
|
|
||||||
val providers = createProvidersByModulePrimaryDependencies(
|
|
||||||
this,
|
|
||||||
sourceModule,
|
|
||||||
kotlinScopeProvider,
|
|
||||||
project,
|
|
||||||
builtinTypes
|
|
||||||
) { binaryDependencies ->
|
|
||||||
GlobalSearchScope.union(binaryDependencies.map { it.contentScope })
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val symbolProvider = FirCompositeSymbolProvider(
|
|
||||||
this,
|
|
||||||
buildList {
|
|
||||||
addAll(providers)
|
|
||||||
add(builtinsAndCloneableSession.symbolProvider)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
register(FirProvider::class, LLFirLibrariesSessionProvider(symbolProvider))
|
|
||||||
register(FirSymbolProvider::class, symbolProvider)
|
|
||||||
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
|
|
||||||
configureSession?.invoke(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createProvidersByModulePrimaryDependencies(
|
|
||||||
session: LLFirSession,
|
|
||||||
module: KtModule,
|
|
||||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
|
||||||
project: Project,
|
|
||||||
builtinTypes: BuiltinTypes,
|
|
||||||
createSearchScopeForModules: (List<KtBinaryModule>) -> GlobalSearchScope
|
|
||||||
): List<FirSymbolProvider> = buildList {
|
|
||||||
module
|
|
||||||
.allDirectDependenciesOfType<KtBinaryModule>()
|
|
||||||
.groupBy { it.platform }
|
|
||||||
.forEach { (_, binaryDependencies) ->
|
|
||||||
val moduleDataProvider = createModuleDataProviderWithLibraryDependencies(module, binaryDependencies, session)
|
|
||||||
val scope = createSearchScopeForModules(binaryDependencies)
|
|
||||||
val packagePartProvider = project.createPackagePartProviderForLibrary(scope)
|
|
||||||
add(
|
|
||||||
JvmClassFileBasedSymbolProvider(
|
|
||||||
session,
|
|
||||||
moduleDataProvider,
|
|
||||||
kotlinScopeProvider,
|
|
||||||
packagePartProvider,
|
|
||||||
VirtualFileFinderFactory.getInstance(project).create(scope),
|
|
||||||
LLFirJavaFacadeForBinaries(session, builtinTypes, project.createJavaClassFinder(scope), moduleDataProvider)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
add(OptionalAnnotationClassesProvider(session, moduleDataProvider, kotlinScopeProvider, packagePartProvider))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createModuleDataProviderWithLibraryDependencies(
|
|
||||||
sourceModule: KtModule,
|
|
||||||
binaryDependencies: List<KtBinaryModule>,
|
|
||||||
session: LLFirSession
|
|
||||||
): ModuleDataProvider {
|
|
||||||
val moduleDatas = binaryDependencies.map { LLFirKtModuleBasedModuleData(it) }
|
|
||||||
|
|
||||||
if (moduleDatas.isEmpty()) {
|
|
||||||
return EmptyModuleDataProvider(sourceModule.platform, sourceModule.analyzerServices)
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleDatas.forEach { it.bindSession(session) }
|
|
||||||
|
|
||||||
val moduleDataWithFilters: Map<FirModuleData, LibraryPathFilter.LibraryList> =
|
|
||||||
moduleDatas.associateWith { moduleData ->
|
|
||||||
checkIsInstance<LLFirKtModuleBasedModuleData>(moduleData)
|
|
||||||
val ktBinaryModule = moduleData.ktModule as KtBinaryModule
|
|
||||||
val moduleBinaryRoots = ktBinaryModule.getBinaryRoots().mapTo(mutableSetOf()) { it.toAbsolutePath() }
|
|
||||||
LibraryPathFilter.LibraryList(moduleBinaryRoots)
|
|
||||||
}
|
|
||||||
|
|
||||||
return MultipleModuleDataProvider(moduleDataWithFilters)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createBuiltinsAndCloneableSession(
|
|
||||||
project: Project,
|
|
||||||
builtinTypes: BuiltinTypes,
|
|
||||||
useSiteModule: KtModule,
|
|
||||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
|
||||||
configureSession: (LLFirSession.() -> Unit)? = null,
|
|
||||||
): LLFirBuiltinsAndCloneableSession {
|
|
||||||
return LLFirBuiltinsAndCloneableSession(project, builtinTypes).apply session@{
|
|
||||||
val moduleData = LLFirBuiltinsModuleData(useSiteModule).apply {
|
|
||||||
bindSession(this@session)
|
|
||||||
}
|
|
||||||
registerIdeComponents(project)
|
|
||||||
register(FirPhaseManager::class, FirPhaseCheckingPhaseManager)
|
|
||||||
registerCommonComponents(languageVersionSettings)
|
|
||||||
registerModuleData(moduleData)
|
|
||||||
|
|
||||||
val kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
|
|
||||||
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
|
|
||||||
val symbolProvider = FirCompositeSymbolProvider(
|
|
||||||
this,
|
|
||||||
listOf(
|
|
||||||
LLFirBuiltinSymbolProvider(this, moduleData, kotlinScopeProvider),
|
|
||||||
FirCloneableSymbolProvider(this, moduleData, kotlinScopeProvider),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
register(FirSymbolProvider::class, symbolProvider)
|
|
||||||
register(FirProvider::class, LLFirBuiltinsAndCloneableSessionProvider(symbolProvider))
|
|
||||||
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
|
|
||||||
configureSession?.invoke(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createLibraryOrLibrarySourceResolvableSession(
|
fun createLibraryOrLibrarySourceResolvableSession(
|
||||||
project: Project,
|
project: Project,
|
||||||
@@ -396,7 +235,15 @@ internal object LLFirSessionFactory {
|
|||||||
val librariesSearchScope = ProjectScope.getLibrariesScope(project)
|
val librariesSearchScope = ProjectScope.getLibrariesScope(project)
|
||||||
.intersectWith(GlobalSearchScope.notScope(libraryModule.contentScope)) // <all libraries scope> - <current library scope>
|
.intersectWith(GlobalSearchScope.notScope(libraryModule.contentScope)) // <all libraries scope> - <current library scope>
|
||||||
add(builtinsAndCloneableSession.symbolProvider)
|
add(builtinsAndCloneableSession.symbolProvider)
|
||||||
addAll(createProvidersByModulePrimaryDependencies(session, module, scopeProvider, project, builtinTypes) { librariesSearchScope })
|
addAll(
|
||||||
|
LLFirLibraryProviderFactory.createProvidersByModuleLibraryDependencies(
|
||||||
|
session,
|
||||||
|
module,
|
||||||
|
scopeProvider,
|
||||||
|
project,
|
||||||
|
builtinTypes
|
||||||
|
) { librariesSearchScope }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need FirRegisteredPluginAnnotations during extensions' registration process
|
// We need FirRegisteredPluginAnnotations during extensions' registration process
|
||||||
@@ -436,12 +283,6 @@ internal object LLFirSessionFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun LLFirSession.registerIdeComponents(project: Project) {
|
|
||||||
register(IdeSessionComponents::class, IdeSessionComponents.create(this))
|
|
||||||
register(FirCachesFactory::class, FirThreadSafeCachesFactory)
|
|
||||||
register(SealedClassInheritorsProvider::class, project.createSealedInheritorsProvider())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<KtModule>.extractLibraryPaths(): List<Path> =
|
private fun List<KtModule>.extractLibraryPaths(): List<Path> =
|
||||||
|
|||||||
+25
-17
@@ -11,7 +11,7 @@ import kotlinx.collections.immutable.PersistentMap
|
|||||||
import kotlinx.collections.immutable.persistentMapOf
|
import kotlinx.collections.immutable.persistentMapOf
|
||||||
import kotlinx.collections.immutable.toPersistentMap
|
import kotlinx.collections.immutable.toPersistentMap
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveComponents
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirPhaseRunner
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySessionFactory
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.firKtModuleBasedModuleData
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.firKtModuleBasedModuleData
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.addValueFor
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.addValueFor
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.executeWithoutPCE
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.executeWithoutPCE
|
||||||
@@ -20,56 +20,64 @@ import org.jetbrains.kotlin.analysis.providers.createLibrariesModificationTracke
|
|||||||
import org.jetbrains.kotlin.analysis.providers.createModuleWithoutDependenciesOutOfBlockModificationTracker
|
import org.jetbrains.kotlin.analysis.providers.createModuleWithoutDependenciesOutOfBlockModificationTracker
|
||||||
import org.jetbrains.kotlin.analysis.utils.caches.getValue
|
import org.jetbrains.kotlin.analysis.utils.caches.getValue
|
||||||
import org.jetbrains.kotlin.analysis.utils.caches.softCachedValue
|
import org.jetbrains.kotlin.analysis.utils.caches.softCachedValue
|
||||||
|
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||||
import org.jetbrains.kotlin.fir.BuiltinTypes
|
import org.jetbrains.kotlin.fir.BuiltinTypes
|
||||||
import org.jetbrains.kotlin.fir.FirSessionProvider
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
class LLFirSessionProviderStorage(val project: Project) {
|
class LLFirSessionProviderStorage(val project: Project) {
|
||||||
private val sessionsCache = ConcurrentHashMap<KtModule, FromModuleViewSessionCache>()
|
private val sessionsCache = ConcurrentHashMap<KtModule, FromModuleViewSessionCache>()
|
||||||
|
|
||||||
private val librariesCache by softCachedValue(project, project.createLibrariesModificationTracker()) { LibrariesCache() }
|
private val librariesFactoryByUseSiteModule by softCachedValue(project, project.createLibrariesModificationTracker()) {
|
||||||
|
ConcurrentHashMap<KtModule, LLFirLibrarySessionFactory>()
|
||||||
|
}
|
||||||
|
|
||||||
fun getSessionProvider(
|
fun getSessionProvider(
|
||||||
rootModule: KtModule,
|
useSiteKtModule: KtModule,
|
||||||
configureSession: (LLFirSession.() -> Unit)? = null
|
configureSession: (LLFirSession.() -> Unit)? = null
|
||||||
): LLFirSessionProvider {
|
): LLFirSessionProvider {
|
||||||
val globalComponents = LLFirGlobalResolveComponents(rootModule, project)
|
val globalComponents = LLFirGlobalResolveComponents(useSiteKtModule, project)
|
||||||
|
|
||||||
val builtinTypes = BuiltinTypes()
|
val librariesSessionFactory = librariesFactoryByUseSiteModule.getOrPut(useSiteKtModule) {
|
||||||
|
val languageVersionSettings = when (useSiteKtModule) {
|
||||||
|
is KtSourceModule -> useSiteKtModule.languageVersionSettings
|
||||||
|
is KtLibraryModule, is KtLibrarySourceModule -> LanguageVersionSettingsImpl.DEFAULT
|
||||||
|
else -> unexpectedElementError("module", useSiteKtModule)
|
||||||
|
}
|
||||||
|
LLFirLibrarySessionFactory(project, useSiteKtModule, languageVersionSettings)
|
||||||
|
}
|
||||||
|
|
||||||
val builtinsAndCloneableSession = LLFirSessionFactory.createBuiltinsAndCloneableSession(project, builtinTypes, rootModule)
|
val cache = sessionsCache.getOrPut(useSiteKtModule) { FromModuleViewSessionCache() }
|
||||||
val cache = sessionsCache.getOrPut(rootModule) { FromModuleViewSessionCache() }
|
|
||||||
val (sessions, session) = cache.withMappings(project) { mappings ->
|
val (sessions, session) = cache.withMappings(project) { mappings ->
|
||||||
val sessions = mutableMapOf<KtModule, LLFirResolvableModuleSession>().apply { putAll(mappings) }
|
val sessions = mutableMapOf<KtModule, LLFirResolvableModuleSession>().apply { putAll(mappings) }
|
||||||
val session = executeWithoutPCE {
|
val session = executeWithoutPCE {
|
||||||
when (rootModule) {
|
when (useSiteKtModule) {
|
||||||
is KtSourceModule -> {
|
is KtSourceModule -> {
|
||||||
LLFirSessionFactory.createSourcesSession(
|
LLFirSessionFactory.createSourcesSession(
|
||||||
project,
|
project,
|
||||||
rootModule,
|
useSiteKtModule,
|
||||||
builtinsAndCloneableSession,
|
|
||||||
globalComponents,
|
globalComponents,
|
||||||
cache.sessionInvalidator,
|
cache.sessionInvalidator,
|
||||||
builtinTypes,
|
|
||||||
sessions,
|
sessions,
|
||||||
isRootModule = true,
|
isRootModule = true,
|
||||||
librariesCache = librariesCache,
|
librariesSessionFactory = librariesSessionFactory,
|
||||||
configureSession = configureSession,
|
configureSession = configureSession,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is KtLibraryModule, is KtLibrarySourceModule -> {
|
is KtLibraryModule, is KtLibrarySourceModule -> {
|
||||||
LLFirSessionFactory.createLibraryOrLibrarySourceResolvableSession(
|
LLFirSessionFactory.createLibraryOrLibrarySourceResolvableSession(
|
||||||
project,
|
project,
|
||||||
rootModule,
|
useSiteKtModule,
|
||||||
builtinsAndCloneableSession,
|
librariesSessionFactory.builtinsAndCloneableSession,
|
||||||
globalComponents,
|
globalComponents,
|
||||||
cache.sessionInvalidator,
|
cache.sessionInvalidator,
|
||||||
builtinTypes,
|
librariesSessionFactory.builtInTypes,
|
||||||
sessions,
|
sessions,
|
||||||
configureSession = configureSession,
|
configureSession = configureSession,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> error("Unexpected ${rootModule::class.simpleName}")
|
else -> error("Unexpected ${useSiteKtModule::class.simpleName}")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 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.low.level.api.fir.sessions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
|
||||||
|
|
||||||
@JvmInline
|
|
||||||
internal value class LibrariesCache(
|
|
||||||
private val cache: ConcurrentHashMap<KtModule, LLFirLibrariesSession> = ConcurrentHashMap()
|
|
||||||
) {
|
|
||||||
fun cached(
|
|
||||||
module: KtModule,
|
|
||||||
create: (KtModule) -> LLFirLibrariesSession
|
|
||||||
): LLFirLibrariesSession =
|
|
||||||
cache.computeIfAbsent(module, create)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user