[FIR] Refactor deserialized dependency providers and session factories with FirModuleData
This commit is contained in:
committed by
TeamCityServer
parent
24f1f7b7b2
commit
02c58b7a8f
+2
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
@@ -30,6 +31,7 @@ abstract class AbstractFirLoadCompiledKotlin : AbstractFirLoadBinariesTest() {
|
||||
return createEnvironmentWithMockJdk(ConfigurationKind.JDK_NO_RUNTIME)
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTestInfrastructure::class)
|
||||
fun doTest(path: String) {
|
||||
val moduleDescriptor = compileKtFileToTmpDir(path)
|
||||
|
||||
|
||||
+2
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir
|
||||
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.serialization.builtins.BuiltinsTestUtils
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
@@ -16,6 +17,7 @@ class BuiltInsDeserializationForFirTestCase : AbstractFirLoadBinariesTest() {
|
||||
return createEnvironmentWithJdk(ConfigurationKind.ALL, TestJdkKind.FULL_JDK)
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTestInfrastructure::class)
|
||||
fun testBuiltInPackagesContent() {
|
||||
val moduleDescriptor = BuiltinsTestUtils.compileBuiltinsModule(environment)
|
||||
val session = createSessionForTests(environment, GlobalSearchScope.allScope(project))
|
||||
|
||||
+2
@@ -16,6 +16,7 @@ import com.intellij.psi.PsiPackageStatement
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.testFramework.LightVirtualFile
|
||||
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
@@ -82,6 +83,7 @@ abstract class AbstractFirTypeEnhancementTest : KtUsefulTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTestInfrastructure::class)
|
||||
fun doTest(path: String) {
|
||||
val javaFile = File(path)
|
||||
val javaLines = javaFile.readLines()
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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
|
||||
|
||||
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.deserialization.SingleModuleDataProvider
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
|
||||
class DependencyListForCliModule(
|
||||
val platform: TargetPlatform,
|
||||
val analyzerServices: PlatformDependentAnalyzerServices,
|
||||
val regularDependencies: List<FirModuleData>,
|
||||
val dependsOnDependencies: List<FirModuleData>,
|
||||
val friendsDependencies: List<FirModuleData>,
|
||||
val moduleDataProvider: ModuleDataProvider,
|
||||
) {
|
||||
companion object {
|
||||
fun createDependencyModuleData(
|
||||
name: Name,
|
||||
platform: TargetPlatform,
|
||||
analyzerServices: PlatformDependentAnalyzerServices
|
||||
): FirModuleData {
|
||||
return FirModuleDataImpl(
|
||||
name,
|
||||
dependencies = emptyList(),
|
||||
dependsOnDependencies = emptyList(),
|
||||
friendDependencies = emptyList(),
|
||||
platform,
|
||||
analyzerServices,
|
||||
)
|
||||
}
|
||||
|
||||
inline fun build(
|
||||
mainModuleName: Name,
|
||||
platform: TargetPlatform,
|
||||
analyzerServices: PlatformDependentAnalyzerServices,
|
||||
init: Builder.() -> Unit = {}
|
||||
): DependencyListForCliModule {
|
||||
return Builder(mainModuleName, platform, analyzerServices).apply(init).build()
|
||||
}
|
||||
}
|
||||
|
||||
class Builder(val mainModuleName: Name, val platform: TargetPlatform, val analyzerServices: PlatformDependentAnalyzerServices) {
|
||||
private fun createData(name: String): FirModuleData = createDependencyModuleData(Name.special(name), platform, analyzerServices)
|
||||
|
||||
private val binaryRegularDependenciesModuleData: FirModuleData = createData("<regular dependencies of $mainModuleName>")
|
||||
private val binaryDependsOnModuleData: FirModuleData = createData("<dependsOn dependencies of $mainModuleName")
|
||||
private val binaryFriendsModuleData: FirModuleData = createData("<friends dependencies of $mainModuleName")
|
||||
|
||||
private val allRegularDependencies = mutableListOf<FirModuleData>()
|
||||
private val allFriendsDependencies = mutableListOf<FirModuleData>()
|
||||
private val allDependsOnDependencies = mutableListOf<FirModuleData>()
|
||||
|
||||
private val filtersMap: Map<FirModuleData, MutableSet<Path>> =
|
||||
listOf(
|
||||
binaryDependsOnModuleData,
|
||||
binaryFriendsModuleData,
|
||||
binaryRegularDependenciesModuleData
|
||||
).map { it to mutableSetOf<Path>() }.toMap()
|
||||
|
||||
fun dependency(vararg path: Path) {
|
||||
filtersMap.getValue(binaryRegularDependenciesModuleData) += path
|
||||
}
|
||||
|
||||
fun friendDependency(vararg path: Path) {
|
||||
filtersMap.getValue(binaryFriendsModuleData) += path
|
||||
}
|
||||
|
||||
fun dependsOnDependency(vararg path: Path) {
|
||||
filtersMap.getValue(binaryDependsOnModuleData) += path
|
||||
}
|
||||
|
||||
fun dependency(vararg path: String) {
|
||||
path.mapTo(filtersMap.getValue(binaryRegularDependenciesModuleData)) { Paths.get(it) }
|
||||
}
|
||||
|
||||
fun friendDependency(vararg path: String) {
|
||||
path.mapTo(filtersMap.getValue(binaryFriendsModuleData)) { Paths.get(it) }
|
||||
}
|
||||
|
||||
fun dependsOnDependency(vararg path: String) {
|
||||
path.mapTo(filtersMap.getValue(binaryDependsOnModuleData)) { Paths.get(it) }
|
||||
}
|
||||
|
||||
@JvmName("dependenciesString")
|
||||
fun dependencies(paths: Collection<String>) {
|
||||
paths.mapTo(filtersMap.getValue(binaryRegularDependenciesModuleData)) { Paths.get(it) }
|
||||
}
|
||||
|
||||
@JvmName("friendDependenciesString")
|
||||
fun friendDependencies(paths: Collection<String>) {
|
||||
paths.mapTo(filtersMap.getValue(binaryFriendsModuleData)) { Paths.get(it) }
|
||||
}
|
||||
|
||||
@JvmName("dependsOnDependenciesString")
|
||||
fun dependsOnDependencies(paths: Collection<String>) {
|
||||
paths.mapTo(filtersMap.getValue(binaryDependsOnModuleData)) { Paths.get(it) }
|
||||
}
|
||||
|
||||
fun dependencies(paths: Collection<Path>) {
|
||||
filtersMap.getValue(binaryRegularDependenciesModuleData) += paths
|
||||
}
|
||||
|
||||
fun friendDependencies(paths: Collection<Path>) {
|
||||
filtersMap.getValue(binaryFriendsModuleData) += paths
|
||||
}
|
||||
|
||||
fun dependsOnDependencies(paths: Collection<Path>) {
|
||||
filtersMap.getValue(binaryDependsOnModuleData) += paths
|
||||
}
|
||||
|
||||
fun sourceDependencies(modules: Collection<FirModuleData>) {
|
||||
allRegularDependencies += modules
|
||||
}
|
||||
|
||||
fun sourceFriendsDependencies(modules: Collection<FirModuleData>) {
|
||||
allFriendsDependencies += modules
|
||||
}
|
||||
|
||||
fun sourceDependsOnDependencies(modules: Collection<FirModuleData>) {
|
||||
allDependsOnDependencies += modules
|
||||
}
|
||||
|
||||
fun build(): DependencyListForCliModule {
|
||||
val pathFiltersMap: MutableMap<FirModuleData, LibraryPathFilter> = filtersMap
|
||||
.filterValues { it.isNotEmpty() }
|
||||
.mapValues { LibraryPathFilter.LibraryList(it.value) }
|
||||
.toMutableMap()
|
||||
|
||||
allRegularDependencies += binaryRegularDependenciesModuleData
|
||||
if (pathFiltersMap.isEmpty()) {
|
||||
return DependencyListForCliModule(
|
||||
platform,
|
||||
analyzerServices,
|
||||
allRegularDependencies,
|
||||
dependsOnDependencies = allDependsOnDependencies,
|
||||
friendsDependencies = allFriendsDependencies,
|
||||
SingleModuleDataProvider(binaryRegularDependenciesModuleData)
|
||||
)
|
||||
}
|
||||
if (binaryFriendsModuleData in pathFiltersMap) {
|
||||
allFriendsDependencies += binaryFriendsModuleData
|
||||
}
|
||||
if (binaryDependsOnModuleData in pathFiltersMap) {
|
||||
allDependsOnDependencies += binaryDependsOnModuleData
|
||||
}
|
||||
|
||||
val moduleDataProvider = MultipleModuleDataProvider(pathFiltersMap)
|
||||
pathFiltersMap.putIfAbsent(binaryRegularDependenciesModuleData, LibraryPathFilter.TakeAll)
|
||||
return DependencyListForCliModule(
|
||||
platform,
|
||||
analyzerServices,
|
||||
allRegularDependencies,
|
||||
allDependsOnDependencies,
|
||||
allFriendsDependencies,
|
||||
moduleDataProvider
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,13 +9,10 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
|
||||
import org.jetbrains.kotlin.fir.SessionConfiguration
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.type.TypeCheckers
|
||||
@@ -23,6 +20,8 @@ import org.jetbrains.kotlin.fir.analysis.checkersComponent
|
||||
import org.jetbrains.kotlin.fir.analysis.extensions.additionalCheckers
|
||||
import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers
|
||||
import org.jetbrains.kotlin.fir.checkers.registerJvmCheckers
|
||||
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
|
||||
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
|
||||
import org.jetbrains.kotlin.fir.extensions.BunchOfRegisteredExtensions
|
||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||
import org.jetbrains.kotlin.fir.extensions.registerExtensions
|
||||
@@ -37,6 +36,11 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
|
||||
|
||||
@OptIn(PrivateSessionConstructor::class, SessionConfiguration::class)
|
||||
object FirSessionFactory {
|
||||
@@ -66,20 +70,24 @@ object FirSessionFactory {
|
||||
}
|
||||
}
|
||||
|
||||
data class ProviderAndScopeForIncrementalCompilation(
|
||||
val packagePartProvider: PackagePartProvider,
|
||||
val scope: GlobalSearchScope
|
||||
)
|
||||
|
||||
fun createJavaModuleBasedSession(
|
||||
moduleInfo: ModuleInfo,
|
||||
moduleData: FirModuleData,
|
||||
sessionProvider: FirProjectSessionProvider,
|
||||
scope: GlobalSearchScope,
|
||||
project: Project,
|
||||
additionalPackagePartProvider: PackagePartProvider? = null,
|
||||
additionalScope: GlobalSearchScope? = null,
|
||||
dependenciesProvider: FirSymbolProvider? = null,
|
||||
providerAndScopeForIncrementalCompilation: ProviderAndScopeForIncrementalCompilation?,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
lookupTracker: LookupTracker? = null,
|
||||
init: FirSessionConfigurator.() -> Unit = {}
|
||||
): FirSession {
|
||||
return FirCliSession(sessionProvider, FirCliSession.Kind.Source).apply session@{
|
||||
val moduleData = FirModuleInfoBasedModuleData(moduleInfo).apply { bindSession(this@session) }
|
||||
moduleData.bindSession(this@session)
|
||||
sessionProvider.registerSession(moduleData, this@session)
|
||||
registerModuleData(moduleData)
|
||||
registerCliCompilerOnlyComponents()
|
||||
registerCommonComponents(languageVersionSettings)
|
||||
@@ -91,20 +99,19 @@ object FirSessionFactory {
|
||||
val firProvider = FirProviderImpl(this, kotlinScopeProvider)
|
||||
register(FirProvider::class, firProvider)
|
||||
|
||||
val deserializedJvmSymbolsProvider =
|
||||
if (additionalPackagePartProvider == null) null
|
||||
else {
|
||||
val javaSymbolProvider = JavaSymbolProvider(this, moduleData, project, additionalScope ?: scope)
|
||||
val symbolProviderForBinariesFromIncrementalCompilation = providerAndScopeForIncrementalCompilation?.let {
|
||||
val javaSymbolProvider = JavaSymbolProvider(this, moduleData, project, it.scope)
|
||||
|
||||
makeDeserializedJvmSymbolsProvider(
|
||||
moduleData,
|
||||
project,
|
||||
additionalScope ?: scope,
|
||||
additionalPackagePartProvider,
|
||||
javaSymbolProvider,
|
||||
kotlinScopeProvider
|
||||
)
|
||||
}
|
||||
makeDeserializedJvmSymbolsProvider(
|
||||
this@session,
|
||||
SingleModuleDataProvider(moduleData),
|
||||
project,
|
||||
it.scope,
|
||||
it.packagePartProvider,
|
||||
javaSymbolProvider,
|
||||
kotlinScopeProvider
|
||||
)
|
||||
}
|
||||
|
||||
register(
|
||||
FirSymbolProvider::class,
|
||||
@@ -112,11 +119,11 @@ object FirSessionFactory {
|
||||
this,
|
||||
listOfNotNull(
|
||||
firProvider.symbolProvider,
|
||||
symbolProviderForBinariesFromIncrementalCompilation,
|
||||
JavaSymbolProvider(this, moduleData, project, scope),
|
||||
dependenciesProvider ?: FirDependenciesSymbolProviderImpl(this),
|
||||
deserializedJvmSymbolsProvider
|
||||
FirDependenciesSymbolProviderImpl(this)
|
||||
)
|
||||
) as FirSymbolProvider
|
||||
)
|
||||
)
|
||||
|
||||
FirSessionConfigurator(this).apply {
|
||||
@@ -130,34 +137,50 @@ object FirSessionFactory {
|
||||
}
|
||||
|
||||
fun createLibrarySession(
|
||||
moduleInfo: ModuleInfo,
|
||||
mainModuleName: Name,
|
||||
sessionProvider: FirProjectSessionProvider,
|
||||
moduleDataProvider: ModuleDataProvider,
|
||||
scope: GlobalSearchScope,
|
||||
project: Project,
|
||||
packagePartProvider: PackagePartProvider,
|
||||
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
|
||||
): FirSession {
|
||||
return FirCliSession(sessionProvider, FirCliSession.Kind.Library).apply session@{
|
||||
val moduleData = FirModuleInfoBasedModuleData(moduleInfo).apply { bindSession(this@session) }
|
||||
sessionProvider.registerSession(moduleData, this)
|
||||
moduleDataProvider.allModuleData.forEach {
|
||||
sessionProvider.registerSession(it, this)
|
||||
it.bindSession(this)
|
||||
}
|
||||
|
||||
registerCliCompilerOnlyComponents()
|
||||
registerCommonComponents(languageVersionSettings)
|
||||
|
||||
val javaSymbolProvider = JavaSymbolProvider(this, moduleData, project, scope)
|
||||
val javaSymbolProvider = JavaSymbolProvider(this, moduleDataProvider.allModuleData.last(), project, scope)
|
||||
|
||||
val kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
|
||||
|
||||
val deserializedJvmSymbolsProvider = makeDeserializedJvmSymbolsProvider(
|
||||
moduleData, project, scope, packagePartProvider, javaSymbolProvider, kotlinScopeProvider
|
||||
librarySession = this,
|
||||
moduleDataProvider,
|
||||
project,
|
||||
scope,
|
||||
packagePartProvider,
|
||||
javaSymbolProvider,
|
||||
kotlinScopeProvider
|
||||
)
|
||||
|
||||
val builtinsModuleData = createModuleDataForBuiltins(
|
||||
mainModuleName,
|
||||
moduleDataProvider.platform,
|
||||
moduleDataProvider.analyzerServices
|
||||
).also { it.bindSession(this@session) }
|
||||
|
||||
val symbolProvider = FirCompositeSymbolProvider(
|
||||
this,
|
||||
listOf(
|
||||
deserializedJvmSymbolsProvider,
|
||||
FirBuiltinSymbolProvider(this, moduleData, kotlinScopeProvider),
|
||||
FirCloneableSymbolProvider(this, moduleData, kotlinScopeProvider),
|
||||
javaSymbolProvider,
|
||||
FirBuiltinSymbolProvider(this, builtinsModuleData, kotlinScopeProvider),
|
||||
FirCloneableSymbolProvider(this, builtinsModuleData, kotlinScopeProvider),
|
||||
javaSymbolProvider, // TODO: looks like it can be removed
|
||||
FirDependenciesSymbolProviderImpl(this)
|
||||
)
|
||||
)
|
||||
@@ -167,7 +190,8 @@ object FirSessionFactory {
|
||||
}
|
||||
|
||||
private fun makeDeserializedJvmSymbolsProvider(
|
||||
moduleData: FirModuleData,
|
||||
librarySession: FirSession,
|
||||
moduleDataProvider: ModuleDataProvider,
|
||||
project: Project,
|
||||
scope: GlobalSearchScope,
|
||||
packagePartProvider: PackagePartProvider,
|
||||
@@ -182,12 +206,41 @@ object FirSessionFactory {
|
||||
}
|
||||
|
||||
return KotlinDeserializedJvmSymbolsProvider(
|
||||
moduleData, kotlinScopeProvider, packagePartProvider, kotlinClassFinder, javaSymbolProvider, javaClassFinder
|
||||
librarySession,
|
||||
moduleDataProvider,
|
||||
kotlinScopeProvider,
|
||||
packagePartProvider,
|
||||
kotlinClassFinder,
|
||||
javaSymbolProvider,
|
||||
javaClassFinder
|
||||
)
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun createEmptySession(): FirSession {
|
||||
return object : FirSession(null) {}
|
||||
return object : FirSession(null) {}.apply {
|
||||
val moduleData = FirModuleDataImpl(
|
||||
Name.identifier("<stub module>"),
|
||||
dependencies = emptyList(),
|
||||
dependsOnDependencies = emptyList(),
|
||||
friendDependencies = emptyList(),
|
||||
platform = JvmPlatforms.unspecifiedJvmPlatform,
|
||||
analyzerServices = JvmPlatformAnalyzerServices
|
||||
)
|
||||
registerModuleData(moduleData)
|
||||
moduleData.bindSession(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun createModuleDataForBuiltins(
|
||||
parentModuleName: Name,
|
||||
platform: TargetPlatform,
|
||||
analyzerServices: PlatformDependentAnalyzerServices
|
||||
): FirModuleData {
|
||||
return DependencyListForCliModule.createDependencyModuleData(
|
||||
Name.special("<builtins of ${parentModuleName.identifier}"),
|
||||
platform,
|
||||
analyzerServices,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,95 +7,125 @@ package org.jetbrains.kotlin.fir
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
||||
import org.jetbrains.kotlin.fir.session.FirJvmModuleInfo
|
||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.modules.Module
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
|
||||
fun createSessionWithDependencies(
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun createSessionWithDependencies(
|
||||
name: Name,
|
||||
friendPaths: List<String>,
|
||||
outputDirectory: String?,
|
||||
platform: TargetPlatform,
|
||||
analyzerServices: PlatformDependentAnalyzerServices,
|
||||
externalSessionProvider: FirProjectSessionProvider?,
|
||||
project: Project,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
sourceScope: GlobalSearchScope,
|
||||
librariesScope: GlobalSearchScope,
|
||||
lookupTracker: LookupTracker?,
|
||||
getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||
getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider?,
|
||||
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {}
|
||||
getProviderAndScopeForIncrementalCompilation: () -> FirSessionFactory.ProviderAndScopeForIncrementalCompilation?,
|
||||
dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {},
|
||||
noinline sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {},
|
||||
): FirSession {
|
||||
return createSessionWithDependencies(
|
||||
name.identifier,
|
||||
val dependencyList = DependencyListForCliModule.build(name, platform, analyzerServices, dependenciesConfigurator)
|
||||
return createSessionWithDependenciesImpl(
|
||||
name,
|
||||
dependencyList,
|
||||
externalSessionProvider,
|
||||
project,
|
||||
languageVersionSettings,
|
||||
sourceScope,
|
||||
librariesScope,
|
||||
lookupTracker,
|
||||
getPackagePartProvider,
|
||||
getAdditionalModulePackagePartProvider,
|
||||
getProviderAndScopeForIncrementalCompilation,
|
||||
sessionConfigurator
|
||||
) {
|
||||
FirJvmModuleInfo(name, it, friendPaths, outputDirectory)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun createSessionWithDependencies(
|
||||
@OptIn(PrivateForInline::class)
|
||||
inline fun createSessionWithDependencies(
|
||||
module: Module,
|
||||
platform: TargetPlatform,
|
||||
analyzerServices: PlatformDependentAnalyzerServices,
|
||||
externalSessionProvider: FirProjectSessionProvider?,
|
||||
project: Project,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
sourceScope: GlobalSearchScope,
|
||||
librariesScope: GlobalSearchScope,
|
||||
lookupTracker: LookupTracker?,
|
||||
getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||
getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider?,
|
||||
sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {}
|
||||
getProviderAndScopeForIncrementalCompilation: () -> FirSessionFactory.ProviderAndScopeForIncrementalCompilation?,
|
||||
noinline sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit = {},
|
||||
): FirSession {
|
||||
return createSessionWithDependencies(
|
||||
module.getModuleName(),
|
||||
val moduleName = Name.identifier(module.getModuleName())
|
||||
val dependencyList = DependencyListForCliModule.build(
|
||||
moduleName,
|
||||
platform,
|
||||
analyzerServices
|
||||
) {
|
||||
friendDependencies(module.getFriendPaths())
|
||||
dependencies(module.getClasspathRoots())
|
||||
}
|
||||
return createSessionWithDependenciesImpl(
|
||||
moduleName,
|
||||
dependencyList,
|
||||
externalSessionProvider,
|
||||
project,
|
||||
languageVersionSettings,
|
||||
sourceScope,
|
||||
librariesScope,
|
||||
lookupTracker,
|
||||
getPackagePartProvider,
|
||||
getAdditionalModulePackagePartProvider,
|
||||
getProviderAndScopeForIncrementalCompilation,
|
||||
sessionConfigurator
|
||||
) {
|
||||
FirJvmModuleInfo(module, it)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private inline fun createSessionWithDependencies(
|
||||
moduleName: String,
|
||||
@PrivateForInline
|
||||
inline fun createSessionWithDependenciesImpl(
|
||||
moduleName: Name,
|
||||
dependencyListForCliModule: DependencyListForCliModule,
|
||||
externalSessionProvider: FirProjectSessionProvider?,
|
||||
project: Project,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
sourceScope: GlobalSearchScope,
|
||||
librariesScope: GlobalSearchScope,
|
||||
lookupTracker: LookupTracker?,
|
||||
getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||
getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider?,
|
||||
getProviderAndScopeForIncrementalCompilation: () -> FirSessionFactory.ProviderAndScopeForIncrementalCompilation?,
|
||||
noinline sessionConfigurator: FirSessionFactory.FirSessionConfigurator.() -> Unit,
|
||||
moduleInfoProvider: (dependencies: List<ModuleInfo>) -> ModuleInfo,
|
||||
): FirSession {
|
||||
val provider = FirProjectSessionProvider()
|
||||
val librariesModuleInfo = FirJvmModuleInfo.createForLibraries(moduleName)
|
||||
val sessionProvider = externalSessionProvider ?: FirProjectSessionProvider()
|
||||
FirSessionFactory.createLibrarySession(
|
||||
librariesModuleInfo, provider, librariesScope,
|
||||
project, getPackagePartProvider(librariesScope)
|
||||
moduleName,
|
||||
sessionProvider,
|
||||
dependencyListForCliModule.moduleDataProvider,
|
||||
librariesScope,
|
||||
project,
|
||||
getPackagePartProvider(librariesScope)
|
||||
)
|
||||
|
||||
val mainModuleData = FirModuleDataImpl(
|
||||
moduleName,
|
||||
dependencyListForCliModule.regularDependencies,
|
||||
dependencyListForCliModule.dependsOnDependencies,
|
||||
dependencyListForCliModule.friendsDependencies,
|
||||
dependencyListForCliModule.platform,
|
||||
dependencyListForCliModule.analyzerServices
|
||||
)
|
||||
return FirSessionFactory.createJavaModuleBasedSession(
|
||||
moduleInfoProvider(listOf(librariesModuleInfo)),
|
||||
provider,
|
||||
mainModuleData,
|
||||
sessionProvider,
|
||||
sourceScope,
|
||||
project,
|
||||
additionalPackagePartProvider = getAdditionalModulePackagePartProvider(sourceScope),
|
||||
additionalScope = librariesScope,
|
||||
providerAndScopeForIncrementalCompilation = getProviderAndScopeForIncrementalCompilation(),
|
||||
languageVersionSettings = languageVersionSettings,
|
||||
lookupTracker = lookupTracker,
|
||||
init = sessionConfigurator
|
||||
|
||||
+40
-20
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.deserialization
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.caches.*
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.name.*
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||
import java.nio.file.Path
|
||||
|
||||
class PackagePartsCacheData(
|
||||
val proto: ProtoBuf.Package,
|
||||
@@ -36,13 +37,30 @@ class PackagePartsCacheData(
|
||||
}
|
||||
}
|
||||
|
||||
abstract class LibraryPathFilter {
|
||||
abstract fun accepts(path: Path?): Boolean
|
||||
|
||||
object TakeAll : LibraryPathFilter() {
|
||||
override fun accepts(path: Path?): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
class LibraryList(val libs: Set<Path>) : LibraryPathFilter() {
|
||||
override fun accepts(path: Path?): Boolean {
|
||||
if (path == null) return false
|
||||
return libs.any { path.startsWith(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typealias DeserializedClassPostProcessor = (FirRegularClassSymbol) -> Unit
|
||||
|
||||
abstract class AbstractFirDeserializedSymbolsProvider(
|
||||
val moduleData: FirModuleData,
|
||||
val kotlinScopeProvider: FirKotlinScopeProvider
|
||||
) : FirSymbolProvider(moduleData.session) {
|
||||
|
||||
session: FirSession,
|
||||
val moduleDataProvider: ModuleDataProvider,
|
||||
val kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
) : FirSymbolProvider(session) {
|
||||
// ------------------------ Caches ------------------------
|
||||
|
||||
private val packagePartsCache = session.firCachesFactory.createCache(::tryComputePackagePartInfos)
|
||||
@@ -75,6 +93,7 @@ abstract class AbstractFirDeserializedSymbolsProvider(
|
||||
val nameResolver: NameResolver,
|
||||
val classProto: ProtoBuf.Class,
|
||||
val annotationDeserializer: AbstractAnnotationDeserializer,
|
||||
val containingLibraryPath: Path?,
|
||||
val sourceElement: DeserializedContainerSource,
|
||||
val classPostProcessor: DeserializedClassPostProcessor
|
||||
) : ClassMetadataFindResult()
|
||||
@@ -107,7 +126,8 @@ abstract class AbstractFirDeserializedSymbolsProvider(
|
||||
): Pair<FirRegularClassSymbol?, DeserializedClassPostProcessor?> {
|
||||
return when (val result = extractClassMetadata(classId, parentContext)) {
|
||||
is ClassMetadataFindResult.Metadata -> {
|
||||
val (nameResolver, classProto, annotationDeserializer, sourceElement, postProcessor) = result
|
||||
val (nameResolver, classProto, annotationDeserializer, containingLibrary, sourceElement, postProcessor) = result
|
||||
val moduleData = moduleDataProvider.getModuleData(containingLibrary) ?: return null to null
|
||||
val symbol = FirRegularClassSymbol(classId)
|
||||
deserializeClassToSymbol(
|
||||
classId,
|
||||
@@ -158,6 +178,20 @@ abstract class AbstractFirDeserializedSymbolsProvider(
|
||||
return packagePartsCache.getValue(packageFqName)
|
||||
}
|
||||
|
||||
private fun getClass(
|
||||
classId: ClassId,
|
||||
parentContext: FirDeserializationContext? = null
|
||||
): FirRegularClassSymbol? {
|
||||
return classCache.getValue(classId, parentContext)
|
||||
}
|
||||
|
||||
private fun getTypeAlias(
|
||||
classId: ClassId,
|
||||
): FirTypeAliasSymbol? {
|
||||
if (!classId.relativeClassName.isOneSegmentFQN()) return null
|
||||
return typeAliasCache.getValue(classId)
|
||||
}
|
||||
|
||||
// ------------------------ SymbolProvider methods ------------------------
|
||||
|
||||
@FirSymbolProviderInternals
|
||||
@@ -181,19 +215,5 @@ abstract class AbstractFirDeserializedSymbolsProvider(
|
||||
return getClass(classId) ?: getTypeAlias(classId)
|
||||
}
|
||||
|
||||
private fun getClass(
|
||||
classId: ClassId,
|
||||
parentContext: FirDeserializationContext? = null
|
||||
): FirRegularClassSymbol? {
|
||||
return classCache.getValue(classId, parentContext)
|
||||
}
|
||||
|
||||
private fun getTypeAlias(
|
||||
classId: ClassId,
|
||||
): FirTypeAliasSymbol? {
|
||||
if (!classId.relativeClassName.isOneSegmentFQN()) return null
|
||||
return typeAliasCache.getValue(classId)
|
||||
}
|
||||
|
||||
override fun getPackage(fqName: FqName): FqName? = null
|
||||
}
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.deserialization
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.same
|
||||
import java.nio.file.Path
|
||||
|
||||
abstract class ModuleDataProvider {
|
||||
abstract val platform: TargetPlatform
|
||||
abstract val analyzerServices: PlatformDependentAnalyzerServices
|
||||
abstract val allModuleData: Collection<FirModuleData>
|
||||
|
||||
abstract fun getModuleData(path: Path?): FirModuleData?
|
||||
}
|
||||
|
||||
class SingleModuleDataProvider(private val moduleData: FirModuleData) : ModuleDataProvider() {
|
||||
override val platform: TargetPlatform
|
||||
get() = moduleData.platform
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices
|
||||
get() = moduleData.analyzerServices
|
||||
override val allModuleData: Collection<FirModuleData>
|
||||
get() = listOf(moduleData)
|
||||
|
||||
override fun getModuleData(path: Path?): FirModuleData {
|
||||
return moduleData
|
||||
}
|
||||
}
|
||||
|
||||
class MultipleModuleDataProvider(private val moduleDataWithFilters: Map<FirModuleData, LibraryPathFilter>) : ModuleDataProvider() {
|
||||
init {
|
||||
require(moduleDataWithFilters.isNotEmpty()) { "ModuleDataProvider must contain at least one module data" }
|
||||
require(moduleDataWithFilters.keys.same { it.platform }) { "All module data should have same target platform" }
|
||||
require(moduleDataWithFilters.keys.same { it.analyzerServices }) { "All module data should have same analyzerServices" }
|
||||
}
|
||||
|
||||
override val platform: TargetPlatform = allModuleData.first().platform
|
||||
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices = allModuleData.first().analyzerServices
|
||||
|
||||
override val allModuleData: Collection<FirModuleData>
|
||||
get() = moduleDataWithFilters.keys
|
||||
|
||||
override fun getModuleData(path: Path?): FirModuleData? {
|
||||
for ((session, filter) in moduleDataWithFilters.entries) {
|
||||
if (filter.accepts(path)) {
|
||||
return session
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.java.deserialization
|
||||
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.fir.FirModuleData
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.ThreadSafeMutableState
|
||||
import org.jetbrains.kotlin.fir.caches.*
|
||||
@@ -35,13 +34,14 @@ import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErr
|
||||
|
||||
@ThreadSafeMutableState
|
||||
class KotlinDeserializedJvmSymbolsProvider(
|
||||
moduleData: FirModuleData,
|
||||
session: FirSession,
|
||||
moduleDataProvider: ModuleDataProvider,
|
||||
kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
private val packagePartProvider: PackagePartProvider,
|
||||
private val kotlinClassFinder: KotlinClassFinder,
|
||||
private val javaSymbolProvider: JavaSymbolProvider,
|
||||
javaClassFinder: JavaClassFinder,
|
||||
) : AbstractFirDeserializedSymbolsProvider(moduleData, kotlinScopeProvider) {
|
||||
) : AbstractFirDeserializedSymbolsProvider(session, moduleDataProvider, kotlinScopeProvider) {
|
||||
private val knownNameInPackageCache = KnownNameInPackageCache(session, javaClassFinder)
|
||||
private val annotationsLoader = AnnotationsLoader(session)
|
||||
|
||||
@@ -56,6 +56,8 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
val facadeFqName = facadeName?.let { JvmClassName.byInternalName(it).fqNameForTopLevelClassMaybeWithDollars }
|
||||
val facadeBinaryClass = facadeFqName?.let { kotlinClassFinder.findKotlinClass(ClassId.topLevel(it)) }
|
||||
|
||||
val moduleData = moduleDataProvider.getModuleData(kotlinJvmBinaryClass.containingLibrary) ?: return@mapNotNull null
|
||||
|
||||
val header = kotlinJvmBinaryClass.classHeader
|
||||
val data = header.data ?: header.incompatibleData ?: return@mapNotNull null
|
||||
val strings = header.strings ?: return@mapNotNull null
|
||||
@@ -113,6 +115,7 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
nameResolver,
|
||||
classProto,
|
||||
JvmBinaryAnnotationDeserializer(session, kotlinClass.kotlinJvmBinaryClass, kotlinClassFinder, kotlinClass.byteContent),
|
||||
kotlinClass.kotlinJvmBinaryClass.containingLibrary,
|
||||
KotlinJvmBinarySourceElement(kotlinClass.kotlinJvmBinaryClass),
|
||||
classPostProcessor = { loadAnnotationsFromClassFile(kotlinClass, it) }
|
||||
)
|
||||
|
||||
+3
-1
@@ -12,6 +12,7 @@ import com.intellij.psi.search.ProjectScope
|
||||
import com.sun.jna.Library
|
||||
import com.sun.jna.Native
|
||||
import com.sun.management.HotSpotDiagnosticMXBean
|
||||
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.cli.common.profiling.AsyncProfilerHelper
|
||||
import org.jetbrains.kotlin.cli.common.toBooleanLenient
|
||||
@@ -149,6 +150,7 @@ class FirResolveModularizedTotalKotlinTest : AbstractModularizedTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteTestInfrastructure::class)
|
||||
private fun runAnalysis(moduleData: ModuleData, environment: KotlinCoreEnvironment) {
|
||||
val project = environment.project
|
||||
val ktFiles = environment.getSourceFiles()
|
||||
@@ -161,7 +163,7 @@ class FirResolveModularizedTotalKotlinTest : AbstractModularizedTest() {
|
||||
scope,
|
||||
librariesScope,
|
||||
moduleData.qualifiedName,
|
||||
moduleData.friendDirs.map { it.canonicalPath }
|
||||
moduleData.friendDirs.map { it.toPath() }
|
||||
)
|
||||
val scopeSession = ScopeSession()
|
||||
val processors = createAllCompilerResolveProcessors(session, scopeSession).let {
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ open class FirDependenciesSymbolProviderImpl(session: FirSession) : FirSymbolPro
|
||||
|
||||
protected open val dependencyProviders by lazy {
|
||||
val moduleData = session.nullableModuleData ?: return@lazy emptyList()
|
||||
moduleData.dependencies.mapNotNull {
|
||||
(moduleData.dependencies + moduleData.friendDependencies + moduleData.dependsOnDependencies).mapNotNull {
|
||||
session.sessionProvider?.getSession(it)?.symbolProvider
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@ abstract class FirModuleData : FirSessionComponent {
|
||||
|
||||
private var _session: FirSession? = null
|
||||
val session: FirSession
|
||||
get() = _session!!
|
||||
get() = _session ?: error("module data not bound to session")
|
||||
|
||||
fun bindSession(session: FirSession) {
|
||||
if (_session != null) {
|
||||
error("session already bound to $this")
|
||||
error("module data already bound to $this")
|
||||
}
|
||||
_session = session
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user