[FIR & FIR2IR] Prepare test and CLI infrastructure to support MPP

- Move out getAnalyzerServices from FirFrontendFacade to TestSetupUtils
- Simplify DependencyListForCliModule. Now it takes BinaryModuleData as input
- FirOutArtifact contains several FirOutputArtifactPart
- Simplify FirFrontendFacade
This commit is contained in:
Ivan Kochurkin
2022-11-18 19:51:58 +01:00
committed by Space Team
parent 3029e47609
commit 5d273ce839
44 changed files with 1025 additions and 788 deletions
@@ -9,117 +9,66 @@ 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()
inline fun build(binaryModuleData: BinaryModuleData, init: Builder.() -> Unit = {}): DependencyListForCliModule {
return Builder(binaryModuleData).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")
class Builder(val binaryModuleData: BinaryModuleData) {
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()
binaryModuleData.dependsOn,
binaryModuleData.friends,
binaryModuleData.regular
).associateWith { mutableSetOf() }
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
filtersMap.getValue(binaryModuleData.regular) += 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) }
path.mapTo(filtersMap.getValue(binaryModuleData.regular)) { Paths.get(it) }
}
@JvmName("dependenciesString")
fun dependencies(paths: Collection<String>) {
paths.mapTo(filtersMap.getValue(binaryRegularDependenciesModuleData)) { Paths.get(it) }
paths.mapTo(filtersMap.getValue(binaryModuleData.regular)) { Paths.get(it) }
}
@JvmName("friendDependenciesString")
fun friendDependencies(paths: Collection<String>) {
paths.mapTo(filtersMap.getValue(binaryFriendsModuleData)) { Paths.get(it) }
paths.mapTo(filtersMap.getValue(binaryModuleData.friends)) { Paths.get(it) }
}
@JvmName("dependsOnDependenciesString")
fun dependsOnDependencies(paths: Collection<String>) {
paths.mapTo(filtersMap.getValue(binaryDependsOnModuleData)) { Paths.get(it) }
paths.mapTo(filtersMap.getValue(binaryModuleData.dependsOn)) { Paths.get(it) }
}
fun dependencies(paths: Collection<Path>) {
filtersMap.getValue(binaryRegularDependenciesModuleData) += paths
filtersMap.getValue(binaryModuleData.regular) += paths
}
fun friendDependencies(paths: Collection<Path>) {
filtersMap.getValue(binaryFriendsModuleData) += paths
filtersMap.getValue(binaryModuleData.friends) += paths
}
fun dependsOnDependencies(paths: Collection<Path>) {
filtersMap.getValue(binaryDependsOnModuleData) += paths
}
fun sourceDependencies(modules: Collection<FirModuleData>) {
allRegularDependencies += modules
filtersMap.getValue(binaryModuleData.dependsOn) += paths
}
fun sourceFriendsDependencies(modules: Collection<FirModuleData>) {
@@ -136,29 +85,25 @@ class DependencyListForCliModule(
.mapValues { LibraryPathFilter.LibraryList(it.value) }
.toMutableMap()
allRegularDependencies += binaryRegularDependenciesModuleData
allRegularDependencies += binaryModuleData.regular
if (pathFiltersMap.isEmpty()) {
return DependencyListForCliModule(
platform,
analyzerServices,
allRegularDependencies,
dependsOnDependencies = allDependsOnDependencies,
friendsDependencies = allFriendsDependencies,
SingleModuleDataProvider(binaryRegularDependenciesModuleData)
SingleModuleDataProvider(binaryModuleData.regular)
)
}
if (binaryFriendsModuleData in pathFiltersMap) {
allFriendsDependencies += binaryFriendsModuleData
if (binaryModuleData.friends in pathFiltersMap) {
allFriendsDependencies += binaryModuleData.friends
}
if (binaryDependsOnModuleData in pathFiltersMap) {
allDependsOnDependencies += binaryDependsOnModuleData
if (binaryModuleData.dependsOn in pathFiltersMap) {
allDependsOnDependencies += binaryModuleData.dependsOn
}
val moduleDataProvider = MultipleModuleDataProvider(pathFiltersMap)
pathFiltersMap.putIfAbsent(binaryRegularDependenciesModuleData, LibraryPathFilter.TakeAll)
pathFiltersMap.putIfAbsent(binaryModuleData.regular, LibraryPathFilter.TakeAll)
return DependencyListForCliModule(
platform,
analyzerServices,
allRegularDependencies,
allDependsOnDependencies,
allFriendsDependencies,
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
@@ -17,34 +18,65 @@ import org.jetbrains.kotlin.fir.backend.jvm.FirJvmKotlinMangler
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmVisibilityConverter
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmDescriptorMangler
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
data class FirResult(
val platformOutput: ModuleCompilerAnalyzedOutput,
val commonOutput: ModuleCompilerAnalyzedOutput?
)
data class ModuleCompilerAnalyzedOutput(
val session: FirSession,
val scopeSession: ScopeSession,
val fir: List<FirFile>
)
fun ModuleCompilerAnalyzedOutput.convertToIr(
fun FirResult.convertToIrAndActualize(
fir2IrExtensions: Fir2IrExtensions,
irGeneratorExtensions: Collection<IrGenerationExtension>,
linkViaSignatures: Boolean
linkViaSignatures: Boolean,
): Fir2IrResult {
val commonFirFiles = session.moduleData.dependsOnDependencies
.map { it.session }
.filter { it.kind == FirSession.Kind.Source }
.flatMap { (it.firProvider as FirProviderImpl).getAllFirFiles() }
val result: Fir2IrResult
if (commonOutput != null) {
val commonIrOutput = commonOutput.convertToIr(
fir2IrExtensions,
irGeneratorExtensions,
linkViaSignatures = true,
dependentComponents = emptyList()
)
result = platformOutput.convertToIr(
fir2IrExtensions,
irGeneratorExtensions,
linkViaSignatures = true,
dependentComponents = listOf(commonIrOutput.components)
)
// TODO: implement IR actualization
} else {
result = platformOutput.convertToIr(
fir2IrExtensions,
irGeneratorExtensions,
linkViaSignatures = linkViaSignatures,
dependentComponents = emptyList()
)
}
return result
}
private fun ModuleCompilerAnalyzedOutput.convertToIr(
fir2IrExtensions: Fir2IrExtensions,
irGeneratorExtensions: Collection<IrGenerationExtension>,
linkViaSignatures: Boolean,
dependentComponents: List<Fir2IrComponents>
): Fir2IrResult {
if (linkViaSignatures) {
val signaturer = JvmIdSignatureDescriptor(mangler = JvmDescriptorMangler(mainDetector = null))
return Fir2IrConverter.createModuleFragmentWithSignaturesIfNeeded(
session, scopeSession, fir + commonFirFiles,
session, scopeSession, fir,
session.languageVersionSettings, signaturer, fir2IrExtensions,
FirJvmKotlinMangler(session),
JvmIrMangler, IrFactoryImpl, FirJvmVisibilityConverter,
@@ -55,7 +87,7 @@ fun ModuleCompilerAnalyzedOutput.convertToIr(
)
} else {
return Fir2IrConverter.createModuleFragmentWithoutSignatures(
session, scopeSession, fir + commonFirFiles,
session, scopeSession, fir,
session.languageVersionSettings, fir2IrExtensions,
FirJvmKotlinMangler(session),
JvmIrMangler, IrFactoryImpl, FirJvmVisibilityConverter,
@@ -6,17 +6,13 @@
package org.jetbrains.kotlin.fir.session
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.checkers.registerCommonCheckers
import org.jetbrains.kotlin.fir.checkers.registerJsCheckers
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.extensions.FirSwitchableExtensionDeclarationsSymbolProvider
import org.jetbrains.kotlin.fir.java.FirCliSession
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
import org.jetbrains.kotlin.fir.resolve.providers.FirDependenciesSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
@@ -25,7 +21,6 @@ import org.jetbrains.kotlin.fir.resolve.providers.impl.FirDependenciesSymbolProv
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirLibrarySessionProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.name.Name
@@ -54,12 +49,12 @@ abstract class FirAbstractSessionFactory {
val kotlinScopeProvider = createKotlinScopeProvider.invoke()
register(FirKotlinScopeProvider::class, kotlinScopeProvider)
val builtinsModuleData = DependencyListForCliModule.createDependencyModuleData(
val builtinsModuleData = BinaryModuleData.createDependencyModuleData(
Name.special("<builtins of ${mainModuleName.asString()}"),
moduleDataProvider.platform,
moduleDataProvider.analyzerServices,
)
builtinsModuleData.bindSession(this@session)
builtinsModuleData.bindSession(this)
val providers = createProviders(this, builtinsModuleData, kotlinScopeProvider)
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.checkers.registerJvmCheckers
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
import org.jetbrains.kotlin.fir.deserialization.SingleModuleDataProvider
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
@@ -29,7 +30,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
fun createLibrarySession(
mainModuleName: Name,
sessionProvider: FirProjectSessionProvider,
dependencyList: DependencyListForCliModule,
moduleDataProvider: ModuleDataProvider,
projectEnvironment: AbstractProjectEnvironment,
scope: AbstractProjectFileSearchScope,
packagePartProvider: PackagePartProvider,
@@ -39,7 +40,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
return createLibrarySession(
mainModuleName,
sessionProvider,
dependencyList.moduleDataProvider,
moduleDataProvider,
languageVersionSettings,
registerExtraComponents = {
it.registerCommonJavaComponents(projectEnvironment.getJavaModuleResolver())
@@ -50,15 +51,20 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
listOf(
JvmClassFileBasedSymbolProvider(
session,
dependencyList.moduleDataProvider,
moduleDataProvider,
kotlinScopeProvider,
packagePartProvider,
projectEnvironment.getKotlinClassFinder(scope),
projectEnvironment.getFirJavaFacade(session, dependencyList.moduleDataProvider.allModuleData.last(), scope)
projectEnvironment.getFirJavaFacade(session, moduleDataProvider.allModuleData.last(), scope)
),
FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider),
FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider),
OptionalAnnotationClassesProvider(session, dependencyList.moduleDataProvider, kotlinScopeProvider, packagePartProvider)
OptionalAnnotationClassesProvider(
session,
moduleDataProvider,
kotlinScopeProvider,
packagePartProvider
)
)
}
)
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.checkers.registerNativeCheckers
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory
@@ -24,11 +25,10 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
mainModuleName: Name,
resolvedLibraries: List<KotlinResolvedLibrary>,
sessionProvider: FirProjectSessionProvider,
dependencyListForCliModule: DependencyListForCliModule,
moduleDataProvider: ModuleDataProvider,
languageVersionSettings: LanguageVersionSettings,
registerExtraComponents: ((FirSession) -> Unit) = {},
): FirSession {
val moduleDataProvider = dependencyListForCliModule.moduleDataProvider
return createLibrarySession(
mainModuleName,
sessionProvider,
@@ -38,13 +38,14 @@ object FirSessionFactoryHelper {
dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {},
noinline sessionConfigurator: FirSessionConfigurator.() -> Unit = {},
): FirSession {
val dependencyList = DependencyListForCliModule.build(moduleName, platform, analyzerServices, dependenciesConfigurator)
val binaryModuleData = BinaryModuleData.initialize(moduleName, platform, analyzerServices)
val dependencyList = DependencyListForCliModule.build(binaryModuleData, init = dependenciesConfigurator)
val sessionProvider = externalSessionProvider ?: FirProjectSessionProvider()
val packagePartProvider = projectEnvironment.getPackagePartProvider(librariesScope)
FirJvmSessionFactory.createLibrarySession(
moduleName,
sessionProvider,
dependencyList,
dependencyList.moduleDataProvider,
projectEnvironment,
librariesScope,
packagePartProvider,
@@ -57,8 +58,8 @@ object FirSessionFactoryHelper {
dependencyList.regularDependencies,
dependencyList.dependsOnDependencies,
dependencyList.friendsDependencies,
dependencyList.platform,
dependencyList.analyzerServices
platform,
analyzerServices
)
return FirJvmSessionFactory.createModuleBasedSession(
mainModuleData,