[FIR2IR] Make convertAndActualize method the only entrypoint to fir2ir

Fir2Ir conversion consists of multiple steps with complex logic (like
  conversion of each module, actualization, plugins application, constant
  evaluation), and to ensure that they all are executed correctly it's
  convenient to have the single entry point for all this machinery
This commit is contained in:
Dmitriy Novozhilov
2023-11-21 13:15:21 +02:00
committed by Space Team
parent 075010b14e
commit e38b25c278
14 changed files with 228 additions and 399 deletions
@@ -16,11 +16,7 @@ import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.analysis.api.impl.base.util.KtCompiledFileForOutputFile import org.jetbrains.kotlin.analysis.api.impl.base.util.KtCompiledFileForOutputFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirInternals import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirInternals
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.DiagnosticCheckerFilter import org.jetbrains.kotlin.analysis.low.level.api.fir.api.*
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.collectDiagnosticsForFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getModule
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedId import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedId
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedValueAnalyzer import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CodeFragmentCapturedValueAnalyzer
import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CompilationPeerCollector import org.jetbrains.kotlin.analysis.low.level.api.fir.compile.CompilationPeerCollector
@@ -73,11 +69,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.util.DelicateSymbolTableApi import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.classId
import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
@@ -91,7 +83,7 @@ import org.jetbrains.kotlin.resolve.source.PsiSourceFile
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.runIf import org.jetbrains.kotlin.utils.addToStdlib.runIf
import java.util.Collections import java.util.*
internal class KtFirCompilerFacility( internal class KtFirCompilerFacility(
override val analysisSession: KtFirAnalysisSession override val analysisSession: KtFirAnalysisSession
@@ -185,7 +177,7 @@ internal class KtFirCompilerFacility(
ProgressManager.checkCanceled() ProgressManager.checkCanceled()
val irGeneratorExtensions = IrGenerationExtension.getInstances(project) val irGeneratorExtensions = IrGenerationExtension.getInstances(project)
targetFir2IrResult.components.applyIrGenerationExtensions(targetFir2IrResult.irModuleFragment, irGeneratorExtensions) targetFir2IrResult.pluginContext.applyIrGenerationExtensions(targetFir2IrResult.irModuleFragment, irGeneratorExtensions)
val bindingContext = NoScopeRecordCliBindingTrace().bindingContext val bindingContext = NoScopeRecordCliBindingTrace().bindingContext
val codegenFactory = createJvmIrCodegenFactory(targetConfiguration, file is KtCodeFragment, targetFir2IrResult.irModuleFragment) val codegenFactory = createJvmIrCodegenFactory(targetConfiguration, file is KtCodeFragment, targetFir2IrResult.irModuleFragment)
@@ -261,8 +261,8 @@ fun transformFirToIr(
visibilityConverter = Fir2IrVisibilityConverter.Default, visibilityConverter = Fir2IrVisibilityConverter.Default,
kotlinBuiltIns = builtInsModule ?: DefaultBuiltIns.Instance, kotlinBuiltIns = builtInsModule ?: DefaultBuiltIns.Instance,
actualizerTypeContextProvider = ::IrTypeSystemContextImpl actualizerTypeContextProvider = ::IrTypeSystemContextImpl
) { ) { _, irPart ->
(this.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = librariesDescriptors } (irPart.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = librariesDescriptors }
} }
} }
@@ -31,29 +31,7 @@ data class ModuleCompilerAnalyzedOutput(
val session: FirSession, val session: FirSession,
val scopeSession: ScopeSession, val scopeSession: ScopeSession,
val fir: List<FirFile> val fir: List<FirFile>
) { )
fun convertToIr(
fir2IrExtensions: Fir2IrExtensions,
fir2IrConfiguration: Fir2IrConfiguration,
commonMemberStorage: Fir2IrCommonMemberStorage,
irBuiltIns: IrBuiltInsOverFir?,
irMangler: KotlinMangler.IrMangler,
visibilityConverter: Fir2IrVisibilityConverter,
kotlinBuiltIns: KotlinBuiltIns,
typeContextProvider: (IrBuiltIns) -> IrTypeSystemContext,
): Fir2IrResult {
return Fir2IrConverter.createIrModuleFragment(
session, scopeSession, fir,
fir2IrExtensions, fir2IrConfiguration,
irMangler, IrFactoryImpl, visibilityConverter,
Fir2IrJvmSpecialAnnotationSymbolProvider(), // TODO KT-60526: replace with appropriate (probably empty) implementation for other backends.
kotlinBuiltIns = kotlinBuiltIns,
commonMemberStorage = commonMemberStorage,
initializedIrBuiltIns = irBuiltIns,
typeContextProvider = typeContextProvider
)
}
}
data class Fir2IrActualizedResult( data class Fir2IrActualizedResult(
val irModuleFragment: IrModuleFragment, val irModuleFragment: IrModuleFragment,
@@ -81,7 +59,7 @@ fun FirResult.convertToIrAndActualize(
visibilityConverter: Fir2IrVisibilityConverter, visibilityConverter: Fir2IrVisibilityConverter,
kotlinBuiltIns: KotlinBuiltIns, kotlinBuiltIns: KotlinBuiltIns,
actualizerTypeContextProvider: (IrBuiltIns) -> IrTypeSystemContext, actualizerTypeContextProvider: (IrBuiltIns) -> IrTypeSystemContext,
fir2IrResultPostCompute: Fir2IrResult.() -> Unit = {}, fir2IrResultPostCompute: (ModuleCompilerAnalyzedOutput, Fir2IrResult) -> Unit = { _, _ -> },
): Fir2IrActualizedResult { ): Fir2IrActualizedResult {
val fir2IrResult: Fir2IrResult val fir2IrResult: Fir2IrResult
val actualizationResult: IrActualizedResult? val actualizationResult: IrActualizedResult?
@@ -91,7 +69,9 @@ fun FirResult.convertToIrAndActualize(
when (outputs.size) { when (outputs.size) {
0 -> error("No modules found") 0 -> error("No modules found")
1 -> { 1 -> {
fir2IrResult = outputs.single().convertToIr( val output = outputs.single()
fir2IrResult = convertToIr(
output,
fir2IrExtensions, fir2IrExtensions,
fir2IrConfiguration, fir2IrConfiguration,
commonMemberStorage = commonMemberStorage, commonMemberStorage = commonMemberStorage,
@@ -101,7 +81,7 @@ fun FirResult.convertToIrAndActualize(
kotlinBuiltIns, kotlinBuiltIns,
actualizerTypeContextProvider, actualizerTypeContextProvider,
).also { result -> ).also { result ->
fir2IrResultPostCompute(result) fir2IrResultPostCompute(output, result)
} }
actualizationResult = null actualizationResult = null
} }
@@ -110,10 +90,11 @@ fun FirResult.convertToIrAndActualize(
val commonOutputs = outputs.dropLast(1) val commonOutputs = outputs.dropLast(1)
var irBuiltIns: IrBuiltInsOverFir? = null var irBuiltIns: IrBuiltInsOverFir? = null
val commonIrOutputs = commonOutputs.map { val commonIrOutputs = commonOutputs.map {
it.convertToIr( convertToIr(
fir2IrExtensions, it,
// We need to build all modules before rebuilding fake overrides // We need to build all modules before rebuilding fake overrides
// to avoid fixing declaration storages // to avoid fixing declaration storages
fir2IrExtensions,
fir2IrConfiguration.copy(useIrFakeOverrideBuilder = false), fir2IrConfiguration.copy(useIrFakeOverrideBuilder = false),
commonMemberStorage = commonMemberStorage, commonMemberStorage = commonMemberStorage,
irBuiltIns = irBuiltIns, irBuiltIns = irBuiltIns,
@@ -122,13 +103,14 @@ fun FirResult.convertToIrAndActualize(
kotlinBuiltIns, kotlinBuiltIns,
actualizerTypeContextProvider, actualizerTypeContextProvider,
).also { result -> ).also { result ->
fir2IrResultPostCompute(result) fir2IrResultPostCompute(it, result)
if (irBuiltIns == null) { if (irBuiltIns == null) {
irBuiltIns = result.components.irBuiltIns irBuiltIns = result.components.irBuiltIns
} }
} }
} }
fir2IrResult = platformOutput.convertToIr( fir2IrResult = convertToIr(
platformOutput,
fir2IrExtensions, fir2IrExtensions,
fir2IrConfiguration, fir2IrConfiguration,
commonMemberStorage = commonMemberStorage, commonMemberStorage = commonMemberStorage,
@@ -138,7 +120,7 @@ fun FirResult.convertToIrAndActualize(
kotlinBuiltIns, kotlinBuiltIns,
actualizerTypeContextProvider, actualizerTypeContextProvider,
).also { ).also {
fir2IrResultPostCompute(it) fir2IrResultPostCompute(platformOutput, it)
} }
actualizationResult = IrActualizer.actualize( actualizationResult = IrActualizer.actualize(
@@ -158,13 +140,31 @@ fun FirResult.convertToIrAndActualize(
} }
val (irModuleFragment, components, pluginContext) = fir2IrResult val (irModuleFragment, components, pluginContext) = fir2IrResult
components.applyIrGenerationExtensions(irModuleFragment, irGeneratorExtensions) pluginContext.applyIrGenerationExtensions(irModuleFragment, irGeneratorExtensions)
return Fir2IrActualizedResult(irModuleFragment, components, pluginContext, actualizationResult) return Fir2IrActualizedResult(irModuleFragment, components, pluginContext, actualizationResult)
} }
fun Fir2IrComponents.applyIrGenerationExtensions(irModuleFragment: IrModuleFragment, irGenerationExtensions: Collection<IrGenerationExtension>) { private fun convertToIr(
if (irGenerationExtensions.isEmpty()) return firOutput: ModuleCompilerAnalyzedOutput,
Fir2IrPluginContext(this, irModuleFragment.descriptor).applyIrGenerationExtensions(irModuleFragment, irGenerationExtensions) fir2IrExtensions: Fir2IrExtensions,
fir2IrConfiguration: Fir2IrConfiguration,
commonMemberStorage: Fir2IrCommonMemberStorage,
irBuiltIns: IrBuiltInsOverFir?,
irMangler: KotlinMangler.IrMangler,
visibilityConverter: Fir2IrVisibilityConverter,
kotlinBuiltIns: KotlinBuiltIns,
typeContextProvider: (IrBuiltIns) -> IrTypeSystemContext,
): Fir2IrResult {
return Fir2IrConverter.createIrModuleFragment(
firOutput.session, firOutput.scopeSession, firOutput.fir,
fir2IrExtensions, fir2IrConfiguration,
irMangler, IrFactoryImpl, visibilityConverter,
Fir2IrJvmSpecialAnnotationSymbolProvider(), // TODO KT-60526: replace with appropriate (probably empty) implementation for other backends.
kotlinBuiltIns = kotlinBuiltIns,
commonMemberStorage = commonMemberStorage,
initializedIrBuiltIns = irBuiltIns,
typeContextProvider = typeContextProvider
)
} }
fun IrPluginContext.applyIrGenerationExtensions(irModuleFragment: IrModuleFragment, irGenerationExtensions: Collection<IrGenerationExtension>) { fun IrPluginContext.applyIrGenerationExtensions(irModuleFragment: IrModuleFragment, irGenerationExtensions: Collection<IrGenerationExtension>) {
@@ -172,4 +172,4 @@ fun IrPluginContext.applyIrGenerationExtensions(irModuleFragment: IrModuleFragme
for (extension in irGenerationExtensions) { for (extension in irGenerationExtensions) {
extension.generate(irModuleFragment, this) extension.generate(irModuleFragment, this)
} }
} }
@@ -73,7 +73,7 @@ sealed class IrBackendInput : ResultingArtifact.BackendInput<IrBackendInput>() {
override val descriptorMangler: KotlinMangler.DescriptorMangler, override val descriptorMangler: KotlinMangler.DescriptorMangler,
override val irMangler: KotlinMangler.IrMangler, override val irMangler: KotlinMangler.IrMangler,
override val firMangler: FirMangler?, override val firMangler: FirMangler?,
val serializeSingleFile: (KtSourceFile, IrActualizedResult?) -> ProtoBuf.PackageFragment, val serializeSingleFile: (KtSourceFile) -> ProtoBuf.PackageFragment,
) : IrBackendInput() ) : IrBackendInput()
data class JsIrDeserializedFromKlibBackendInput( data class JsIrDeserializedFromKlibBackendInput(
@@ -99,7 +99,7 @@ sealed class IrBackendInput : ResultingArtifact.BackendInput<IrBackendInput>() {
override val descriptorMangler: KotlinMangler.DescriptorMangler, override val descriptorMangler: KotlinMangler.DescriptorMangler,
override val irMangler: KotlinMangler.IrMangler, override val irMangler: KotlinMangler.IrMangler,
override val firMangler: FirMangler?, override val firMangler: FirMangler?,
val serializeSingleFile: (KtSourceFile, IrActualizedResult?) -> ProtoBuf.PackageFragment, val serializeSingleFile: (KtSourceFile) -> ProtoBuf.PackageFragment,
) : IrBackendInput() ) : IrBackendInput()
class JvmIrBackendInput( class JvmIrBackendInput(
@@ -117,7 +117,7 @@ class ClassicFrontend2IrConverter(
descriptorMangler = (pluginContext.symbolTable as SymbolTable).signaturer.mangler, descriptorMangler = (pluginContext.symbolTable as SymbolTable).signaturer.mangler,
irMangler = JsManglerIr, irMangler = JsManglerIr,
firMangler = null, firMangler = null,
) { file, _ -> ) { file ->
metadataSerializer.serializeScope(file, analysisResult.bindingContext, moduleFragment.descriptor) metadataSerializer.serializeScope(file, analysisResult.bindingContext, moduleFragment.descriptor)
} }
} }
@@ -159,7 +159,7 @@ class ClassicFrontend2IrConverter(
descriptorMangler = (pluginContext.symbolTable as SymbolTable).signaturer.mangler, descriptorMangler = (pluginContext.symbolTable as SymbolTable).signaturer.mangler,
irMangler = JsManglerIr, irMangler = JsManglerIr,
firMangler = null, firMangler = null,
) { file, _ -> ) { file ->
metadataSerializer.serializeScope(file, analysisResult.bindingContext, moduleFragment.descriptor) metadataSerializer.serializeScope(file, analysisResult.bindingContext, moduleFragment.descriptor)
} }
} }
@@ -6,22 +6,24 @@
package org.jetbrains.kotlin.test.frontend.fir package org.jetbrains.kotlin.test.frontend.fir
import org.jetbrains.kotlin.KtSourceFile import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.constant.EvaluatedConstTracker import org.jetbrains.kotlin.constant.EvaluatedConstTracker
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.backend.js.FirJsKotlinMangler import org.jetbrains.kotlin.fir.backend.js.FirJsKotlinMangler
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.pipeline.FirResult
import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput
import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize
import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension
import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -30,7 +32,6 @@ import org.jetbrains.kotlin.ir.backend.js.getSerializedData
import org.jetbrains.kotlin.ir.backend.js.incrementalDataProvider import org.jetbrains.kotlin.ir.backend.js.incrementalDataProvider
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
import org.jetbrains.kotlin.library.unresolvedDependencies import org.jetbrains.kotlin.library.unresolvedDependencies
@@ -70,65 +71,62 @@ class Fir2IrJsResultsConverter(
inputArtifact: FirOutputArtifact inputArtifact: FirOutputArtifact
): IrBackendInput { ): IrBackendInput {
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module) val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
lateinit var mainIrPart: IrModuleFragment
val dependentIrParts = mutableListOf<IrModuleFragment>()
val sourceFiles = mutableListOf<KtSourceFile>() val sourceFiles = mutableListOf<KtSourceFile>()
val firFilesAndComponentsBySourceFile = mutableMapOf<KtSourceFile, Pair<FirFile, Fir2IrComponents>>() val firFilesAndComponentsBySourceFile = mutableMapOf<KtSourceFile, Pair<FirFile, Fir2IrComponents>>()
lateinit var mainPluginContext: IrPluginContext
var irBuiltIns: IrBuiltInsOverFir? = null
val commonMemberStorage = Fir2IrCommonMemberStorage(IdSignatureDescriptor(JsManglerDesc), FirJsKotlinMangler())
val irMangler = JsManglerIr val irMangler = JsManglerIr
val diagnosticReporter = DiagnosticReporterFactory.createReporter() val diagnosticReporter = DiagnosticReporterFactory.createReporter()
for ((index, part) in inputArtifact.partsForDependsOnModules.withIndex()) { val libraries = resolveLibraries(configuration, getAllJsDependenciesPaths(module, testServices))
val (irModuleFragment, components, pluginContext) = val (dependencies, builtIns) = loadResolvedLibraries(libraries, configuration.languageVersionSettings, testServices)
part.firAnalyzerFacade.result.outputs.single().convertToJsIr(
testServices,
module,
configuration,
diagnosticReporter,
commonMemberStorage,
irBuiltIns,
)
irBuiltIns = components.irBuiltIns
mainPluginContext = pluginContext
if (index < inputArtifact.partsForDependsOnModules.size - 1) { val fir2IrConfiguration = Fir2IrConfiguration(
dependentIrParts.add(irModuleFragment) languageVersionSettings = configuration.languageVersionSettings,
} else { diagnosticReporter = diagnosticReporter,
mainIrPart = irModuleFragment linkViaSignatures = true,
} evaluatedConstTracker = configuration
.putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()),
sourceFiles.addAll(part.firFiles.mapNotNull { it.value.sourceFile }) inlineConstTracker = null,
expectActualTracker = configuration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
for (firFile in part.firFiles.values) { allowNonCachedDeclarations = false,
firFilesAndComponentsBySourceFile[firFile.sourceFile!!] = firFile to components useIrFakeOverrideBuilder = module.shouldUseIrFakeOverrideBuilderInConvertToIr()
)
val fir2irResult = inputArtifact.toFirResult().convertToIrAndActualize(
Fir2IrExtensions.Default,
fir2IrConfiguration,
module.irGenerationExtensions(testServices),
IdSignatureDescriptor(JsManglerDesc),
JsManglerIr,
FirJsKotlinMangler(),
Fir2IrVisibilityConverter.Default,
builtIns ?: DefaultBuiltIns.Instance, // TODO: consider passing externally,
::IrTypeSystemContextImpl
) { firPart, irPart ->
sourceFiles.addAll(firPart.fir.mapNotNull { it.sourceFile })
for (firFile in firPart.fir) {
firFilesAndComponentsBySourceFile[firFile.sourceFile!!] = firFile to irPart.components
} }
}.also {
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = dependencies }
} }
val metadataVersion = configuration.metadataVersion(module.languageVersionSettings.languageVersion) val metadataVersion = configuration.metadataVersion(module.languageVersionSettings.languageVersion)
var actualizedExpectDeclarations: Set<FirDeclaration>? = null return IrBackendInput.JsIrBackendInput(
fir2irResult.irModuleFragment,
val result = IrBackendInput.JsIrBackendInput( fir2irResult.pluginContext,
mainIrPart,
mainPluginContext,
sourceFiles, sourceFiles,
configuration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList(), configuration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList(),
diagnosticReporter = diagnosticReporter, diagnosticReporter = diagnosticReporter,
hasErrors = inputArtifact.hasErrors, hasErrors = inputArtifact.hasErrors,
descriptorMangler = commonMemberStorage.symbolTable.signaturer.mangler, descriptorMangler = fir2irResult.components.symbolTable.signaturer.mangler,
irMangler = irMangler, irMangler = irMangler,
firMangler = commonMemberStorage.firSignatureComposer.mangler, firMangler = fir2irResult.components.signatureComposer.mangler,
) { file, irActualizedResult -> ) { file ->
val (firFile, components) = firFilesAndComponentsBySourceFile[file] val (firFile, components) = firFilesAndComponentsBySourceFile[file]
?: error("cannot find FIR file by source file ${file.name} (${file.path})") ?: error("cannot find FIR file by source file ${file.name} (${file.path})")
if (actualizedExpectDeclarations == null && irActualizedResult != null) { val actualizedExpectDeclarations = fir2irResult.irActualizedResult?.actualizedExpectDeclarations?.extractFirDeclarations()
actualizedExpectDeclarations = irActualizedResult.actualizedExpectDeclarations.extractFirDeclarations()
}
serializeSingleFirFile( serializeSingleFirFile(
firFile, firFile,
components.session, components.session,
@@ -143,45 +141,6 @@ class Fir2IrJsResultsConverter(
configuration.languageVersionSettings, configuration.languageVersionSettings,
) )
} }
return result
}
}
fun ModuleCompilerAnalyzedOutput.convertToJsIr(
testServices: TestServices,
module: TestModule,
configuration: CompilerConfiguration,
diagnosticReporter: DiagnosticReporter,
commonMemberStorage: Fir2IrCommonMemberStorage,
irBuiltIns: IrBuiltInsOverFir?
): Fir2IrResult {
// TODO: consider avoiding repeated libraries resolution
val libraries = resolveLibraries(configuration, getAllJsDependenciesPaths(module, testServices))
val (dependencies, builtIns) = loadResolvedLibraries(libraries, configuration.languageVersionSettings, testServices)
val fir2IrConfiguration = Fir2IrConfiguration(
languageVersionSettings = configuration.languageVersionSettings,
diagnosticReporter = diagnosticReporter,
linkViaSignatures = true,
evaluatedConstTracker = configuration
.putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()),
inlineConstTracker = null,
expectActualTracker = configuration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
allowNonCachedDeclarations = false,
useIrFakeOverrideBuilder = module.shouldUseIrFakeOverrideBuilderInConvertToIr()
)
return convertToIr(
Fir2IrExtensions.Default,
fir2IrConfiguration,
commonMemberStorage,
irBuiltIns,
JsManglerIr,
Fir2IrVisibilityConverter.Default,
builtIns ?: DefaultBuiltIns.Instance, // TODO: consider passing externally,
::IrTypeSystemContextImpl
).also {
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = dependencies }
} }
} }
@@ -216,3 +175,14 @@ private fun loadResolvedLibraries(
} }
} to builtInsModule } to builtInsModule
} }
fun TestModule.irGenerationExtensions(testServices: TestServices): Collection<IrGenerationExtension> {
return IrGenerationExtension.getInstances(testServices.compilerConfigurationProvider.getProject(this))
}
fun FirOutputArtifact.toFirResult(): FirResult {
val outputs = partsForDependsOnModules.map {
ModuleCompilerAnalyzedOutput(it.session, it.firAnalyzerFacade.scopeSession, it.firFiles.values.toList())
}
return FirResult(outputs)
}
@@ -20,14 +20,12 @@ import org.jetbrains.kotlin.constant.EvaluatedConstTracker
import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.backend.Fir2IrCommonMemberStorage import org.jetbrains.kotlin.fir.backend.Fir2IrCommonMemberStorage
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.Fir2IrConfiguration import org.jetbrains.kotlin.fir.backend.Fir2IrConfiguration
import org.jetbrains.kotlin.fir.backend.IrBuiltInsOverFir
import org.jetbrains.kotlin.fir.backend.jvm.* import org.jetbrains.kotlin.fir.backend.jvm.*
import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize
import org.jetbrains.kotlin.fir.pipeline.signatureComposerForJvmFir2Ir import org.jetbrains.kotlin.fir.pipeline.signatureComposerForJvmFir2Ir
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.CompilerEnvironment import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
@@ -86,57 +84,46 @@ class Fir2IrJvmResultsConverter(
val phaseConfig = configuration.get(CLIConfigurationKeys.PHASE_CONFIG) val phaseConfig = configuration.get(CLIConfigurationKeys.PHASE_CONFIG)
val dependentIrParts = mutableListOf<IrModuleFragment>()
lateinit var backendInput: JvmIrCodegenFactory.JvmIrBackendInput
lateinit var mainModuleComponents: Fir2IrComponents
val generateSignatures = compilerConfigurationProvider.getCompilerConfiguration(module) val generateSignatures = compilerConfigurationProvider.getCompilerConfiguration(module)
.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES) .getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES)
val commonMemberStorage = Fir2IrCommonMemberStorage(signatureComposerForJvmFir2Ir(generateSignatures), FirJvmKotlinMangler()) val commonMemberStorage = Fir2IrCommonMemberStorage(signatureComposerForJvmFir2Ir(generateSignatures), FirJvmKotlinMangler())
var irBuiltIns: IrBuiltInsOverFir? = null
val diagnosticReporter = DiagnosticReporterFactory.createReporter() val diagnosticReporter = DiagnosticReporterFactory.createReporter()
for ((index, firOutputPart) in inputArtifact.partsForDependsOnModules.withIndex()) { val compilerConfiguration = compilerConfigurationProvider.getCompilerConfiguration(module)
val compilerConfiguration = compilerConfigurationProvider.getCompilerConfiguration(module) val fir2IrConfiguration = Fir2IrConfiguration(
val fir2IrConfiguration = Fir2IrConfiguration( languageVersionSettings = module.languageVersionSettings,
languageVersionSettings = module.languageVersionSettings, diagnosticReporter = diagnosticReporter,
diagnosticReporter = diagnosticReporter, linkViaSignatures = compilerConfiguration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES),
linkViaSignatures = compilerConfiguration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES), evaluatedConstTracker = compilerConfiguration
evaluatedConstTracker = compilerConfiguration .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()),
.putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()), inlineConstTracker = compilerConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER],
inlineConstTracker = compilerConfiguration[CommonConfigurationKeys.INLINE_CONST_TRACKER], expectActualTracker = compilerConfiguration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
expectActualTracker = compilerConfiguration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER], allowNonCachedDeclarations = false,
allowNonCachedDeclarations = false, useIrFakeOverrideBuilder = module.shouldUseIrFakeOverrideBuilderInConvertToIr(),
useIrFakeOverrideBuilder = module.shouldUseIrFakeOverrideBuilderInConvertToIr(), )
)
val (irModuleFragment, components, pluginContext) = firOutputPart.firAnalyzerFacade.result.outputs.single().convertToIr(
fir2IrExtensions,
fir2IrConfiguration,
commonMemberStorage,
irBuiltIns,
irMangler,
FirJvmVisibilityConverter,
DefaultBuiltIns.Instance,
typeContextProvider = ::JvmIrTypeSystemContext,
)
irBuiltIns = components.irBuiltIns
if (index < inputArtifact.partsForDependsOnModules.size - 1) { val fir2irResult = inputArtifact.toFirResult().convertToIrAndActualize(
dependentIrParts.add(irModuleFragment) fir2IrExtensions,
} else { fir2IrConfiguration,
mainModuleComponents = components module.irGenerationExtensions(testServices),
backendInput = JvmIrCodegenFactory.JvmIrBackendInput( signatureComposerForJvmFir2Ir(generateSignatures),
irModuleFragment, irMangler,
components.symbolTable, FirJvmKotlinMangler(),
phaseConfig, FirJvmVisibilityConverter,
components.irProviders, DefaultBuiltIns.Instance,
fir2IrExtensions, ::JvmIrTypeSystemContext
FirJvmBackendExtension(components, actualizedExpectDeclarations = null), )
pluginContext,
notifyCodegenStart = {}, val backendInput = JvmIrCodegenFactory.JvmIrBackendInput(
) fir2irResult.irModuleFragment,
} fir2irResult.components.symbolTable,
} phaseConfig,
fir2irResult.components.irProviders,
fir2IrExtensions,
FirJvmBackendExtension(fir2irResult.components, actualizedExpectDeclarations = null),
fir2irResult.pluginContext,
notifyCodegenStart = {},
)
val codegenFactory = JvmIrCodegenFactory(configuration, phaseConfig) val codegenFactory = JvmIrCodegenFactory(configuration, phaseConfig)
val generationState = GenerationState.Builder( val generationState = GenerationState.Builder(
@@ -145,12 +132,12 @@ class Fir2IrJvmResultsConverter(
).isIrBackend( ).isIrBackend(
true true
).jvmBackendClassResolver( ).jvmBackendClassResolver(
FirJvmBackendClassResolver(mainModuleComponents) FirJvmBackendClassResolver(fir2irResult.components)
).diagnosticReporter( ).diagnosticReporter(
diagnosticReporter diagnosticReporter
).build() ).build()
val result = IrBackendInput.JvmIrBackendInput( return IrBackendInput.JvmIrBackendInput(
generationState, generationState,
codegenFactory, codegenFactory,
backendInput, backendInput,
@@ -159,7 +146,5 @@ class Fir2IrJvmResultsConverter(
irMangler = irMangler, irMangler = irMangler,
firMangler = commonMemberStorage.firSignatureComposer.mangler, firMangler = commonMemberStorage.firSignatureComposer.mangler,
) )
return result
} }
} }
@@ -6,25 +6,21 @@
package org.jetbrains.kotlin.test.frontend.fir package org.jetbrains.kotlin.test.frontend.fir
import org.jetbrains.kotlin.KtSourceFile import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.constant.EvaluatedConstTracker import org.jetbrains.kotlin.constant.EvaluatedConstTracker
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.backend.js.FirJsKotlinMangler import org.jetbrains.kotlin.fir.backend.js.FirJsKotlinMangler
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize
import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension
import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -33,7 +29,6 @@ import org.jetbrains.kotlin.ir.backend.js.getSerializedData
import org.jetbrains.kotlin.ir.backend.js.incrementalDataProvider import org.jetbrains.kotlin.ir.backend.js.incrementalDataProvider
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
import org.jetbrains.kotlin.library.unresolvedDependencies import org.jetbrains.kotlin.library.unresolvedDependencies
@@ -74,49 +69,53 @@ class Fir2IrWasmResultsConverter(
): IrBackendInput { ): IrBackendInput {
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module) val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
lateinit var mainIrPart: IrModuleFragment
val dependentIrParts = mutableListOf<IrModuleFragment>()
val sourceFiles = mutableListOf<KtSourceFile>() val sourceFiles = mutableListOf<KtSourceFile>()
val firFilesAndComponentsBySourceFile = mutableMapOf<KtSourceFile, Pair<FirFile, Fir2IrComponents>>() val firFilesAndComponentsBySourceFile = mutableMapOf<KtSourceFile, Pair<FirFile, Fir2IrComponents>>()
lateinit var mainPluginContext: IrPluginContext
var irBuiltIns: IrBuiltInsOverFir? = null
val commonMemberStorage = Fir2IrCommonMemberStorage(IdSignatureDescriptor(JsManglerDesc), FirJsKotlinMangler())
val diagnosticReporter = DiagnosticReporterFactory.createReporter() val diagnosticReporter = DiagnosticReporterFactory.createReporter()
for ((index, part) in inputArtifact.partsForDependsOnModules.withIndex()) { // TODO: consider avoiding repeated libraries resolution
val (irModuleFragment, components, pluginContext) = val libraries = resolveWasmLibraries(module, testServices, configuration)
part.firAnalyzerFacade.result.outputs.single().convertToWasmIr( val (dependencies, builtIns) = loadResolvedLibraries(libraries, configuration.languageVersionSettings, testServices)
testServices,
module,
configuration,
diagnosticReporter,
commonMemberStorage,
irBuiltIns,
)
irBuiltIns = components.irBuiltIns
mainPluginContext = pluginContext
if (index < inputArtifact.partsForDependsOnModules.size - 1) { val fir2IrConfiguration = Fir2IrConfiguration(
dependentIrParts.add(irModuleFragment) languageVersionSettings = configuration.languageVersionSettings,
} else { diagnosticReporter = diagnosticReporter,
mainIrPart = irModuleFragment linkViaSignatures = true,
} evaluatedConstTracker = configuration
.putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()),
sourceFiles.addAll(part.firFiles.mapNotNull { it.value.sourceFile }) inlineConstTracker = null,
expectActualTracker = configuration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
for (firFile in part.firFiles.values) { allowNonCachedDeclarations = false,
firFilesAndComponentsBySourceFile[firFile.sourceFile!!] = firFile to components useIrFakeOverrideBuilder = module.shouldUseIrFakeOverrideBuilderInConvertToIr(),
)
val fir2irResult = inputArtifact.toFirResult().convertToIrAndActualize(
Fir2IrExtensions.Default,
fir2IrConfiguration,
module.irGenerationExtensions(testServices),
IdSignatureDescriptor(JsManglerDesc),
JsManglerIr,
FirJsKotlinMangler(),
Fir2IrVisibilityConverter.Default,
builtIns ?: DefaultBuiltIns.Instance, // TODO: consider passing externally,
::IrTypeSystemContextImpl
) { firPart, irPart ->
sourceFiles.addAll(firPart.fir.mapNotNull { it.sourceFile })
for (firFile in firPart.fir) {
firFilesAndComponentsBySourceFile[firFile.sourceFile!!] = firFile to irPart.components
} }
}.also {
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = dependencies }
} }
val commonMemberStorage = Fir2IrCommonMemberStorage(IdSignatureDescriptor(JsManglerDesc), FirJsKotlinMangler())
val metadataVersion = configuration.metadataVersion(module.languageVersionSettings.languageVersion) val metadataVersion = configuration.metadataVersion(module.languageVersionSettings.languageVersion)
var actualizedExpectDeclarations: Set<FirDeclaration>? = null
return IrBackendInput.WasmBackendInput( return IrBackendInput.WasmBackendInput(
mainIrPart, fir2irResult.irModuleFragment,
mainPluginContext, fir2irResult.pluginContext,
sourceFiles, sourceFiles,
configuration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList(), configuration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList(),
diagnosticReporter = diagnosticReporter, diagnosticReporter = diagnosticReporter,
@@ -124,12 +123,11 @@ class Fir2IrWasmResultsConverter(
descriptorMangler = commonMemberStorage.symbolTable.signaturer.mangler, descriptorMangler = commonMemberStorage.symbolTable.signaturer.mangler,
irMangler = JsManglerIr, irMangler = JsManglerIr,
firMangler = commonMemberStorage.firSignatureComposer.mangler, firMangler = commonMemberStorage.firSignatureComposer.mangler,
) { file, irActualizedResult -> ) { file ->
val (firFile, components) = firFilesAndComponentsBySourceFile[file] val (firFile, components) = firFilesAndComponentsBySourceFile[file]
?: error("cannot find FIR file by source file ${file.name} (${file.path})") ?: error("cannot find FIR file by source file ${file.name} (${file.path})")
if (actualizedExpectDeclarations == null && irActualizedResult != null) {
actualizedExpectDeclarations = irActualizedResult.actualizedExpectDeclarations.extractFirDeclarations() val actualizedExpectDeclarations = fir2irResult.irActualizedResult?.actualizedExpectDeclarations?.extractFirDeclarations()
}
serializeSingleFirFile( serializeSingleFirFile(
firFile, firFile,
components.session, components.session,
@@ -147,44 +145,6 @@ class Fir2IrWasmResultsConverter(
} }
} }
fun ModuleCompilerAnalyzedOutput.convertToWasmIr(
testServices: TestServices,
module: TestModule,
configuration: CompilerConfiguration,
diagnosticReporter: DiagnosticReporter,
commonMemberStorage: Fir2IrCommonMemberStorage,
irBuiltIns: IrBuiltInsOverFir?
): Fir2IrResult {
// TODO: consider avoiding repeated libraries resolution
val libraries = resolveWasmLibraries(module, testServices, configuration)
val (dependencies, builtIns) = loadResolvedLibraries(libraries, configuration.languageVersionSettings, testServices)
val fir2IrConfiguration = Fir2IrConfiguration(
languageVersionSettings = configuration.languageVersionSettings,
diagnosticReporter = diagnosticReporter,
linkViaSignatures = true,
evaluatedConstTracker = configuration
.putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()),
inlineConstTracker = null,
expectActualTracker = configuration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
allowNonCachedDeclarations = false,
useIrFakeOverrideBuilder = module.shouldUseIrFakeOverrideBuilderInConvertToIr(),
)
return convertToIr(
Fir2IrExtensions.Default,
fir2IrConfiguration,
commonMemberStorage,
irBuiltIns,
JsManglerIr,
Fir2IrVisibilityConverter.Default,
builtIns ?: DefaultBuiltIns.Instance, // TODO: consider passing externally
typeContextProvider = ::IrTypeSystemContextImpl,
).also {
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = dependencies }
}
}
private fun loadResolvedLibraries( private fun loadResolvedLibraries(
resolvedLibraries: List<KotlinResolvedLibrary>, resolvedLibraries: List<KotlinResolvedLibrary>,
languageVersionSettings: LanguageVersionSettings, languageVersionSettings: LanguageVersionSettings,
@@ -15,8 +15,6 @@ import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.backend.jvm.JvmIrDeserializerImpl import org.jetbrains.kotlin.backend.jvm.JvmIrDeserializerImpl
import org.jetbrains.kotlin.backend.jvm.JvmIrTypeSystemContext
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector
@@ -25,19 +23,17 @@ import org.jetbrains.kotlin.cli.common.output.writeAllTo
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.cli.jvm.compiler.pipeline.convertToIrAndActualizeForJvm
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.constant.EvaluatedConstTracker
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.FirAnalyzerFacade import org.jetbrains.kotlin.fir.FirAnalyzerFacade
import org.jetbrains.kotlin.fir.FirTestSessionFactoryHelper import org.jetbrains.kotlin.fir.FirTestSessionFactoryHelper
import org.jetbrains.kotlin.fir.backend.Fir2IrCommonMemberStorage import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.Fir2IrConfiguration import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
import org.jetbrains.kotlin.fir.backend.jvm.* import org.jetbrains.kotlin.fir.backend.jvm.JvmFir2IrExtensions
import org.jetbrains.kotlin.fir.pipeline.signatureComposerForJvmFir2Ir
import org.jetbrains.kotlin.ir.backend.jvm.jvmResolveLibraries import org.jetbrains.kotlin.ir.backend.jvm.jvmResolveLibraries
import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler import org.jetbrains.kotlin.ir.backend.jvm.serialization.JvmIrMangler
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
@@ -118,7 +114,6 @@ object GenerationUtils {
getPackagePartProvider = packagePartProvider getPackagePartProvider = packagePartProvider
) )
val linkViaSignatures = configuration.getBoolean(JVMConfigurationKeys.LINK_VIA_SIGNATURES)
// TODO: add running checkers and check that it's safe to compile // TODO: add running checkers and check that it's safe to compile
val firAnalyzerFacade = FirAnalyzerFacade( val firAnalyzerFacade = FirAnalyzerFacade(
session, session,
@@ -129,32 +124,14 @@ object GenerationUtils {
val fir2IrExtensions = JvmFir2IrExtensions(configuration, JvmIrDeserializerImpl(), JvmIrMangler) val fir2IrExtensions = JvmFir2IrExtensions(configuration, JvmIrDeserializerImpl(), JvmIrMangler)
val diagnosticReporter = DiagnosticReporterFactory.createReporter() val diagnosticReporter = DiagnosticReporterFactory.createReporter()
val fir2IrConfiguration = Fir2IrConfiguration(
languageVersionSettings = configuration.languageVersionSettings,
diagnosticReporter = diagnosticReporter,
linkViaSignatures = linkViaSignatures,
evaluatedConstTracker = configuration
.putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()),
inlineConstTracker = configuration[CommonConfigurationKeys.INLINE_CONST_TRACKER],
expectActualTracker = configuration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
allowNonCachedDeclarations = false,
useIrFakeOverrideBuilder = configuration.getBoolean(CommonConfigurationKeys.USE_IR_FAKE_OVERRIDE_BUILDER),
)
val commonMemberStorage = Fir2IrCommonMemberStorage(signatureComposerForJvmFir2Ir(linkViaSignatures), FirJvmKotlinMangler())
firAnalyzerFacade.runResolution() firAnalyzerFacade.runResolution()
val (moduleFragment, components, pluginContext) = firAnalyzerFacade.result.outputs.single().convertToIr( val (moduleFragment, components, pluginContext) = firAnalyzerFacade.result.convertToIrAndActualizeForJvm(
fir2IrExtensions, fir2IrExtensions,
fir2IrConfiguration, configuration,
commonMemberStorage, diagnosticReporter,
irBuiltIns = null, irGeneratorExtensions = emptyList()
JvmIrMangler,
FirJvmVisibilityConverter,
DefaultBuiltIns.Instance,
::JvmIrTypeSystemContext
) )
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
val codegenFactory = JvmIrCodegenFactory( val codegenFactory = JvmIrCodegenFactory(
@@ -74,7 +74,7 @@ class FirJsKlibBackendFacade(
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
jsOutputName = null jsOutputName = null
) { ) {
inputArtifact.serializeSingleFile(it, TODO("Will be fixed in the next commit")) inputArtifact.serializeSingleFile(it)
} }
} }
@@ -63,7 +63,7 @@ class JsKlibBackendFacade(
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
jsOutputName = null jsOutputName = null
) { ) {
inputArtifact.serializeSingleFile(it, TODO("Will be fixed in the next commit")) inputArtifact.serializeSingleFile(it)
} }
} }
@@ -40,7 +40,9 @@ import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
import org.jetbrains.kotlin.ir.declarations.IrMemberWithContainerSource import org.jetbrains.kotlin.ir.declarations.IrMemberWithContainerSource
import org.jetbrains.kotlin.ir.objcinterop.IrObjCOverridabilityCondition import org.jetbrains.kotlin.ir.objcinterop.IrObjCOverridabilityCondition
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.DelicateSymbolTableApi
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.getPackageFragment
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.library.isNativeStdlib import org.jetbrains.kotlin.library.isNativeStdlib
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
@@ -115,9 +117,9 @@ internal fun PhaseContext.fir2Ir(
visibilityConverter = Fir2IrVisibilityConverter.Default, visibilityConverter = Fir2IrVisibilityConverter.Default,
kotlinBuiltIns = builtInsModule ?: DefaultBuiltIns.Instance, kotlinBuiltIns = builtInsModule ?: DefaultBuiltIns.Instance,
actualizerTypeContextProvider = ::IrTypeSystemContextImpl, actualizerTypeContextProvider = ::IrTypeSystemContextImpl,
fir2IrResultPostCompute = { fir2IrResultPostCompute = { _, irOutput ->
// it's important to compare manglers before actualization, since IR will be actualized, while FIR won't // it's important to compare manglers before actualization, since IR will be actualized, while FIR won't
irModuleFragment.acceptVoid( irOutput.irModuleFragment.acceptVoid(
ManglerChecker( ManglerChecker(
KonanManglerIr, KonanManglerIr,
Ir2FirManglerAdapter(FirNativeKotlinMangler), Ir2FirManglerAdapter(FirNativeKotlinMangler),
@@ -5,8 +5,6 @@
package org.jetbrains.kotlin.konan.test package org.jetbrains.kotlin.konan.test
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc
@@ -15,32 +13,27 @@ import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.constant.EvaluatedConstTracker import org.jetbrains.kotlin.constant.EvaluatedConstTracker
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.Fir2IrConfiguration
import org.jetbrains.kotlin.fir.backend.Fir2IrExtensions
import org.jetbrains.kotlin.fir.backend.Fir2IrVisibilityConverter
import org.jetbrains.kotlin.fir.backend.native.FirNativeKotlinMangler import org.jetbrains.kotlin.fir.backend.native.FirNativeKotlinMangler
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.util.KotlinMangler
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
import org.jetbrains.kotlin.library.unresolvedDependencies import org.jetbrains.kotlin.library.unresolvedDependencies
import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact import org.jetbrains.kotlin.test.frontend.fir.*
import org.jetbrains.kotlin.test.frontend.fir.getAllNativeDependenciesPaths
import org.jetbrains.kotlin.test.frontend.fir.resolveLibraries
import org.jetbrains.kotlin.test.model.BackendKinds import org.jetbrains.kotlin.test.model.BackendKinds
import org.jetbrains.kotlin.test.model.Frontend2BackendConverter import org.jetbrains.kotlin.test.model.Frontend2BackendConverter
import org.jetbrains.kotlin.test.model.FrontendKinds import org.jetbrains.kotlin.test.model.FrontendKinds
@@ -74,92 +67,43 @@ class Fir2IrNativeResultsConverter(
): IrBackendInput { ): IrBackendInput {
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module) val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
lateinit var mainIrPart: IrModuleFragment val libraries = resolveLibraries(configuration, getAllNativeDependenciesPaths(module, testServices))
val dependentIrParts = mutableListOf<IrModuleFragment>() val (dependencies, builtIns) = loadResolvedLibraries(libraries, configuration.languageVersionSettings, testServices)
val sourceFiles = mutableListOf<KtSourceFile>()
val firFilesAndComponentsBySourceFile = mutableMapOf<KtSourceFile, Pair<FirFile, Fir2IrComponents>>()
lateinit var mainPluginContext: IrPluginContext
var irBuiltIns: IrBuiltInsOverFir? = null
val commonMemberStorage = Fir2IrCommonMemberStorage(IdSignatureDescriptor(KonanManglerDesc), FirNativeKotlinMangler)
val diagnosticReporter = DiagnosticReporterFactory.createReporter() val diagnosticReporter = DiagnosticReporterFactory.createReporter()
val fir2IrConfiguration = Fir2IrConfiguration(
for ((index, part) in inputArtifact.partsForDependsOnModules.withIndex()) { languageVersionSettings = configuration.languageVersionSettings,
val (irModuleFragment, components, pluginContext) = diagnosticReporter = diagnosticReporter,
part.firAnalyzerFacade.result.outputs.single().convertToNativeIr( linkViaSignatures = true,
testServices, evaluatedConstTracker = configuration
module, .putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()),
configuration, inlineConstTracker = null,
diagnosticReporter, allowNonCachedDeclarations = false,
commonMemberStorage, expectActualTracker = configuration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
irBuiltIns, useIrFakeOverrideBuilder = configuration.getBoolean(CommonConfigurationKeys.USE_IR_FAKE_OVERRIDE_BUILDER),
KonanManglerIr )
) val fir2irResult = inputArtifact.toFirResult().convertToIrAndActualize(
irBuiltIns = components.irBuiltIns Fir2IrExtensions.Default,
mainPluginContext = pluginContext fir2IrConfiguration,
module.irGenerationExtensions(testServices),
if (index < inputArtifact.partsForDependsOnModules.size - 1) { IdSignatureDescriptor(KonanManglerDesc),
dependentIrParts.add(irModuleFragment) KonanManglerIr,
} else { FirNativeKotlinMangler,
mainIrPart = irModuleFragment Fir2IrVisibilityConverter.Default,
} builtIns ?: DefaultBuiltIns.Instance, // TODO: consider passing externally,
::IrTypeSystemContextImpl
sourceFiles.addAll(part.firFiles.mapNotNull { it.value.sourceFile }) ).also {
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = dependencies }
for (firFile in part.firFiles.values) {
firFilesAndComponentsBySourceFile[firFile.sourceFile!!] = firFile to components
}
} }
val result = IrBackendInput.NativeBackendInput( return IrBackendInput.NativeBackendInput(
mainIrPart, fir2irResult.irModuleFragment,
mainPluginContext, fir2irResult.pluginContext,
diagnosticReporter = diagnosticReporter, diagnosticReporter = diagnosticReporter,
descriptorMangler = commonMemberStorage.symbolTable.signaturer.mangler, descriptorMangler = fir2irResult.components.symbolTable.signaturer.mangler,
irMangler = KonanManglerIr, irMangler = KonanManglerIr,
firMangler = commonMemberStorage.firSignatureComposer.mangler, firMangler = fir2irResult.components.signatureComposer.mangler,
) )
return result
}
}
fun ModuleCompilerAnalyzedOutput.convertToNativeIr(
testServices: TestServices,
module: TestModule,
configuration: CompilerConfiguration,
diagnosticReporter: DiagnosticReporter,
commonMemberStorage: Fir2IrCommonMemberStorage,
irBuiltIns: IrBuiltInsOverFir?,
irMangler: KotlinMangler.IrMangler,
): Fir2IrResult {
// TODO: consider avoiding repeated libraries resolution
val libraries = resolveLibraries(configuration, getAllNativeDependenciesPaths(module, testServices))
val (dependencies, builtIns) = loadResolvedLibraries(libraries, configuration.languageVersionSettings, testServices)
val fir2IrConfiguration = Fir2IrConfiguration(
languageVersionSettings = configuration.languageVersionSettings,
diagnosticReporter = diagnosticReporter,
linkViaSignatures = true,
evaluatedConstTracker = configuration
.putIfAbsent(CommonConfigurationKeys.EVALUATED_CONST_TRACKER, EvaluatedConstTracker.create()),
inlineConstTracker = null,
allowNonCachedDeclarations = false,
expectActualTracker = configuration[CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER],
useIrFakeOverrideBuilder = configuration.getBoolean(CommonConfigurationKeys.USE_IR_FAKE_OVERRIDE_BUILDER),
)
return convertToIr(
Fir2IrExtensions.Default,
fir2IrConfiguration,
commonMemberStorage,
irBuiltIns,
irMangler,
Fir2IrVisibilityConverter.Default,
builtIns ?: DefaultBuiltIns.Instance, // TODO: consider passing externally,
::IrTypeSystemContextImpl
).also {
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = dependencies }
} }
} }
@@ -196,4 +140,3 @@ private fun loadResolvedLibraries(
} }
} to builtInsModule } to builtInsModule
} }
@@ -74,7 +74,7 @@ class FirWasmKlibBackendFacade(
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
jsOutputName = null jsOutputName = null
) { ) {
inputArtifact.serializeSingleFile(it, TODO("Will be fixed in the next commit")) inputArtifact.serializeSingleFile(it)
} }
} }