[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:
committed by
Space Team
parent
5a6f51e474
commit
f39335b3f7
@@ -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()
|
||||
}
|
||||
|
||||
+103
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+35
@@ -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)
|
||||
}
|
||||
+28
-28
@@ -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(
|
||||
|
||||
+61
-2
@@ -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 }
|
||||
|
||||
+3
-5
@@ -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(
|
||||
|
||||
+20
-11
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+18
-18
@@ -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(
|
||||
|
||||
+10
-40
@@ -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> {
|
||||
|
||||
+8
-37
@@ -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()
|
||||
|
||||
+7
-7
@@ -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
-55
@@ -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)
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
+2
-4
@@ -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>
|
||||
)
|
||||
|
||||
|
||||
+2
-5
@@ -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
|
||||
|
||||
+2
-4
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user