[klib] Don't pass around metadata serialization closure

Pass the metadata serializer instance instead. This allows to further
reduce code duplication by introducing the common interface
`KlibSingleFileMetadataSerializer` for abstracting away K1 and K2
representation of a source file, as well as reusing
`Fir2KlibMetadataSerializer` across different backends.

KT-64392
This commit is contained in:
Sergej Jaskiewicz
2024-01-22 14:21:20 +01:00
committed by Space Team
parent 5a6f51e474
commit f39335b3f7
23 changed files with 388 additions and 406 deletions
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.pipeline.Fir2KlibMetadataSerializer
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
@@ -470,13 +471,6 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
sourceModule.getModuleDescriptor(it)
}
val metadataSerializer =
KlibMetadataIncrementalSerializer(
environmentForJS.configuration,
sourceModule.project,
sourceModule.jsFrontEndResult.hasErrors
)
val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter()
generateKLib(
sourceModule,
@@ -486,10 +480,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
icData = icData,
moduleFragment = moduleFragment,
diagnosticReporter = diagnosticsReporter,
builtInsPlatform = if (arguments.wasm) BuiltInsPlatform.WASM else BuiltInsPlatform.JS
) { file ->
metadataSerializer.serializeScope(file, sourceModule.jsFrontEndResult.bindingContext, moduleFragment.descriptor)
}
builtInsPlatform = if (arguments.wasm) BuiltInsPlatform.WASM else BuiltInsPlatform.JS,
)
val messageCollector = environmentForJS.configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
reportCollectedDiagnostics(environmentForJS.configuration, diagnosticsReporter, messageCollector)
@@ -562,7 +554,16 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
// This happens because we check the next round before compilation errors.
// Test reproducer: testFileWithConstantRemoved
// Issue: https://youtrack.jetbrains.com/issue/KT-58824/
if (shouldGoToNextIcRound(moduleStructure, analyzedOutput.output, fir2IrActualizedResult)) {
val shouldGoToNextIcRound = shouldGoToNextIcRound(moduleStructure.compilerConfiguration) {
Fir2KlibMetadataSerializer(
moduleStructure.compilerConfiguration,
analyzedOutput.output,
fir2IrActualizedResult,
exportKDoc = false,
produceHeaderKlib = false,
)
}
if (shouldGoToNextIcRound) {
throw IncrementalNextRoundException()
}
}
@@ -22,13 +22,13 @@ import org.jetbrains.kotlin.diagnostics.impl.PendingDiagnosticsCollectorWithSupp
import org.jetbrains.kotlin.fir.BinaryModuleData
import org.jetbrains.kotlin.fir.DependencyListForCliModule
import org.jetbrains.kotlin.fir.FirSession
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.js.FirJsKotlinMangler
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.pipeline.*
import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension
import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile
import org.jetbrains.kotlin.fir.session.KlibIcData
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
@@ -41,16 +41,13 @@ import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.library.impl.BuiltInsPlatform
import org.jetbrains.kotlin.library.unresolvedDependencies
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.platform.wasm.WasmPlatforms
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.utils.metadataVersion
import org.jetbrains.kotlin.wasm.resolve.WasmJsPlatformAnalyzerServices
import org.jetbrains.kotlin.wasm.resolve.WasmWasiPlatformAnalyzerServices
import java.io.File
import java.nio.file.Paths
inline fun <F> compileModuleToAnalyzedFir(
@@ -253,50 +250,6 @@ fun transformFirToIr(
}
}
private class Fir2KlibSerializer(
moduleStructure: ModulesStructure,
private val firOutputs: List<ModuleCompilerAnalyzedOutput>,
private val fir2IrActualizedResult: Fir2IrActualizedResult
) {
private val firFilesAndSessionsBySourceFile = buildMap {
for (output in firOutputs) {
output.fir.forEach {
put(it.sourceFile!!, it)
}
}
}
private val actualizedExpectDeclarations by lazy {
fir2IrActualizedResult.irActualizedResult?.actualizedExpectDeclarations?.extractFirDeclarations()
}
private val metadataVersion = moduleStructure.compilerConfiguration.metadataVersion()
private val languageVersionSettings = moduleStructure.compilerConfiguration.languageVersionSettings
val sourceFiles: List<KtSourceFile> = firFilesAndSessionsBySourceFile.keys.toList()
fun serializeSingleFirFile(file: KtSourceFile): ProtoBuf.PackageFragment {
val firFile = firFilesAndSessionsBySourceFile[file]
?: error("cannot find FIR file by source file ${file.name} (${file.path})")
val components = fir2IrActualizedResult.components
return serializeSingleFirFile(
firFile,
components.session,
components.scopeSession,
actualizedExpectDeclarations,
FirKLibSerializerExtension(
components.session, components.firProvider, metadataVersion,
ConstValueProviderImpl(components),
allowErrorTypes = false, exportKDoc = false,
components.annotationsFromPluginRegistrar.createAdditionalMetadataProvider()
),
languageVersionSettings,
)
}
}
fun serializeFirKlib(
moduleStructure: ModulesStructure,
firOutputs: List<ModuleCompilerAnalyzedOutput>,
@@ -308,14 +261,20 @@ fun serializeFirKlib(
jsOutputName: String?,
useWasmPlatform: Boolean,
) {
val fir2KlibSerializer = Fir2KlibSerializer(moduleStructure, firOutputs, fir2IrActualizedResult)
val icData = moduleStructure.compilerConfiguration.incrementalDataProvider?.getSerializedData(fir2KlibSerializer.sourceFiles)
val fir2KlibMetadataSerializer = Fir2KlibMetadataSerializer(
moduleStructure.compilerConfiguration,
firOutputs,
fir2IrActualizedResult,
exportKDoc = false,
produceHeaderKlib = false,
)
val icData = moduleStructure.compilerConfiguration.incrementalDataProvider?.getSerializedData(fir2KlibMetadataSerializer.sourceFiles)
serializeModuleIntoKlib(
moduleStructure.compilerConfiguration[CommonConfigurationKeys.MODULE_NAME]!!,
moduleStructure.compilerConfiguration,
diagnosticsReporter,
fir2KlibSerializer.sourceFiles,
fir2KlibMetadataSerializer,
klibPath = outputKlibPath,
moduleStructure.allDependencies,
fir2IrActualizedResult.irModuleFragment,
@@ -325,27 +284,6 @@ fun serializeFirKlib(
containsErrorCode = messageCollector.hasErrors() || diagnosticsReporter.hasErrors,
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
jsOutputName = jsOutputName,
serializeSingleFile = fir2KlibSerializer::serializeSingleFirFile,
builtInsPlatform = if (useWasmPlatform) BuiltInsPlatform.WASM else BuiltInsPlatform.JS,
)
}
fun shouldGoToNextIcRound(
moduleStructure: ModulesStructure,
firOutputs: List<ModuleCompilerAnalyzedOutput>,
fir2IrActualizedResult: Fir2IrActualizedResult
): Boolean {
val nextRoundChecker = moduleStructure.compilerConfiguration.get(JSConfigurationKeys.INCREMENTAL_NEXT_ROUND_CHECKER) ?: return false
val fir2KlibSerializer = Fir2KlibSerializer(moduleStructure, firOutputs, fir2IrActualizedResult)
for (ktFile in fir2KlibSerializer.sourceFiles) {
val packageFragment = fir2KlibSerializer.serializeSingleFirFile(ktFile)
// to minimize a number of IC rounds, we should inspect all proto for changes first,
// then go to a next round if needed, with all new dirty files
nextRoundChecker.checkProtoChanges(File(ktFile.path!!), packageFragment.toByteArray())
}
return nextRoundChecker.shouldGoToNextRound()
}
@@ -0,0 +1,103 @@
/*
* Copyright 2010-2024 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.pipeline
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.ConstValueProviderImpl
import org.jetbrains.kotlin.fir.backend.extractFirDeclarations
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.packageFqName
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension
import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile
import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.FqName
/**
* Responsible for serializing a FIR file metadata into a protobuf to be later written to a KLIB.
*/
class Fir2KlibMetadataSerializer(
compilerConfiguration: CompilerConfiguration,
private val firOutputs: List<ModuleCompilerAnalyzedOutput>,
private val fir2IrActualizedResult: Fir2IrActualizedResult?,
private val exportKDoc: Boolean,
private val produceHeaderKlib: Boolean,
) : KlibSingleFileMetadataSerializer<FirFile> {
private val firFilesAndSessions: Map<FirFile, Pair<FirSession, ScopeSession>> =
buildMap {
for (firOutput in firOutputs) {
for (firFile in firOutput.fir) {
put(firFile, firOutput.session to firOutput.scopeSession)
}
}
}
private val actualizedExpectDeclarations by lazy {
fir2IrActualizedResult?.irActualizedResult?.actualizedExpectDeclarations?.extractFirDeclarations()
}
private val languageVersionSettings = compilerConfiguration.languageVersionSettings
private val metadataVersion = compilerConfiguration.get(CommonConfigurationKeys.METADATA_VERSION) as? KlibMetadataVersion
?: KlibMetadataVersion.INSTANCE
/**
* The list of source files whose metadata is to be serialized.
*/
val sourceFiles: List<KtSourceFile> = firFilesAndSessions.keys.map { it.sourceFile!! }
override val numberOfSourceFiles: Int
get() = firFilesAndSessions.size
override fun serializeSingleFileMetadata(file: FirFile): ProtoBuf.PackageFragment {
val session: FirSession
val scopeSession: ScopeSession
val firProvider: FirProvider
val components = fir2IrActualizedResult?.components
if (components != null) {
session = components.session
scopeSession = components.scopeSession
firProvider = components.firProvider
} else {
val sessionAndScopeSession = firFilesAndSessions[file] ?: error("Missing FirSession and ScopeSession")
session = sessionAndScopeSession.first
scopeSession = sessionAndScopeSession.second
firProvider = session.firProvider
}
return serializeSingleFirFile(
file,
session,
scopeSession,
actualizedExpectDeclarations,
FirKLibSerializerExtension(
session,
firProvider,
metadataVersion,
components?.let(::ConstValueProviderImpl),
allowErrorTypes = false,
exportKDoc,
components?.annotationsFromPluginRegistrar?.createAdditionalMetadataProvider(),
),
languageVersionSettings,
produceHeaderKlib,
)
}
override fun forEachFile(block: (Int, FirFile, KtSourceFile, FqName) -> Unit) {
firFilesAndSessions.keys.forEachIndexed { i, firFile ->
block(i, firFile, firFile.sourceFile!!, firFile.packageFqName)
}
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2024 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.backend.common.serialization.metadata
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.FqName
/**
* Something capable of serializing the metadata of a source file to a protobuf message, one file at a time.
*/
interface KlibSingleFileMetadataSerializer<SourceFile> {
/**
* The number of source files whose metadata is to be serialized.
*/
val numberOfSourceFiles: Int
/**
* Serializes the metadata of a single source file to a protobuf message and returns the message.
*/
fun serializeSingleFileMetadata(file: SourceFile): ProtoBuf.PackageFragment
/**
* Iterates through each file whose metadata is to be serialized, providing an opportunity to call [serializeSingleFileMetadata]
* and perform additional processing of the serialized data.
*
* @param block A closure that accepts the index of the file in the list of source files, the source file, its corresponding
* [KtSourceFile], and the fully qualified name of the package containing the file.
*/
fun forEachFile(block: (Int, SourceFile, KtSourceFile, FqName) -> Unit)
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.KtIoFileSourceFile
import org.jetbrains.kotlin.KtPsiSourceFile
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.KtVirtualFileSourceFile
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer
import org.jetbrains.kotlin.backend.common.serialization.metadata.serializeKlibHeader
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
@@ -24,8 +25,6 @@ import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.SerializedIrFile
import org.jetbrains.kotlin.library.SerializedIrModule
import org.jetbrains.kotlin.library.SerializedMetadata
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.FqName
import java.io.File
/**
@@ -86,24 +85,22 @@ fun KtSourceFile.toIoFileOrNull(): File? = when (this) {
* @param irModuleFragment The IR to be serialized into the KLIB being produced, or `null` if this is going to be a metadata-only KLIB.
* @param configuration Used to determine certain serialization parameters and enable/disable serialization diagnostics.
* @param diagnosticReporter Used for reporting serialization-time diagnostics, for example, about clashing IR signatures.
* @param sourceFiles The source files from which the KLIB is being compiled. Used for serializing file metadata.
* @param compatibilityMode The information about KLIB ABI.
* @param cleanFiles In the case of incremental compilation, the list of files that were not changed and therefore don't need to be
* serialized again.
* @param dependencies The list of KLIBs that the KLIB being produced depends on.
* @param createModuleSerializer Used for creating a backend-specific instance of [IrModuleSerializer].
* @param serializeFileMetadata The name of this argument kind of speaks for itself.
* @param metadataSerializer Something capable of serializing the metadata of the source files. See the corresponding interface KDoc.
* @param runKlibCheckers Additional checks to be run before serializing [irModuleFragment]. Can be used to report serialization-time
* diagnostics.
* @param processCompiledFileData Called for each newly serialized file. Useful for incremental compilation.
* @param processKlibHeader Called after serializing the KLIB header. Useful for incremental compilation.
*/
fun <Dependency : KotlinLibrary> serializeModuleIntoKlib(
fun <Dependency : KotlinLibrary, SourceFile> serializeModuleIntoKlib(
moduleName: String,
irModuleFragment: IrModuleFragment?,
configuration: CompilerConfiguration,
diagnosticReporter: DiagnosticReporter,
sourceFiles: List<KtSourceFile>,
compatibilityMode: CompatibilityMode,
cleanFiles: List<KotlinFileSerializedData>,
dependencies: List<Dependency>,
@@ -116,14 +113,14 @@ fun <Dependency : KotlinLibrary> serializeModuleIntoKlib(
languageVersionSettings: LanguageVersionSettings,
shouldCheckSignaturesOnUniqueness: Boolean,
) -> IrModuleSerializer<*>,
serializeFileMetadata: (KtSourceFile) -> Pair<ProtoBuf.PackageFragment, FqName>,
metadataSerializer: KlibSingleFileMetadataSerializer<SourceFile>,
runKlibCheckers: (IrModuleFragment, IrDiagnosticReporter, CompilerConfiguration) -> Unit = { _, _, _ -> },
processCompiledFileData: ((File, KotlinFileSerializedData) -> Unit)? = null,
processKlibHeader: (ByteArray) -> Unit = {},
): SerializerOutput<Dependency> {
if (irModuleFragment != null) {
assert(sourceFiles.size == irModuleFragment.files.size) {
"The number of source files (${sourceFiles.size}) does not match the number of IrFiles (${irModuleFragment.files.size})"
assert(metadataSerializer.numberOfSourceFiles == irModuleFragment.files.size) {
"The number of source files (${metadataSerializer.numberOfSourceFiles}) does not match the number of IrFiles (${irModuleFragment.files.size})"
}
}
@@ -147,28 +144,31 @@ fun <Dependency : KotlinLibrary> serializeModuleIntoKlib(
val serializedFiles = serializedIr?.files?.toList()
val compiledKotlinFiles = sourceFiles.mapIndexedTo(cleanFiles.toMutableList()) { i, ktSourceFile ->
val binaryFile = serializedFiles?.get(i)?.also {
assert(ktSourceFile.path == it.path) {
"""The Kt and Ir files are put in different order
Kt: ${ktSourceFile.path}
Ir: ${it.path}
""".trimMargin()
val compiledKotlinFiles = buildList {
addAll(cleanFiles)
metadataSerializer.forEachFile { i, sourceFile, ktSourceFile, packageFqName ->
val binaryFile = serializedFiles?.get(i)?.also {
assert(ktSourceFile.path == it.path) {
"""The Kt and Ir files are put in different order
Kt: ${ktSourceFile.path}
Ir: ${it.path}
""".trimMargin()
}
}
}
val (packageFragment, fqName) = serializeFileMetadata(ktSourceFile)
val metadata = packageFragment.toByteArray()
val compiledKotlinFile = if (binaryFile == null)
KotlinFileSerializedData(metadata, ktSourceFile.path, fqName.asString())
else
KotlinFileSerializedData(metadata, binaryFile)
val protoBuf = metadataSerializer.serializeSingleFileMetadata(sourceFile)
val metadata = protoBuf.toByteArray()
val compiledKotlinFile = if (binaryFile == null)
KotlinFileSerializedData(metadata, ktSourceFile.path, packageFqName.asString())
else
KotlinFileSerializedData(metadata, binaryFile)
if (processCompiledFileData != null) {
val ioFile = ktSourceFile.toIoFileOrNull() ?: error("No file found for source ${ktSourceFile.path}")
processCompiledFileData(ioFile, compiledKotlinFile)
}
if (processCompiledFileData != null) {
val ioFile = ktSourceFile.toIoFileOrNull() ?: error("No file found for source ${ktSourceFile.path}")
processCompiledFileData(ioFile, compiledKotlinFile)
}
compiledKotlinFile
add(compiledKotlinFile)
}
}
val header = serializeKlibHeader(
@@ -6,21 +6,35 @@
package org.jetbrains.kotlin.ir.backend.js
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.KtPsiSourceFile
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataSerializer
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer
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.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContextUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.serialization.DescriptorSerializer
// TODO: need a refactoring between IncrementalSerializer and MonolithicSerializer.
class KlibMetadataIncrementalSerializer(
private val ktFiles: List<KtFile>,
private val bindingContext: BindingContext,
private val moduleDescriptor: ModuleDescriptor,
languageVersionSettings: LanguageVersionSettings,
metadataVersion: KlibMetadataVersion,
project: Project,
@@ -33,9 +47,54 @@ class KlibMetadataIncrementalSerializer(
exportKDoc = exportKDoc,
skipExpects = true, // Incremental compilation is not supposed to work when producing pure metadata (IR-less) KLIBs.
allowErrorTypes = allowErrorTypes
) {
), KlibSingleFileMetadataSerializer<KtFile> {
fun serializePackageFragment(
constructor(
files: List<KtFile>,
configuration: CompilerConfiguration,
project: Project,
bindingContext: BindingContext,
moduleDescriptor: ModuleDescriptor,
allowErrorTypes: Boolean,
) : this(
ktFiles = files,
bindingContext = bindingContext,
moduleDescriptor = moduleDescriptor,
languageVersionSettings = configuration.languageVersionSettings,
metadataVersion = configuration.get(CommonConfigurationKeys.METADATA_VERSION) as? KlibMetadataVersion
?: KlibMetadataVersion.INSTANCE,
project = project,
exportKDoc = false,
allowErrorTypes = allowErrorTypes,
)
constructor(modulesStructure: ModulesStructure, moduleFragment: IrModuleFragment) : this(
(modulesStructure.mainModule as MainModule.SourceFiles).files,
modulesStructure.compilerConfiguration,
modulesStructure.project,
modulesStructure.jsFrontEndResult.bindingContext,
moduleFragment.descriptor,
modulesStructure.jsFrontEndResult.hasErrors,
)
override fun serializeSingleFileMetadata(file: KtFile): ProtoBuf.PackageFragment {
val memberScope = file.declarations.map { getDescriptorForElement(bindingContext, it) }
return serializePackageFragment(moduleDescriptor, memberScope, file.packageFqName)
}
override val numberOfSourceFiles: Int
get() = ktFiles.size
override fun forEachFile(block: (Int, KtFile, KtSourceFile, FqName) -> Unit) {
ktFiles.forEachIndexed { i, ktFile ->
block(i, ktFile, KtPsiSourceFile(ktFile), ktFile.packageFqName)
}
}
private fun getDescriptorForElement(context: BindingContext, element: PsiElement): DeclarationDescriptor =
BindingContextUtils.getNotNull(context, BindingContext.DECLARATION_TO_DESCRIPTOR, element)
private fun serializePackageFragment(
module: ModuleDescriptor,
scope: Collection<DeclarationDescriptor>,
fqName: FqName
@@ -6,9 +6,8 @@
package org.jetbrains.kotlin.ir.backend.js
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.KtPsiSourceFile
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.analyzer.AbstractAnalyzerWithCompilerReport
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.analyzer.CompilationErrorException
@@ -22,12 +21,12 @@ import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker
import org.jetbrains.kotlin.backend.common.serialization.*
import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker
import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter
import org.jetbrains.kotlin.backend.common.serialization.metadata.*
import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor
import org.jetbrains.kotlin.backend.common.toLogger
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
@@ -55,8 +54,6 @@ import org.jetbrains.kotlin.library.impl.BuiltInsPlatform
import org.jetbrains.kotlin.library.impl.buildKotlinLibrary
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.progress.IncrementalNextRoundException
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.KtFile
@@ -66,7 +63,6 @@ import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContextUtils
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.DFS
@@ -94,9 +90,6 @@ val KotlinLibrary.serializedIrFileFingerprints: List<SerializedIrFileFingerprint
val KotlinLibrary.serializedKlibFingerprint: SerializedKlibFingerprint?
get() = manifestProperties.getProperty(KLIB_PROPERTY_SERIALIZED_KLIB_FINGERPRINT)?.let { SerializedKlibFingerprint.fromString(it) }
private val CompilerConfiguration.metadataVersion
get() = get(CommonConfigurationKeys.METADATA_VERSION) as? KlibMetadataVersion ?: KlibMetadataVersion.INSTANCE
internal val SerializedIrFile.fileMetadata: ByteArray
get() = backendSpecificMetadata ?: error("Expect file caches to have backendSpecificMetadata, but '$path' doesn't")
@@ -110,9 +103,7 @@ fun generateKLib(
moduleFragment: IrModuleFragment,
diagnosticReporter: DiagnosticReporter,
builtInsPlatform: BuiltInsPlatform = BuiltInsPlatform.JS,
serializeSingleFile: (KtSourceFile) -> ProtoBuf.PackageFragment
) {
val files = (depsDescriptors.mainModule as MainModule.SourceFiles).files.map(::KtPsiSourceFile)
val configuration = depsDescriptors.compilerConfiguration
val allDependencies = depsDescriptors.allDependencies
@@ -120,7 +111,7 @@ fun generateKLib(
configuration[CommonConfigurationKeys.MODULE_NAME]!!,
configuration,
diagnosticReporter,
files,
KlibMetadataIncrementalSerializer(depsDescriptors, moduleFragment),
outputKlibPath,
allDependencies,
moduleFragment,
@@ -131,7 +122,6 @@ fun generateKLib(
abiVersion,
jsOutputName,
builtInsPlatform,
serializeSingleFile
)
}
@@ -521,8 +511,19 @@ class ModulesStructure(
val analysisResult = analyzer.analysisResult
if (compilerConfiguration.getBoolean(CommonConfigurationKeys.INCREMENTAL_COMPILATION)) {
/** can throw [IncrementalNextRoundException] */
compareMetadataAndGoToNextICRoundIfNeeded(analysisResult, compilerConfiguration, project, files, errorPolicy.allowErrors)
val shouldGoToNextIcRound = shouldGoToNextIcRound(compilerConfiguration) {
KlibMetadataIncrementalSerializer(
files,
compilerConfiguration,
project,
analysisResult.bindingContext,
analysisResult.moduleDescriptor,
errorPolicy.allowErrors,
)
}
if (shouldGoToNextIcRound) {
throw IncrementalNextRoundException()
}
}
var hasErrors = false
@@ -589,12 +590,6 @@ class ModulesStructure(
null // null in case compiling builtInModule itself
}
private fun getDescriptorForElement(
context: BindingContext,
element: PsiElement
): DeclarationDescriptor = BindingContextUtils.getNotNull(context, BindingContext.DECLARATION_TO_DESCRIPTOR, element)
private const val FILE_FINGERPRINTS_SEPARATOR = " "
private fun List<SerializedIrFileFingerprint>.joinIrFileFingerprints(): String {
@@ -609,7 +604,7 @@ fun serializeModuleIntoKlib(
moduleName: String,
configuration: CompilerConfiguration,
diagnosticReporter: DiagnosticReporter,
files: List<KtSourceFile>,
metadataSerializer: KlibSingleFileMetadataSerializer<*>,
klibPath: String,
dependencies: List<KotlinLibrary>,
moduleFragment: IrModuleFragment,
@@ -620,7 +615,6 @@ fun serializeModuleIntoKlib(
abiVersion: KotlinAbiVersion,
jsOutputName: String?,
builtInsPlatform: BuiltInsPlatform = BuiltInsPlatform.JS,
serializeSingleFile: (KtSourceFile) -> ProtoBuf.PackageFragment
) {
val moduleExportedNames = moduleFragment.collectExportedNames()
val incrementalResultsConsumer = configuration.get(JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER)
@@ -630,7 +624,6 @@ fun serializeModuleIntoKlib(
irModuleFragment = moduleFragment,
configuration = configuration,
diagnosticReporter = diagnosticReporter,
sourceFiles = files,
compatibilityMode = CompatibilityMode(abiVersion),
cleanFiles = cleanFiles,
dependencies = dependencies,
@@ -653,7 +646,7 @@ fun serializeModuleIntoKlib(
shouldCheckSignaturesOnUniqueness,
) { JsIrFileMetadata(moduleExportedNames[it]?.values?.toSmartList() ?: emptyList()) }
},
serializeFileMetadata = { serializeSingleFile(it) to FqName.ROOT },
metadataSerializer = metadataSerializer,
runKlibCheckers = { irModuleFragment, irDiagnosticReporter, compilerConfiguration ->
if (builtInsPlatform == BuiltInsPlatform.JS) {
val cleanFilesIrData = cleanFiles.map { it.irData ?: error("Metadata-only KLIBs are not supported in Kotlin/JS") }
@@ -725,54 +718,22 @@ const val KLIB_PROPERTY_JS_OUTPUT_NAME = "jsOutputName"
const val KLIB_PROPERTY_SERIALIZED_IR_FILE_FINGERPRINTS = "serializedIrFileFingerprints"
const val KLIB_PROPERTY_SERIALIZED_KLIB_FINGERPRINT = "serializedKlibFingerprint"
fun KlibMetadataIncrementalSerializer.serializeScope(
ktFile: KtFile,
bindingContext: BindingContext,
moduleDescriptor: ModuleDescriptor
): ProtoBuf.PackageFragment {
val memberScope = ktFile.declarations.map { getDescriptorForElement(bindingContext, it) }
return serializePackageFragment(moduleDescriptor, memberScope, ktFile.packageFqName)
}
fun KlibMetadataIncrementalSerializer.serializeScope(
ktSourceFile: KtSourceFile,
bindingContext: BindingContext,
moduleDescriptor: ModuleDescriptor
): ProtoBuf.PackageFragment {
val ktFile = (ktSourceFile as KtPsiSourceFile).psiFile as KtFile
val memberScope = ktFile.declarations.map { getDescriptorForElement(bindingContext, it) }
return serializePackageFragment(moduleDescriptor, memberScope, ktFile.packageFqName)
}
private fun compareMetadataAndGoToNextICRoundIfNeeded(
analysisResult: AnalysisResult,
config: CompilerConfiguration,
project: Project,
files: List<KtFile>,
allowErrors: Boolean
) {
val nextRoundChecker = config.get(JSConfigurationKeys.INCREMENTAL_NEXT_ROUND_CHECKER) ?: return
val bindingContext = analysisResult.bindingContext
val serializer = KlibMetadataIncrementalSerializer(config, project, allowErrors)
for (ktFile in files) {
val packageFragment = serializer.serializeScope(ktFile, bindingContext, analysisResult.moduleDescriptor)
// to minimize a number of IC rounds, we should inspect all proto for changes first,
// then go to a next round if needed, with all new dirty files
nextRoundChecker.checkProtoChanges(VfsUtilCore.virtualToIoFile(ktFile.virtualFile), packageFragment.toByteArray())
fun <SourceFile> shouldGoToNextIcRound(
compilerConfiguration: CompilerConfiguration,
createMetadataSerializer: () -> KlibSingleFileMetadataSerializer<SourceFile>,
): Boolean {
val nextRoundChecker = compilerConfiguration.get(JSConfigurationKeys.INCREMENTAL_NEXT_ROUND_CHECKER) ?: return false
createMetadataSerializer().run {
forEachFile { _, sourceFile, ktSourceFile, _ ->
val protoBuf = serializeSingleFileMetadata(sourceFile)
// to minimize the number of IC rounds, we should inspect all proto for changes first,
// then go to the next round if needed, with all new dirty files
nextRoundChecker.checkProtoChanges(ktSourceFile.toIoFileOrNull()!!, protoBuf.toByteArray())
}
}
if (nextRoundChecker.shouldGoToNextRound()) throw IncrementalNextRoundException()
return nextRoundChecker.shouldGoToNextRound()
}
fun KlibMetadataIncrementalSerializer(configuration: CompilerConfiguration, project: Project, allowErrors: Boolean) =
KlibMetadataIncrementalSerializer(
languageVersionSettings = configuration.languageVersionSettings,
metadataVersion = configuration.metadataVersion,
project = project,
exportKDoc = false,
allowErrorTypes = allowErrors
)
private fun Map<IrModuleFragment, KotlinLibrary>.getUniqueNameForEachFragment(): Map<IrModuleFragment, String> {
return this.entries.mapNotNull { (moduleFragment, klib) ->
klib.jsOutputName?.let { moduleFragment to it }
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.test.backend.ir
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.serialization.KotlinFileSerializedData
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.fir.backend.FirMangler
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.KotlinMangler
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.test.model.BackendKind
import org.jetbrains.kotlin.test.model.BackendKinds
import org.jetbrains.kotlin.test.model.ResultingArtifact
@@ -66,14 +66,13 @@ sealed class IrBackendInput : ResultingArtifact.BackendInput<IrBackendInput>() {
class JsIrBackendInput(
override val irModuleFragment: IrModuleFragment,
override val irPluginContext: IrPluginContext,
val sourceFiles: List<KtSourceFile>,
val icData: List<KotlinFileSerializedData>,
override val diagnosticReporter: BaseDiagnosticsCollector,
val hasErrors: Boolean,
override val descriptorMangler: KotlinMangler.DescriptorMangler?,
override val irMangler: KotlinMangler.IrMangler,
override val firMangler: FirMangler?,
val serializeSingleFile: (KtSourceFile) -> ProtoBuf.PackageFragment,
val metadataSerializer: KlibSingleFileMetadataSerializer<*>,
) : IrBackendInput()
data class JsIrDeserializedFromKlibBackendInput(
@@ -92,14 +91,13 @@ sealed class IrBackendInput : ResultingArtifact.BackendInput<IrBackendInput>() {
class WasmBackendInput(
override val irModuleFragment: IrModuleFragment,
override val irPluginContext: IrPluginContext,
val sourceFiles: List<KtSourceFile>,
val icData: List<KotlinFileSerializedData>,
override val diagnosticReporter: BaseDiagnosticsCollector,
val hasErrors: Boolean,
override val descriptorMangler: KotlinMangler.DescriptorMangler?,
override val irMangler: KotlinMangler.IrMangler,
override val firMangler: FirMangler?,
val serializeSingleFile: (KtSourceFile) -> ProtoBuf.PackageFragment,
val metadataSerializer: KlibSingleFileMetadataSerializer<*>,
) : IrBackendInput()
class JvmIrBackendInput(
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.test.frontend.classic
import org.jetbrains.kotlin.KtPsiSourceFile
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.js.klib.TopDownAnalyzerFacadeForJSIR
@@ -105,21 +104,26 @@ class ClassicFrontend2IrConverter(
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
val hasErrors = TopDownAnalyzerFacadeForJSIR.checkForErrors(sourceFiles, analysisResult.bindingContext, errorPolicy)
val metadataSerializer = KlibMetadataIncrementalSerializer(configuration, project, hasErrors)
val metadataSerializer = KlibMetadataIncrementalSerializer(
sourceFiles,
configuration,
project,
analysisResult.bindingContext,
moduleFragment.descriptor,
hasErrors,
)
return IrBackendInput.JsIrBackendInput(
moduleFragment,
pluginContext,
sourceFiles.map(::KtPsiSourceFile),
icData,
diagnosticReporter = DiagnosticReporterFactory.createReporter(),
hasErrors,
descriptorMangler = (pluginContext.symbolTable as SymbolTable).signaturer!!.mangler,
irMangler = JsManglerIr,
firMangler = null,
) { file ->
metadataSerializer.serializeScope(file, analysisResult.bindingContext, moduleFragment.descriptor)
}
metadataSerializer = metadataSerializer,
)
}
private fun transformToWasmIr(module: TestModule, inputArtifact: ClassicFrontendOutputArtifact): IrBackendInput {
@@ -147,20 +151,25 @@ class ClassicFrontend2IrConverter(
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
val analyzerFacade = TopDownAnalyzerFacadeForWasm.facadeFor(configuration.get(JSConfigurationKeys.WASM_TARGET))
val hasErrors = analyzerFacade.checkForErrors(sourceFiles, analysisResult.bindingContext, errorPolicy)
val metadataSerializer = KlibMetadataIncrementalSerializer(configuration, project, hasErrors)
val metadataSerializer = KlibMetadataIncrementalSerializer(
sourceFiles,
configuration,
project,
analysisResult.bindingContext,
moduleFragment.descriptor,
hasErrors,
)
return IrBackendInput.WasmBackendInput(
moduleFragment,
pluginContext,
sourceFiles.map(::KtPsiSourceFile),
icData,
diagnosticReporter = DiagnosticReporterFactory.createReporter(),
hasErrors,
descriptorMangler = (pluginContext.symbolTable as SymbolTable).signaturer!!.mangler,
irMangler = JsManglerIr,
firMangler = null,
) { file ->
metadataSerializer.serializeScope(file, analysisResult.bindingContext, moduleFragment.descriptor)
}
metadataSerializer = metadataSerializer,
)
}
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.test.frontend.fir
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
@@ -17,12 +16,8 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.fir.backend.*
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.descriptors.FirModuleDescriptor
import org.jetbrains.kotlin.fir.pipeline.Fir2IrActualizedResult
import org.jetbrains.kotlin.fir.pipeline.FirResult
import org.jetbrains.kotlin.fir.pipeline.ModuleCompilerAnalyzedOutput
import org.jetbrains.kotlin.fir.pipeline.convertToIrAndActualize
import org.jetbrains.kotlin.fir.pipeline.*
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.util.KotlinMangler
@@ -74,8 +69,6 @@ abstract class AbstractFir2IrNonJvmResultsConverter(
inputArtifact: FirOutputArtifact
): IrBackendInput {
val compilerConfiguration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
val sourceFiles = mutableListOf<KtSourceFile>()
val firFilesAndComponentsBySourceFile = mutableMapOf<KtSourceFile, Pair<FirFile, Fir2IrComponents>>()
val irMangler = createIrMangler()
val diagnosticReporter = DiagnosticReporterFactory.createReporter()
@@ -87,7 +80,8 @@ abstract class AbstractFir2IrNonJvmResultsConverter(
compilerConfiguration,
diagnosticReporter,
)
val fir2irResult = inputArtifact.toFirResult().convertToIrAndActualize(
val firResult = inputArtifact.toFirResult()
val fir2irResult = firResult.convertToIrAndActualize(
Fir2IrExtensions.Default,
fir2IrConfiguration,
module.irGenerationExtensions(testServices),
@@ -96,16 +90,23 @@ abstract class AbstractFir2IrNonJvmResultsConverter(
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 {
).also {
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = dependencies }
}
return createBackendInput(compilerConfiguration, diagnosticReporter, inputArtifact, fir2irResult, firFilesAndComponentsBySourceFile, sourceFiles)
return createBackendInput(
compilerConfiguration,
diagnosticReporter,
inputArtifact,
fir2irResult,
Fir2KlibMetadataSerializer(
compilerConfiguration,
firResult.outputs,
fir2irResult,
exportKDoc = false,
produceHeaderKlib = false,
),
)
}
protected abstract fun createBackendInput(
@@ -113,8 +114,7 @@ abstract class AbstractFir2IrNonJvmResultsConverter(
diagnosticReporter: BaseDiagnosticsCollector,
inputArtifact: FirOutputArtifact,
fir2IrResult: Fir2IrActualizedResult,
firFilesAndComponentsBySourceFile: Map<KtSourceFile, Pair<FirFile, Fir2IrComponents>>,
sourceFiles: List<KtSourceFile>
fir2KlibMetadataSerializer: Fir2KlibMetadataSerializer,
): IrBackendInput
private fun loadResolvedLibraries(
@@ -5,21 +5,15 @@
package org.jetbrains.kotlin.test.frontend.fir
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.serialization.KotlinFileSerializedData
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibSingleFileMetadataSerializer
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.fir.backend.ConstValueProviderImpl
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.FirMangler
import org.jetbrains.kotlin.fir.backend.extractFirDeclarations
import org.jetbrains.kotlin.fir.backend.js.FirJsKotlinMangler
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.pipeline.Fir2IrActualizedResult
import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension
import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile
import org.jetbrains.kotlin.fir.pipeline.Fir2KlibMetadataSerializer
import org.jetbrains.kotlin.ir.backend.js.JsFactories
import org.jetbrains.kotlin.ir.backend.js.getSerializedData
import org.jetbrains.kotlin.ir.backend.js.incrementalDataProvider
@@ -28,25 +22,22 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.KotlinMangler
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.frontend.fir.handlers.firDiagnosticCollectorService
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.utils.metadataVersion
abstract class Fir2IrJsWasmResultsConverter(testServices: TestServices) : AbstractFir2IrNonJvmResultsConverter(testServices) {
protected abstract val artifactFactory: (
IrModuleFragment,
IrPluginContext,
List<KtSourceFile>,
List<KotlinFileSerializedData>,
BaseDiagnosticsCollector,
Boolean,
KotlinMangler.DescriptorMangler?,
KotlinMangler.IrMangler,
FirMangler?,
(KtSourceFile) -> ProtoBuf.PackageFragment
KlibSingleFileMetadataSerializer<*>,
) -> IrBackendInput
override fun createIrMangler(): KotlinMangler.IrMangler {
@@ -65,46 +56,25 @@ abstract class Fir2IrJsWasmResultsConverter(testServices: TestServices) : Abstra
diagnosticReporter: BaseDiagnosticsCollector,
inputArtifact: FirOutputArtifact,
fir2IrResult: Fir2IrActualizedResult,
firFilesAndComponentsBySourceFile: Map<KtSourceFile, Pair<FirFile, Fir2IrComponents>>,
sourceFiles: List<KtSourceFile>,
fir2KlibMetadataSerializer: Fir2KlibMetadataSerializer,
): IrBackendInput {
val languageVersionSettings = compilerConfiguration.languageVersionSettings
val metadataVersion = compilerConfiguration.metadataVersion(languageVersionSettings.languageVersion)
val fir2IrComponents = fir2IrResult.components
val manglers = fir2IrComponents.manglers
val manglers = fir2IrResult.components.manglers
return artifactFactory(
fir2IrResult.irModuleFragment,
fir2IrResult.pluginContext,
sourceFiles,
compilerConfiguration.incrementalDataProvider?.getSerializedData(sourceFiles) ?: emptyList(),
compilerConfiguration.incrementalDataProvider?.getSerializedData(fir2KlibMetadataSerializer.sourceFiles) ?: emptyList(),
diagnosticReporter,
testServices.firDiagnosticCollectorService.containsErrors(inputArtifact),
/*descriptorMangler = */null,
manglers.irMangler,
manglers.firMangler,
) { file ->
val (firFile, components) = firFilesAndComponentsBySourceFile[file]
?: error("cannot find FIR file by source file ${file.name} (${file.path})")
val actualizedExpectDeclarations = fir2IrResult.irActualizedResult?.actualizedExpectDeclarations?.extractFirDeclarations()
serializeSingleFirFile(
firFile,
components.session,
components.scopeSession,
actualizedExpectDeclarations,
FirKLibSerializerExtension(
components.session, components.firProvider, metadataVersion,
ConstValueProviderImpl(components),
allowErrorTypes = false, exportKDoc = false,
components.annotationsFromPluginRegistrar.createAdditionalMetadataProvider()
),
languageVersionSettings,
)
}
fir2KlibMetadataSerializer,
)
}
}
class Fir2IrJsResultsConverter(testServices: TestServices) : Fir2IrJsWasmResultsConverter(testServices) {
override val artifactFactory: (IrModuleFragment, IrPluginContext, List<KtSourceFile>, List<KotlinFileSerializedData>, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, (KtSourceFile) -> ProtoBuf.PackageFragment) -> IrBackendInput
override val artifactFactory: (IrModuleFragment, IrPluginContext, List<KotlinFileSerializedData>, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, KlibSingleFileMetadataSerializer<*>) -> IrBackendInput
get() = IrBackendInput::JsIrBackendInput
override fun resolveLibraries(module: TestModule, compilerConfiguration: CompilerConfiguration): List<KotlinResolvedLibrary> {
@@ -114,7 +84,7 @@ class Fir2IrJsResultsConverter(testServices: TestServices) : Fir2IrJsWasmResults
class Fir2IrWasmResultsConverter(testServices: TestServices) : Fir2IrJsWasmResultsConverter(testServices) {
override val artifactFactory: (IrModuleFragment, IrPluginContext, List<KtSourceFile>, List<KotlinFileSerializedData>, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, (KtSourceFile) -> ProtoBuf.PackageFragment) -> IrBackendInput
override val artifactFactory: (IrModuleFragment, IrPluginContext, List<KotlinFileSerializedData>, BaseDiagnosticsCollector, Boolean, KotlinMangler.DescriptorMangler?, KotlinMangler.IrMangler, FirMangler?, KlibSingleFileMetadataSerializer<*>) -> IrBackendInput
get() = IrBackendInput::WasmBackendInput
override fun resolveLibraries(module: TestModule, compilerConfiguration: CompilerConfiguration): List<KotlinResolvedLibrary> {
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.klib
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import junit.framework.TestCase
import org.jetbrains.kotlin.KtPsiSourceFile
import org.jetbrains.kotlin.backend.common.CommonKLibResolver
import org.jetbrains.kotlin.backend.common.linkage.issues.checkNoUnboundSymbols
import org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinker
@@ -18,11 +15,8 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.codegen.CodegenTestCase
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -34,7 +28,6 @@ import org.jetbrains.kotlin.ir.backend.js.KlibMetadataIncrementalSerializer
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc
import org.jetbrains.kotlin.ir.backend.js.serializeModuleIntoKlib
import org.jetbrains.kotlin.ir.backend.js.serializeScope
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.util.*
@@ -45,17 +38,13 @@ import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS
import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.impl.BuiltInsPlatform
import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion
import org.jetbrains.kotlin.library.metadata.resolver.TopologicalLibraryOrder
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl
import org.jetbrains.kotlin.resolve.AnalyzingUtils
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContextUtils
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.test.ConfigurationKind
@@ -119,42 +108,25 @@ abstract class AbstractKlibIrTextTestCase : CodegenTestCase() {
}
}
private fun klibMetadataIncrementalSerializer(configuration: CompilerConfiguration, project: Project, allowErrors: Boolean) =
KlibMetadataIncrementalSerializer(
languageVersionSettings = configuration.languageVersionSettings,
metadataVersion = KlibMetadataVersion.INSTANCE,
project = project,
exportKDoc = false,
allowErrorTypes = allowErrors
)
private fun getDescriptorForElement(
context: BindingContext,
element: PsiElement
): DeclarationDescriptor = BindingContextUtils.getNotNull(context, BindingContext.DECLARATION_TO_DESCRIPTOR, element)
private fun KlibMetadataIncrementalSerializer.serializeScope(
ktFile: KtFile,
bindingContext: BindingContext,
moduleDescriptor: ModuleDescriptor
): ProtoBuf.PackageFragment {
val memberScope = ktFile.declarations.map { getDescriptorForElement(bindingContext, it) }
return serializePackageFragment(moduleDescriptor, memberScope, ktFile.packageFqName)
}
private fun serializeModule(
irModuleFragment: IrModuleFragment,
bindingContext: BindingContext,
stdlib: KotlinLibrary,
containsErrorCode: Boolean,
): String {
val metadataSerializer = klibMetadataIncrementalSerializer(myEnvironment.configuration, myEnvironment.project, containsErrorCode)
val klibDir = org.jetbrains.kotlin.konan.file.createTempDir("testKlib")
serializeModuleIntoKlib(
moduleName = MODULE_NAME,
configuration = myEnvironment.configuration,
diagnosticReporter = DiagnosticReporterFactory.createPendingReporter(),
files = myFiles.psiFiles.map(::KtPsiSourceFile),
metadataSerializer = KlibMetadataIncrementalSerializer(
files = myFiles.psiFiles,
configuration = myEnvironment.configuration,
project = myEnvironment.project,
bindingContext = bindingContext,
moduleDescriptor = irModuleFragment.descriptor,
allowErrorTypes = containsErrorCode
),
klibPath = klibDir.canonicalPath,
dependencies = listOf(stdlib),
moduleFragment = irModuleFragment,
@@ -165,7 +137,6 @@ abstract class AbstractKlibIrTextTestCase : CodegenTestCase() {
abiVersion = KotlinAbiVersion.CURRENT,
jsOutputName = null,
builtInsPlatform = BuiltInsPlatform.JS,
serializeSingleFile = { metadataSerializer.serializeScope(it, bindingContext, irModuleFragment.descriptor) }
)
return klibDir.canonicalPath
}
@@ -74,9 +74,6 @@ class FilePathsInKlibTest : CodegenTestCase() {
module.getModuleDescriptor(it)
}
val metadataSerializer =
KlibMetadataIncrementalSerializer(module.compilerConfiguration, module.project, module.jsFrontEndResult.hasErrors)
val diagnosticReporter = DiagnosticReporterFactory.createPendingReporter()
generateKLib(
module,
@@ -85,10 +82,8 @@ class FilePathsInKlibTest : CodegenTestCase() {
jsOutputName = MODULE_NAME,
icData = icData,
moduleFragment = moduleFragment,
diagnosticReporter = diagnosticReporter
) { file ->
metadataSerializer.serializeScope(file, module.jsFrontEndResult.bindingContext, moduleFragment.descriptor)
}
diagnosticReporter = diagnosticReporter,
)
}
private fun setupEnvironment(): CompilerConfiguration {
@@ -12,7 +12,6 @@ import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.ir.KtDiagnosticReporterWithImplicitIrBasedContext
import org.jetbrains.kotlin.KtPsiSourceFile
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.backend.common.linkage.issues.checkNoUnboundSymbols
import org.jetbrains.kotlin.backend.common.linkage.partial.PartialLinkageSupportForLinker
@@ -485,7 +484,6 @@ class GenerateIrRuntime {
return psi2IrTranslator.generateModuleFragment(psi2IrContext, files, irProviders, emptyList())
}
@OptIn(ExperimentalPathApi::class)
private fun doSerializeModule(
moduleFragment: IrModuleFragment,
bindingContext: BindingContext,
@@ -494,12 +492,19 @@ class GenerateIrRuntime {
): String {
val diagnosticReporter = DiagnosticReporterFactory.createPendingReporter()
val tmpKlibDir = createTempDirectory().also { it.toFile().deleteOnExit() }.toString()
val metadataSerializer = KlibMetadataIncrementalSerializer(configuration, project, false)
val metadataSerializer = KlibMetadataIncrementalSerializer(
files,
configuration,
project,
bindingContext,
moduleFragment.descriptor,
allowErrorTypes = false,
)
serializeModuleIntoKlib(
moduleName,
configuration,
diagnosticReporter,
files.map(::KtPsiSourceFile),
metadataSerializer,
tmpKlibDir,
emptyList(),
moduleFragment,
@@ -507,10 +512,8 @@ class GenerateIrRuntime {
true,
perFile,
abiVersion = KotlinAbiVersion.CURRENT,
jsOutputName = null
) { file ->
metadataSerializer.serializeScope(file, bindingContext, moduleFragment.descriptor)
}
jsOutputName = null,
)
return tmpKlibDir
}
@@ -106,10 +106,6 @@ abstract class IrAbstractInvalidationTest(
) {
sourceModule.getModuleDescriptor(it)
}
val metadataSerializer =
KlibMetadataIncrementalSerializer(configuration, sourceModule.project, sourceModule.jsFrontEndResult.hasErrors)
val diagnosticReporter = DiagnosticReporterFactory.createPendingReporter()
generateKLib(
sourceModule,
outputKlibFile.canonicalPath,
@@ -117,9 +113,7 @@ abstract class IrAbstractInvalidationTest(
jsOutputName = moduleName,
icData = icData,
moduleFragment = moduleFragment,
diagnosticReporter = diagnosticReporter
) { file ->
metadataSerializer.serializeScope(file, sourceModule.jsFrontEndResult.bindingContext, moduleFragment.descriptor)
}
diagnosticReporter = DiagnosticReporterFactory.createPendingReporter(),
)
}
}
@@ -61,7 +61,7 @@ class FirJsKlibBackendFacade(
configuration[CommonConfigurationKeys.MODULE_NAME]!!,
configuration,
inputArtifact.diagnosticReporter,
inputArtifact.sourceFiles,
inputArtifact.metadataSerializer,
klibPath = outputFile,
libraries.map { it.library },
inputArtifact.irModuleFragment,
@@ -71,9 +71,7 @@ class FirJsKlibBackendFacade(
containsErrorCode = inputArtifact.hasErrors,
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
jsOutputName = null
) {
inputArtifact.serializeSingleFile(it)
}
)
}
// TODO: consider avoiding repeated libraries resolution
@@ -51,7 +51,7 @@ class JsKlibBackendFacade(
configuration[CommonConfigurationKeys.MODULE_NAME]!!,
configuration,
inputArtifact.diagnosticReporter,
inputArtifact.sourceFiles,
inputArtifact.metadataSerializer,
klibPath = outputFile,
JsEnvironmentConfigurator.getAllRecursiveLibrariesFor(module, testServices).keys.toList(),
inputArtifact.irModuleFragment,
@@ -61,9 +61,7 @@ class JsKlibBackendFacade(
containsErrorCode = inputArtifact.hasErrors,
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
jsOutputName = null
) {
inputArtifact.serializeSingleFile(it)
}
)
}
val dependencies = JsEnvironmentConfigurator.getAllRecursiveDependenciesFor(module, testServices).toList()
@@ -92,7 +92,7 @@ internal fun PhaseContext.fir2Ir(
val diagnosticsReporter = DiagnosticReporterFactory.createPendingReporter()
val fir2IrConfiguration = Fir2IrConfiguration.forKlibCompilation(configuration, diagnosticsReporter)
val (irModuleFragment, components, pluginContext, irActualizedResult) = input.firResult.convertToIrAndActualize(
val actualizedResult = input.firResult.convertToIrAndActualize(
NativeFir2IrExtensions,
fir2IrConfiguration,
IrGenerationExtension.getInstances(config.project),
@@ -104,8 +104,8 @@ internal fun PhaseContext.fir2Ir(
).also {
(it.irModuleFragment.descriptor as? FirModuleDescriptor)?.let { it.allDependencyModules = librariesDescriptors }
}
assert(irModuleFragment.name.isSpecial) {
"`${irModuleFragment.name}` must be Name.special, since it's required by KlibMetadataModuleDescriptorFactoryImpl.createDescriptorOptionalBuiltIns()"
assert(actualizedResult.irModuleFragment.name.isSpecial) {
"`${actualizedResult.irModuleFragment.name}` must be Name.special, since it's required by KlibMetadataModuleDescriptorFactoryImpl.createDescriptorOptionalBuiltIns()"
}
@OptIn(DelicateDeclarationStorageApi::class)
@@ -116,8 +116,8 @@ internal fun PhaseContext.fir2Ir(
val fragment = (p.getPackageFragment() as? IrExternalPackageFragment) ?: return
add(fragment.packageFqName)
}
components.declarationStorage.forEachCachedDeclarationSymbol(::addExternalPackage)
components.classifierStorage.forEachCachedDeclarationSymbol(::addExternalPackage)
actualizedResult.components.declarationStorage.forEachCachedDeclarationSymbol(::addExternalPackage)
actualizedResult.components.classifierStorage.forEachCachedDeclarationSymbol(::addExternalPackage)
// These packages exist in all platform libraries, but can contain only synthetic declarations.
// These declarations are not really located in klib, so we don't need to depend on klib to use them.
@@ -135,7 +135,7 @@ internal fun PhaseContext.fir2Ir(
}
}
val symbols = createKonanSymbols(components, pluginContext)
val symbols = createKonanSymbols(actualizedResult.components, actualizedResult.pluginContext)
val renderDiagnosticNames = configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME)
FirDiagnosticsCompilerResultsReporter.reportToMessageCollector(diagnosticsReporter, messageCollector, renderDiagnosticNames)
@@ -144,7 +144,7 @@ internal fun PhaseContext.fir2Ir(
throw KonanCompilationException("Compilation failed: there were some diagnostics during fir2ir")
}
return Fir2IrOutput(input.firResult, symbols, irModuleFragment, components, pluginContext, irActualizedResult, usedLibraries)
return Fir2IrOutput(input.firResult, symbols, actualizedResult, usedLibraries)
}
private fun PhaseContext.createKonanSymbols(
@@ -11,23 +11,12 @@ import org.jetbrains.kotlin.backend.konan.driver.phases.SerializerOutput
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleSerializer
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.fir.reportToMessageCollector
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.ConstValueProviderImpl
import org.jetbrains.kotlin.fir.backend.extractFirDeclarations
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.packageFqName
import org.jetbrains.kotlin.fir.pipeline.Fir2KlibMetadataSerializer
import org.jetbrains.kotlin.fir.pipeline.FirResult
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.serialization.FirKLibSerializerExtension
import org.jetbrains.kotlin.fir.serialization.serializeSingleFirFile
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.library.metadata.resolver.TopologicalLibraryOrder
import org.jetbrains.kotlin.utils.toMetadataVersion
internal fun PhaseContext.firSerializer(input: FirOutput): SerializerOutput? = when (input) {
!is FirOutput.Full -> null
@@ -44,35 +33,26 @@ internal fun PhaseContext.firSerializerBase(
produceHeaderKlib: Boolean = false,
): SerializerOutput {
val configuration = config.configuration
val sourceFiles = mutableListOf<KtSourceFile>()
val firFilesAndSessionsBySourceFile = mutableMapOf<KtSourceFile, Triple<FirFile, FirSession, ScopeSession>>()
for (firOutput in firResult.outputs) {
for (firFile in firOutput.fir) {
sourceFiles.add(firFile.sourceFile!!)
firFilesAndSessionsBySourceFile[firFile.sourceFile!!] = Triple(firFile, firOutput.session, firOutput.scopeSession)
}
}
val metadataVersion =
configuration.get(CommonConfigurationKeys.METADATA_VERSION)
?: configuration.languageVersionSettings.languageVersion.toMetadataVersion()
val usedResolvedLibraries = fir2IrOutput?.let {
config.resolvedLibraries.getFullResolvedList(TopologicalLibraryOrder).filter {
(!it.isDefault && !configuration.getBoolean(KonanConfigKeys.PURGE_USER_LIBS)) || it in fir2IrOutput.usedLibraries
}
}
val actualizedFirDeclarations = fir2IrOutput?.irActualizedResult?.actualizedExpectDeclarations?.extractFirDeclarations()
val irModuleFragment = fir2IrOutput?.fir2irActualizedResult?.irModuleFragment
val diagnosticReporter = DiagnosticReporterFactory.createPendingReporter()
val serializerOutput = serializeModuleIntoKlib(
moduleName = fir2IrOutput?.irModuleFragment?.descriptor?.name?.asString()
?: firResult.outputs.last().session.moduleData.name.asString(),
irModuleFragment = fir2IrOutput?.irModuleFragment,
moduleName = irModuleFragment?.name?.asString() ?: firResult.outputs.last().session.moduleData.name.asString(),
irModuleFragment = irModuleFragment,
configuration = configuration,
diagnosticReporter = diagnosticReporter,
sourceFiles = sourceFiles,
metadataSerializer = Fir2KlibMetadataSerializer(
configuration,
firResult.outputs,
fir2IrOutput?.fir2irActualizedResult,
exportKDoc = shouldExportKDoc(),
produceHeaderKlib = produceHeaderKlib,
),
compatibilityMode = CompatibilityMode.CURRENT,
cleanFiles = emptyList(),
dependencies = usedResolvedLibraries?.map { it.library as KonanLibrary }.orEmpty(),
@@ -95,30 +75,6 @@ internal fun PhaseContext.firSerializerBase(
shouldCheckSignaturesOnUniqueness = shouldCheckSignaturesOnUniqueness,
)
},
serializeFileMetadata = { ktSourceFile ->
val (firFile, originalSession, originalScopeSession) = firFilesAndSessionsBySourceFile[ktSourceFile]
?: error("cannot find FIR file by source file ${ktSourceFile.name} (${ktSourceFile.path})")
val session = fir2IrOutput?.components?.session ?: originalSession
val scopeSession = fir2IrOutput?.components?.scopeSession ?: originalScopeSession
val firProvider = fir2IrOutput?.components?.firProvider ?: originalSession.firProvider
serializeSingleFirFile(
firFile,
session,
scopeSession,
actualizedFirDeclarations,
FirKLibSerializerExtension(
session, firProvider, metadataVersion,
fir2IrOutput?.let {
ConstValueProviderImpl(fir2IrOutput.components)
},
allowErrorTypes = false,
exportKDoc = shouldExportKDoc(),
additionalMetadataProvider = fir2IrOutput?.components?.annotationsFromPluginRegistrar?.createAdditionalMetadataProvider()
),
configuration.languageVersionSettings,
produceHeaderKlib,
) to firFile.packageFqName
},
)
val renderDiagnosticNames = configuration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME)
diagnosticReporter.reportToMessageCollector(messageCollector, renderDiagnosticNames)
@@ -51,7 +51,7 @@ internal val K2SpecialBackendChecksPhase = createSimpleNamedCompilerPhase<PhaseC
"SpecialBackendChecks",
"Special backend checks",
) { context, input ->
val moduleFragment = input.irModuleFragment
val moduleFragment = input.fir2irActualizedResult.irModuleFragment
SpecialBackendChecksTraversal(
context,
input.symbols,
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.konan.fir2Ir
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.Fir2IrPluginContext
import org.jetbrains.kotlin.fir.pipeline.Fir2IrActualizedResult
import org.jetbrains.kotlin.fir.pipeline.FirResult
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
@@ -20,10 +21,7 @@ import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
internal data class Fir2IrOutput(
val firResult: FirResult,
val symbols: KonanSymbols,
val irModuleFragment: IrModuleFragment,
val components: Fir2IrComponents,
val pluginContext: Fir2IrPluginContext,
val irActualizedResult: IrActualizedResult?,
val fir2irActualizedResult: Fir2IrActualizedResult,
val usedLibraries: Set<KotlinResolvedLibrary>
)
@@ -5,17 +5,15 @@
package org.jetbrains.kotlin.konan.test
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.FirMangler
import org.jetbrains.kotlin.fir.backend.native.FirNativeKotlinMangler
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.pipeline.Fir2IrActualizedResult
import org.jetbrains.kotlin.fir.pipeline.Fir2KlibMetadataSerializer
import org.jetbrains.kotlin.ir.util.KotlinMangler
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
@@ -48,8 +46,7 @@ class Fir2IrNativeResultsConverter(testServices: TestServices) : AbstractFir2IrN
diagnosticReporter: BaseDiagnosticsCollector,
inputArtifact: FirOutputArtifact,
fir2IrResult: Fir2IrActualizedResult,
firFilesAndComponentsBySourceFile: Map<KtSourceFile, Pair<FirFile, Fir2IrComponents>>,
sourceFiles: List<KtSourceFile>,
fir2KlibMetadataSerializer: Fir2KlibMetadataSerializer,
): IrBackendInput {
val fir2IrComponents = fir2IrResult.components
val manglers = fir2IrComponents.manglers
@@ -61,7 +61,7 @@ class FirWasmKlibBackendFacade(
configuration[CommonConfigurationKeys.MODULE_NAME]!!,
configuration,
inputArtifact.diagnosticReporter,
inputArtifact.sourceFiles,
inputArtifact.metadataSerializer,
klibPath = outputFile,
libraries.map { it.library },
inputArtifact.irModuleFragment,
@@ -71,9 +71,7 @@ class FirWasmKlibBackendFacade(
containsErrorCode = inputArtifact.hasErrors,
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
jsOutputName = null
) {
inputArtifact.serializeSingleFile(it)
}
)
}
// TODO: consider avoiding repeated libraries resolution