[FIR] Refactor deserialized dependency providers and session factories with FirModuleData

This commit is contained in:
Dmitriy Novozhilov
2021-04-30 16:57:46 +03:00
committed by TeamCityServer
parent 24f1f7b7b2
commit 02c58b7a8f
23 changed files with 566 additions and 196 deletions
@@ -12,6 +12,7 @@ import com.intellij.psi.PsiFileFactory
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.builtins.jvm.JvmBuiltIns
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
@@ -147,6 +148,7 @@ abstract class AbstractSimpleFileBenchmark {
bh.consume(result.shouldGenerateCode)
}
@OptIn(ObsoleteTestInfrastructure::class)
private fun analyzeGreenFileIr(bh: Blackhole) {
val scope = GlobalSearchScope.filesScope(env.project, listOf(file.virtualFile))
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project))
@@ -58,6 +58,7 @@ import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
import org.jetbrains.kotlin.fir.createSessionWithDependencies
import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.ir.backend.jvm.jvmResolveLibraries
import org.jetbrains.kotlin.javac.JavacWrapper
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
@@ -65,11 +66,13 @@ import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvid
import org.jetbrains.kotlin.modules.Module
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.diagnostics.SimpleGenericDiagnostics
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
import java.io.File
@@ -337,24 +340,29 @@ object KotlinToJVMBytecodeCompiler {
val languageVersionSettings = moduleConfiguration.languageVersionSettings
val session = createSessionWithDependencies(
module,
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices,
externalSessionProvider = null,
project,
languageVersionSettings,
sourceScope,
librariesScope,
lookupTracker = environment.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
getPackagePartProvider = { environment.createPackagePartProvider(it) },
getAdditionalModulePackagePartProvider = {
if (targetIds == null || incrementalComponents == null) null
else IncrementalPackagePartProvider(
environment.createPackagePartProvider(it),
getProviderAndScopeForIncrementalCompilation = get@{
if (targetIds == null || incrementalComponents == null) return@get null
val packagePartProvider = IncrementalPackagePartProvider(
environment.createPackagePartProvider(sourceScope),
targetIds.map(incrementalComponents::getIncrementalCache)
)
FirSessionFactory.ProviderAndScopeForIncrementalCompilation(packagePartProvider, librariesScope)
},
sessionConfigurator = {
if (extendedAnalysisMode) {
registerExtendedCommonCheckers()
}
}
) {
if (extendedAnalysisMode) {
registerExtendedCommonCheckers()
}
}
)
val firAnalyzerFacade = FirAnalyzerFacade(session, languageVersionSettings, ktFiles)
@@ -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)
@@ -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))
@@ -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
@@ -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
}
@@ -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
}
}
@@ -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) }
)
@@ -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 {
@@ -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
}
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.util.PerformanceCounter
import java.io.FileNotFoundException
import java.io.IOException
import java.nio.file.Path
import java.nio.file.Paths
class VirtualFileKotlinClass private constructor(
val file: VirtualFile,
@@ -38,6 +40,9 @@ class VirtualFileKotlinClass private constructor(
override val location: String
get() = file.path
override val containingLibrary: Path?
get() = file.path.split("!/").firstOrNull()?.let { Paths.get(it) }
override fun getFileContents(): ByteArray {
try {
return file.contentsToByteArray()
@@ -61,7 +66,7 @@ class VirtualFileKotlinClass private constructor(
try {
val byteContent = fileContent ?: file.contentsToByteArray(false)
if (byteContent.isNotEmpty()) {
val kotlinJvmBinaryClass = FileBasedKotlinClass.create(byteContent) { name, classVersion, header, innerClasses ->
val kotlinJvmBinaryClass = create(byteContent) { name, classVersion, header, innerClasses ->
VirtualFileKotlinClass(file, name, classVersion, header, innerClasses)
}
@@ -5,19 +5,29 @@
package org.jetbrains.kotlin.test.frontend.fir
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ProjectScope
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
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.fir.createSessionWithDependencies
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.isCommon
import org.jetbrains.kotlin.platform.js.isJs
import org.jetbrains.kotlin.platform.jvm.isJvm
import org.jetbrains.kotlin.platform.konan.isNative
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.konan.platform.NativePlatformAnalyzerServices
import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
import org.jetbrains.kotlin.test.model.*
@@ -48,28 +58,43 @@ class FirFrontendFacade(
testServices.sourceFileProvider.getKtFilesForSourceFiles(module.files, project).values to emptyList()
}
val sessionProvider = moduleInfoProvider.firSessionProvider
val languageVersionSettings = module.languageVersionSettings
val builtinsModuleInfo = moduleInfoProvider.builtinsModuleInfoForModule(module)
val packagePartProviderFactory = compilerConfigurationProvider.getPackagePartProviderFactory(module)
createSessionForBuiltins(builtinsModuleInfo, sessionProvider, project, packagePartProviderFactory)
createSessionForBinaryDependencies(module, sessionProvider, project, packagePartProviderFactory)
val configuration = compilerConfigurationProvider.getCompilerConfiguration(module)
val librariesScope = ProjectScope.getLibrariesScope(project)
val sourcesScope = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles)
val sourcesModuleInfo = moduleInfoProvider.convertToFirModuleInfo(module)
val session = FirSessionFactory.createJavaModuleBasedSession(
sourcesModuleInfo,
sessionProvider,
sourcesScope,
val session = createSessionWithDependencies(
Name.identifier(module.name),
module.targetPlatform,
module.targetPlatform.getAnalyzerServices(),
moduleInfoProvider.firSessionProvider,
project,
languageVersionSettings = languageVersionSettings
) {
if (FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS in module.directives) {
registerExtendedCommonCheckers()
languageVersionSettings,
sourcesScope,
librariesScope,
lookupTracker = null,
getPackagePartProvider = packagePartProviderFactory,
getProviderAndScopeForIncrementalCompilation = { null },
dependenciesConfigurator = {
dependencies(configuration.jvmModularRoots.map { it.toPath() })
dependencies(configuration.jvmClasspathRoots.map { it.toPath() })
friendDependencies(configuration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
sourceDependencies(moduleInfoProvider.getDependentSourceModules(module))
sourceFriendsDependencies(moduleInfoProvider.getDependentFriendSourceModules(module))
},
sessionConfigurator = {
if (FirDiagnosticsDirectives.WITH_EXTENDED_CHECKERS in module.directives) {
registerExtendedCommonCheckers()
}
}
}
)
moduleInfoProvider.registerModuleData(module, session.moduleData)
val firAnalyzerFacade = FirAnalyzerFacade(session, languageVersionSettings, ktFiles, originalFiles, lightTreeEnabled)
val firFiles = firAnalyzerFacade.runResolution()
@@ -81,35 +106,13 @@ class FirFrontendFacade(
return FirOutputArtifactImpl(session, filesMap, firAnalyzerFacade)
}
private fun createSessionForBuiltins(
builtinsModuleInfo: FirJvmModuleInfo,
sessionProvider: FirProjectSessionProvider,
project: Project,
packagePartProviderFactory: (GlobalSearchScope) -> JvmPackagePartProvider,
) {
//For BuiltIns, registered in sessionProvider automatically
val allProjectScope = GlobalSearchScope.allScope(project)
FirSessionFactory.createLibrarySession(
builtinsModuleInfo, sessionProvider, allProjectScope, project,
packagePartProviderFactory(allProjectScope)
)
}
private fun createSessionForBinaryDependencies(
module: TestModule,
sessionProvider: FirProjectSessionProvider,
project: Project,
packagePartProviderFactory: (GlobalSearchScope) -> JvmPackagePartProvider,
) {
val librariesScope = ProjectScope.getLibrariesScope(project)
val librariesModuleInfo = FirJvmModuleInfo.createForLibraries(module.name)
FirSessionFactory.createLibrarySession(
librariesModuleInfo,
sessionProvider,
librariesScope,
project,
packagePartProviderFactory(librariesScope)
)
private fun TargetPlatform.getAnalyzerServices(): PlatformDependentAnalyzerServices {
return when {
isJvm() -> JvmPlatformAnalyzerServices
isJs() -> JsPlatformAnalyzerServices
isNative() -> NativePlatformAnalyzerServices
isCommon() -> CommonPlatformAnalyzerServices
else -> error("Unknown target platform: $this")
}
}
}
@@ -5,36 +5,40 @@
package org.jetbrains.kotlin.test.frontend.fir
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.session.FirJvmModuleInfo
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.test.model.DependencyDescription
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestService
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.dependencyProvider
import org.jetbrains.kotlin.test.model.TestModule
class FirModuleInfoProvider(
private val testServices: TestServices
) : TestService {
class FirModuleInfoProvider(private val testServices: TestServices) : TestService {
val firSessionProvider = FirProjectSessionProvider()
private val builtinsByModule: MutableMap<TestModule, FirJvmModuleInfo> = mutableMapOf()
private val firModuleInfoByModule: MutableMap<TestModule, FirJvmModuleInfo> = mutableMapOf()
private val firModuleDataByModule: MutableMap<TestModule, FirModuleData> = mutableMapOf()
fun convertToFirModuleInfo(module: TestModule): FirJvmModuleInfo {
return firModuleInfoByModule.getOrPut(module) {
val dependencies = mutableListOf(builtinsModuleInfoForModule(module))
module.dependencies.filter { it.kind == DependencyKind.Source }.mapTo(dependencies) {
convertToFirModuleInfo(testServices.dependencyProvider.getTestModule(it.moduleName))
}
FirJvmModuleInfo(Name.identifier(module.name), dependencies)
}
fun registerModuleData(module: TestModule, moduleData: FirModuleData) {
if (module in firModuleDataByModule) error("module data for module $module already registered")
firModuleDataByModule[module] = moduleData
}
fun builtinsModuleInfoForModule(module: TestModule): FirJvmModuleInfo {
return builtinsByModule.getOrPut(module) {
FirJvmModuleInfo(Name.special("<built-ins>"))
fun getCorrespondingModuleData(module: TestModule): FirModuleData {
return firModuleDataByModule[module] ?: error("module data for module $module is not registered")
}
fun getDependentSourceModules(module: TestModule): List<FirModuleData> {
return getDependentModulesImpl(module.dependencies)
}
fun getDependentFriendSourceModules(module: TestModule): List<FirModuleData> {
return getDependentModulesImpl(module.friends)
}
private fun getDependentModulesImpl(dependencies: List<DependencyDescription>): List<FirModuleData> {
return dependencies.filter { it.kind == DependencyKind.Source }.map {
getCorrespondingModuleData(testServices.dependencyProvider.getTestModule(it.moduleName))
}
}
}
@@ -8,16 +8,13 @@ package org.jetbrains.kotlin.checkers
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.rt.execution.junit.FileComparisonFailure
import junit.framework.AssertionFailedError
import junit.framework.TestCase
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
import org.jetbrains.kotlin.TestsCompilerError
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.analyzer.common.CommonResolverForModuleFactory
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector
@@ -41,8 +38,6 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.fir.AbstractFirOldFrontendDiagnosticsTest
import org.jetbrains.kotlin.fir.loadTestDataWithoutDiagnostics
import org.jetbrains.kotlin.frontend.java.di.createContainerForLazyResolveWithJava
import org.jetbrains.kotlin.frontend.java.di.initJvmBuiltInsForTopDownAnalysis
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
@@ -9,6 +9,7 @@ import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ProjectScope
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
import org.jetbrains.kotlin.TestsCompiletimeError
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
@@ -91,6 +92,7 @@ object GenerationUtils {
return state
}
@OptIn(ObsoleteTestInfrastructure::class)
private fun compileFilesUsingFrontendIR(
project: Project,
files: List<KtFile>,
@@ -7,50 +7,55 @@ package org.jetbrains.kotlin.fir
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.ObsoleteTestInfrastructure
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import java.nio.file.Path
@ObsoleteTestInfrastructure
fun createSessionForTests(
environment: KotlinCoreEnvironment,
sourceScope: GlobalSearchScope,
librariesScope: GlobalSearchScope = GlobalSearchScope.notScope(sourceScope),
moduleName: String = "TestModule",
friendPaths: List<String> = emptyList(),
lookupTracker: LookupTracker? = null
friendsPaths: List<Path> = emptyList(),
): FirSession = createSessionForTests(
environment.project,
sourceScope,
librariesScope,
moduleName,
friendPaths,
lookupTracker,
friendsPaths,
environment::createPackagePartProvider
)
@ObsoleteTestInfrastructure
fun createSessionForTests(
project: Project,
sourceScope: GlobalSearchScope,
librariesScope: GlobalSearchScope,
moduleName: String = "TestModule",
friendPaths: List<String> = emptyList(),
lookupTracker: LookupTracker? = null,
friendsPaths: List<Path> = emptyList(),
getPackagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
getAdditionalModulePackagePartProvider: (GlobalSearchScope) -> PackagePartProvider? = { null }
): FirSession {
return createSessionWithDependencies(
Name.identifier(moduleName),
friendPaths,
outputDirectory = null,
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices,
externalSessionProvider = null,
project,
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
sourceScope,
librariesScope,
lookupTracker,
lookupTracker = null,
getPackagePartProvider,
getAdditionalModulePackagePartProvider
getProviderAndScopeForIncrementalCompilation = { null },
dependenciesConfigurator = {
friendDependencies(friendsPaths)
}
)
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue
import java.nio.file.Path
interface KotlinJvmBinaryClass {
val classId: ClassId
@@ -19,6 +20,9 @@ interface KotlinJvmBinaryClass {
*/
val location: String
val containingLibrary: Path?
get() = null
fun loadClassAnnotations(visitor: AnnotationVisitor, cachedContents: ByteArray?)
fun visitMembers(visitor: MemberVisitor, cachedContents: ByteArray?)
@@ -13,6 +13,7 @@ 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.declarations.SealedClassInheritorsProvider
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
import org.jetbrains.kotlin.fir.java.JavaSymbolProvider
import org.jetbrains.kotlin.fir.java.deserialization.KotlinDeserializedJvmSymbolsProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
@@ -191,7 +192,8 @@ internal object FirIdeSessionFactory {
add(
FirThreadSafeSymbolProviderWrapper(
KotlinDeserializedJvmSymbolsProvider(
moduleData,
this@session,
SingleModuleDataProvider(moduleData),
kotlinScopeProvider,
packagePartProvider,
kotlinClassFinder,