[low level api] fix creating libraries session with non-jvm libraries

This commit is contained in:
Ilya Kirillov
2022-04-19 13:17:12 +02:00
parent 3b4eb2d788
commit ee8de63497
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirGlobalResolveCompone
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.api.services.createSealedInheritorsProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.ModuleFileCacheImpl
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.LLFirBuiltinsModuleData
@@ -213,7 +212,6 @@ internal object LLFirSessionFactory {
configureSession: (LLFirSession.() -> Unit)?,
): LLFirLibrariesSession = librariesCache.cached(sourceModule) {
checkCanceled()
val searchScope = project.moduleScopeProvider.getModuleLibrariesScope(sourceModule)
LLFirLibrariesSession(project, builtinTypes).apply session@{
registerModuleData(LLFirKtModuleBasedModuleData(sourceModule).apply { bindSession(this@session) })
registerIdeComponents(project)
@@ -225,32 +223,24 @@ internal object LLFirSessionFactory {
val kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
val moduleDataProvider = createModuleDataProviderWithLibraryDependencies(sourceModule, this)
val packagePartProvider = project.createPackagePartProviderForLibrary(searchScope)
val classFileBasedSymbolProvider = JvmClassFileBasedSymbolProvider(
this@session,
moduleDataProvider = moduleDataProvider,
kotlinScopeProvider = kotlinScopeProvider,
packagePartProvider = packagePartProvider,
kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope),
javaFacade = LLFirJavaFacadeForBinaries(
this@session,
builtinTypes,
project.createJavaClassFinder(searchScope),
moduleDataProvider
)
)
val optionalAnnotationClassesProvider = OptionalAnnotationClassesProvider(
val providers = createProvidersByModulePrimaryDependencies(
this,
moduleDataProvider,
sourceModule,
kotlinScopeProvider,
packagePartProvider
project,
builtinTypes
) { binaryDependencies ->
GlobalSearchScope.union(binaryDependencies.map { it.contentScope })
}
val symbolProvider = FirCompositeSymbolProvider(
this,
buildList {
addAll(providers)
add(builtinsAndCloneableSession.symbolProvider)
}
)
val symbolProvider =
FirCompositeSymbolProvider(
this,
listOf(classFileBasedSymbolProvider, optionalAnnotationClassesProvider, builtinsAndCloneableSession.symbolProvider)
)
register(FirProvider::class, LLFirLibrariesSessionProvider(symbolProvider))
register(FirSymbolProvider::class, symbolProvider)
register(FirJvmTypeMapper::class, FirJvmTypeMapper(this))
@@ -258,28 +248,50 @@ internal object LLFirSessionFactory {
}
}
private fun createModuleDataProviderWithLibraryDependencies(sourceModule: KtModule, session: LLFirSession): ModuleDataProvider {
val regularDependenciesOnLibs =
sourceModule.directRegularDependenciesOfType<KtBinaryModule>().map { LLFirKtModuleBasedModuleData(it) }
val friendDependenciesOnLibs =
sourceModule.directFriendDependenciesOfType<KtBinaryModule>().map { LLFirKtModuleBasedModuleData(it) }
val dependsOnDependenciesOnLibs =
sourceModule.directRefinementDependenciesOfType<KtBinaryModule>().map { LLFirKtModuleBasedModuleData(it) }
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))
}
}
val allDependencies = buildList {
addAll(regularDependenciesOnLibs)
addAll(friendDependenciesOnLibs)
addAll(dependsOnDependenciesOnLibs)
}
private fun createModuleDataProviderWithLibraryDependencies(
sourceModule: KtModule,
binaryDependencies: List<KtBinaryModule>,
session: LLFirSession
): ModuleDataProvider {
val moduleDatas = binaryDependencies.map { LLFirKtModuleBasedModuleData(it) }
if (allDependencies.isEmpty()) {
if (moduleDatas.isEmpty()) {
return EmptyModuleDataProvider(sourceModule.platform, sourceModule.analyzerServices)
}
allDependencies.forEach { it.bindSession(session) }
moduleDatas.forEach { it.bindSession(session) }
val moduleDataWithFilters: Map<FirModuleData, LibraryPathFilter.LibraryList> =
allDependencies.associateWith { moduleData ->
moduleDatas.associateWith { moduleData ->
checkIsInstance<LLFirKtModuleBasedModuleData>(moduleData)
val ktBinaryModule = moduleData.ktModule as KtBinaryModule
val moduleBinaryRoots = ktBinaryModule.getBinaryRoots().mapTo(mutableSetOf()) { it.toAbsolutePath() }
@@ -375,32 +387,8 @@ internal object LLFirSessionFactory {
val dependentProviders = buildList {
val librariesSearchScope = ProjectScope.getLibrariesScope(project)
.intersectWith(GlobalSearchScope.notScope(libraryModule.contentScope)) // <all libraries scope> - <current library scope>
val packagePartProvider = project.createPackagePartProviderForLibrary(librariesSearchScope)
add(builtinsAndCloneableSession.symbolProvider)
val libraryDependenciesModuleDataProvider = createModuleDataProviderWithLibraryDependencies(module, this@session)
add(
JvmClassFileBasedSymbolProvider(
this@session,
moduleDataProvider = libraryDependenciesModuleDataProvider,
kotlinScopeProvider = scopeProvider,
packagePartProvider = packagePartProvider,
kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(librariesSearchScope),
javaFacade = LLFirJavaFacadeForBinaries(
this@session,
builtinTypes,
project.createJavaClassFinder(librariesSearchScope),
libraryDependenciesModuleDataProvider
)
)
)
add(
OptionalAnnotationClassesProvider(
this@session,
moduleDataProvider = libraryDependenciesModuleDataProvider,
kotlinScopeProvider = scopeProvider,
packagePartProvider = packagePartProvider,
)
)
addAll(createProvidersByModulePrimaryDependencies(session, module, scopeProvider, project, builtinTypes) { librariesSearchScope })
}
// We need FirRegisteredPluginAnnotations during extensions' registration process