[low level fir] create separate FirModuleData for every library module dependency

This commit is contained in:
Ilya Kirillov
2022-04-07 08:19:44 +02:00
parent e69fa1ae07
commit 252d8e283b
6 changed files with 40 additions and 61 deletions
@@ -6,12 +6,13 @@
package org.jetbrains.kotlin.analysis.api.standalone.base.project.structure package org.jetbrains.kotlin.analysis.api.standalone.base.project.structure
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.project.structure.KtLibraryModule import org.jetbrains.kotlin.analysis.project.structure.*
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
import org.jetbrains.kotlin.psi.psiUtil.contains import org.jetbrains.kotlin.psi.psiUtil.contains
class KtStaticModuleProvider(private val modules: List<KtModule>) : ProjectStructureProvider() { class KtStaticModuleProvider(
private val modules: List<KtModule>,
private val stdlibs: Set<KtModule>
) : ProjectStructureProvider() {
override fun getKtModuleForKtElement(element: PsiElement): KtModule { override fun getKtModuleForKtElement(element: PsiElement): KtModule {
return modules.first { module -> return modules.first { module ->
module.contentScope.contains(element) module.contentScope.contains(element)
@@ -19,6 +20,10 @@ class KtStaticModuleProvider(private val modules: List<KtModule>) : ProjectStruc
} }
override fun getKtLibraryModules(): Collection<KtLibraryModule> { override fun getKtLibraryModules(): Collection<KtLibraryModule> {
return modules.filterIsInstance<KtLibraryModule>() return modules.filterIsInstance<KtLibraryModule>()
}
override fun getStdlibModule(module: KtModule): KtLibraryModule? {
return module.allDirectDependenciesOfType<KtLibraryModule>().firstOrNull { it in stdlibs }
} }
} }
@@ -55,7 +55,7 @@ object StandaloneProjectFactory {
KotlinCoreEnvironment.registerProjectExtensionPoints(project.extensionArea) KotlinCoreEnvironment.registerProjectExtensionPoints(project.extensionArea)
KotlinCoreEnvironment.registerProjectServices(project) KotlinCoreEnvironment.registerProjectServices(project)
project.registerService(ProjectStructureProvider::class.java, KtStaticModuleProvider(modules.map { it.ktModule })) project.registerService(ProjectStructureProvider::class.java, KtStaticModuleProvider(modules.map { it.ktModule }, emptySet()))
initialiseVirtualFinderFinderServices(modules, environment, jdkHome, languageVersionSettings) initialiseVirtualFinderFinderServices(modules, environment, jdkHome, languageVersionSettings)
initialiseAnnotationServices(project) initialiseAnnotationServices(project)
@@ -1,40 +0,0 @@
/*
* 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.api.standalone
import com.intellij.openapi.Disposable
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.api.fir.test.configurators.source.AnalysisApiFirSourceTestConfigurator
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
object StandaloneModeConfigurator : AnalysisApiTestConfigurator() {
override val analyseInDependentSession: Boolean get() = false
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).configureTest(builder, disposable)
}
override val serviceRegistrars: List<AnalysisApiTestServiceRegistrar>
get() = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).serviceRegistrars
override fun createModules(
moduleStructure: TestModuleStructure,
testServices: TestServices,
project: Project
): List<KtModuleWithFiles> {
return AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).createModules(moduleStructure, testServices, project)
}
override fun doOutOfBlockModification(file: KtFile) {
AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).doOutOfBlockModification(file)
}
}
@@ -30,7 +30,7 @@ object StandaloneModeConfigurator : AnalysisApiTestConfigurator() {
moduleStructure: TestModuleStructure, moduleStructure: TestModuleStructure,
testServices: TestServices, testServices: TestServices,
project: Project project: Project
): List<KtModuleWithFiles> { ): KtModuleProjectStructure {
return AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).createModules(moduleStructure, testServices, project) return AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).createModules(moduleStructure, testServices, project)
} }
@@ -32,7 +32,9 @@ import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
import org.jetbrains.kotlin.fir.deserialization.LibraryPathFilter
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
import org.jetbrains.kotlin.fir.deserialization.MultipleModuleDataProvider
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.extensions.FirPredicateBasedProvider import org.jetbrains.kotlin.fir.extensions.FirPredicateBasedProvider
import org.jetbrains.kotlin.fir.extensions.FirRegisteredPluginAnnotations import org.jetbrains.kotlin.fir.extensions.FirRegisteredPluginAnnotations
@@ -225,9 +227,10 @@ internal object LLFirSessionFactory {
val mainModuleData = KtModuleBasedModuleData(sourceModule).apply { bindSession(this@session) } val mainModuleData = KtModuleBasedModuleData(sourceModule).apply { bindSession(this@session) }
val moduleDataProvider = createModuleDataProviderWithLibraryDependencies(sourceModule, this)
val classFileBasedSymbolProvider = JvmClassFileBasedSymbolProvider( val classFileBasedSymbolProvider = JvmClassFileBasedSymbolProvider(
this@session, this@session,
moduleDataProvider = createModuleDataProvider(sourceModule, this), moduleDataProvider = moduleDataProvider,
kotlinScopeProvider = kotlinScopeProvider, kotlinScopeProvider = kotlinScopeProvider,
packagePartProvider = project.createPackagePartProviderForLibrary(searchScope), packagePartProvider = project.createPackagePartProviderForLibrary(searchScope),
kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope), kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope),
@@ -244,19 +247,28 @@ internal object LLFirSessionFactory {
} }
} }
private fun createModuleDataProvider(sourceModule: KtModule, session: LLFirSession): ModuleDataProvider { private fun createModuleDataProviderWithLibraryDependencies(sourceModule: KtModule, session: LLFirSession): ModuleDataProvider {
val dependencyList = DependencyListForCliModule.build( val regularDependenciesOnLibs =
Name.special("<${sourceModule.moduleDescription}>"), sourceModule.directRegularDependenciesOfType<KtBinaryModule>().map { KtModuleBasedModuleData(it) }
sourceModule.platform, val friendDependenciesOnLibs =
sourceModule.analyzerServices sourceModule.directFriendDependenciesOfType<KtBinaryModule>().map { KtModuleBasedModuleData(it) }
) { val dependsOnDependenciesOnLibs =
dependencies(sourceModule.directRegularDependencies.extractLibraryPaths()) sourceModule.directRefinementDependenciesOfType<KtBinaryModule>().map { KtModuleBasedModuleData(it) }
friendDependencies(sourceModule.directFriendDependencies.extractLibraryPaths())
dependsOnDependencies(sourceModule.directRefinementDependencies.extractLibraryPaths()) val allDependencies = buildList {
} addAll(regularDependenciesOnLibs)
return dependencyList.moduleDataProvider.apply { addAll(friendDependenciesOnLibs)
allModuleData.forEach { it.bindSession(session) } addAll(dependsOnDependenciesOnLibs)
} }
allDependencies.forEach { it.bindSession(session) }
val moduleDataWithFilters: Map<FirModuleData, LibraryPathFilter.LibraryList> =
allDependencies.associateWith { moduleData ->
LibraryPathFilter.LibraryList((moduleData.module as KtBinaryModule).getBinaryRoots().toSet())
}
return MultipleModuleDataProvider(moduleDataWithFilters)
} }
fun createBuiltinsAndCloneableSession( fun createBuiltinsAndCloneableSession(
@@ -360,7 +372,7 @@ internal object LLFirSessionFactory {
add( add(
JvmClassFileBasedSymbolProvider( JvmClassFileBasedSymbolProvider(
this@session, this@session,
moduleDataProvider = createModuleDataProvider(module, this@session), moduleDataProvider = createModuleDataProviderWithLibraryDependencies(module, this@session),
kotlinScopeProvider = scopeProvider, kotlinScopeProvider = scopeProvider,
packagePartProvider = project.createPackagePartProviderForLibrary(librariesSearchScope), packagePartProvider = project.createPackagePartProviderForLibrary(librariesSearchScope),
kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(librariesSearchScope), kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(librariesSearchScope),
@@ -19,6 +19,8 @@ public abstract class ProjectStructureProvider {
*/ */
// TODO: We rather need a session or facade that maintains this information. // TODO: We rather need a session or facade that maintains this information.
public abstract fun getKtLibraryModules(): Collection<KtLibraryModule> public abstract fun getKtLibraryModules(): Collection<KtLibraryModule>
public abstract fun getStdlibModule(module: KtModule): KtLibraryModule?
} }
/** /**