[KLIB tool] Introduce KlibToolOutput for capturing stdout and errors/warnings

With `KlibToolOutput` it's possible to forward the output of each
KLIB tool's command to either system stdout/stderr streams or to
some buffers which then can be read by tests.

^KT-62340
This commit is contained in:
Dmitriy Dolovov
2024-02-16 18:25:46 +01:00
committed by Space Team
parent 5b7c11ae39
commit 9878c1fa16
11 changed files with 220 additions and 154 deletions
@@ -40,7 +40,7 @@ internal class DeclarationPrinter(
private fun Printer.printPlain(header: String, signature: String? = null, suffix: String? = null) {
if (signature != null) println(signature)
println(if (suffix != null ) header + suffix else header)
println(if (suffix != null) header + suffix else header)
}
private inner class PrinterVisitor : DeclarationDescriptorVisitorEmptyBodies<Unit, Unit>() {
@@ -5,15 +5,14 @@ import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.ir.util.IdSignatureRenderer
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.library.KotlinIrSignatureVersion
internal class DefaultKlibSignatureRenderer(
signatureVersion: KotlinIrSignatureVersion?,
private val individualSignatureRenderer: IdSignatureRenderer,
private val prefix: String? = null,
) : KlibSignatureRenderer {
private val idSignaturer = KonanIdSignaturer(KonanManglerDesc)
private val individualSignatureRenderer = signatureVersion.getMostSuitableSignatureRenderer()
override fun render(descriptor: DeclarationDescriptor): String? {
val idSignature = if (descriptor is ClassDescriptor && descriptor.kind == ClassKind.ENUM_ENTRY) {
@@ -6,11 +6,10 @@
package org.jetbrains.kotlin.cli.klib
import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.IdSignatureRenderer
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.library.KotlinIrSignatureVersion
internal class IrSignaturesRenderer(private val output: Appendable, signatureVersion: KotlinIrSignatureVersion?) {
private val individualSignatureRenderer = signatureVersion.getMostSuitableSignatureRenderer()
internal class IrSignaturesRenderer(private val output: Appendable, private val individualSignatureRenderer: IdSignatureRenderer) {
fun render(signatures: IrSignaturesExtractor.Signatures) {
header("Declared signatures: ${signatures.declaredSignatures.size}")
@@ -6,34 +6,37 @@
package org.jetbrains.kotlin.cli.klib
import org.jetbrains.kotlin.library.KotlinIrSignatureVersion
import kotlin.system.exitProcess
internal class KlibToolArgumentsParser {
fun parseArguments(rawArgs: Array<String>): KlibToolArguments {
internal class KlibToolArgumentsParser(private val output: KlibToolOutput) {
fun parseArguments(rawArgs: Array<String>): KlibToolArguments? {
if (rawArgs.size < 2) {
printUsage()
exitProcess(0)
return null
}
val extraArgs: Map<ExtraOption, List<String>> = parseOptions(rawArgs.drop(2).toTypedArray<String>())
.entries
.mapNotNull { (option, values) ->
?.entries
?.mapNotNull { (option, values) ->
val knownOption = ExtraOption.parseOrNull(option)
if (knownOption == null) {
logWarning("Unrecognized command-line argument: $option")
output.logWarning("Unrecognized command-line argument: $option")
return@mapNotNull null
}
knownOption to values
}.toMap()
}?.toMap()
?: return null
val signatureVersion = extraArgs[ExtraOption.SIGNATURE_VERSION]?.last()?.let { rawSignatureVersion ->
rawSignatureVersion.toIntOrNull()?.let(::KotlinIrSignatureVersion)
?: logError("Invalid signature version: $rawSignatureVersion")
rawSignatureVersion.toIntOrNull()?.let(::KotlinIrSignatureVersion) ?: run {
output.logError("Invalid signature version: $rawSignatureVersion")
return null
}
}
if (signatureVersion != null && signatureVersion !in KotlinIrSignatureVersion.CURRENTLY_SUPPORTED_VERSIONS)
logError("Unsupported signature version: ${signatureVersion.number}")
if (signatureVersion != null && signatureVersion !in KotlinIrSignatureVersion.CURRENTLY_SUPPORTED_VERSIONS) {
output.logError("Unsupported signature version: ${signatureVersion.number}")
return null
}
return KlibToolArguments(
commandName = rawArgs[0],
@@ -45,15 +48,17 @@ internal class KlibToolArgumentsParser {
)
}
private fun parseOptions(args: Array<String>): Map<String, List<String>> {
private fun parseOptions(args: Array<String>): Map<String, List<String>>? {
val options = mutableMapOf<String, MutableList<String>>()
for (index in args.indices step 2) {
val key = args[index]
if (key[0] != '-') {
logError("Expected a flag with initial dash: $key")
output.logError("Expected a flag with initial dash: $key")
return null
}
if (index + 1 == args.size) {
logError("Expected an value after $key")
output.logError("Expected an value after $key")
return null
}
val value = listOf(args[index + 1])
options[key]?.addAll(value) ?: options.put(key, value.toMutableList())
@@ -62,7 +67,7 @@ internal class KlibToolArgumentsParser {
}
private fun printUsage() {
println(
output.stderr.appendLine(
"""
Usage: klib <command> <library> [<option>]
@@ -18,12 +18,14 @@ import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled
internal class KlibToolIrLinker(
output: KlibToolOutput,
module: ModuleDescriptor,
irBuiltIns: IrBuiltIns,
symbolTable: SymbolTable
) : KotlinIrLinker(module, KlibToolLogger, irBuiltIns, symbolTable, exportedDependencies = emptyList()) {
) : KotlinIrLinker(module, KlibToolLogger(output), irBuiltIns, symbolTable, exportedDependencies = emptyList()) {
override val fakeOverrideBuilder = IrLinkerFakeOverrideProvider(
linker = this,
symbolTable = symbolTable,
@@ -35,7 +37,7 @@ internal class KlibToolIrLinker(
override val returnUnboundSymbolsIfSignatureNotFound get() = true
override val translationPluginContext get() = TODO("Not needed for ir dumping")
override val translationPluginContext get() = shouldNotBeCalled()
override fun createModuleDeserializer(
moduleDescriptor: ModuleDescriptor,
@@ -7,15 +7,22 @@ package org.jetbrains.kotlin.cli.klib
import org.jetbrains.kotlin.ir.util.IrMessageLogger
import org.jetbrains.kotlin.util.Logger
import kotlin.system.exitProcess
internal object KlibToolLogger : Logger, IrMessageLogger {
override fun log(message: String) = println(message)
override fun warning(message: String) = logWarning(message)
override fun error(message: String) = logWarning(message)
internal class KlibToolLogger(private val output: KlibToolOutput) : Logger, IrMessageLogger {
override fun log(message: String) {
output.logInfo(message)
}
override fun warning(message: String) {
output.logWarning(message)
}
override fun error(message: String) {
output.logError(message)
}
@Deprecated(Logger.FATAL_DEPRECATION_MESSAGE, ReplaceWith(Logger.FATAL_REPLACEMENT))
override fun fatal(message: String) = logError(message, withStacktrace = true)
override fun fatal(message: String) = throw IllegalStateException("error: $message")
override fun report(severity: IrMessageLogger.Severity, message: String, location: IrMessageLogger.Location?) {
when (severity) {
@@ -25,16 +32,3 @@ internal object KlibToolLogger : Logger, IrMessageLogger {
}
}
}
internal fun logWarning(text: String) {
println("warning: $text")
}
internal fun logError(text: String, withStacktrace: Boolean = false): Nothing {
if (withStacktrace)
error("error: $text")
else {
System.err.println("error: $text")
exitProcess(1)
}
}
@@ -0,0 +1,37 @@
/*
* 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.cli.klib
/**
* TODO: Consider using [org.jetbrains.kotlin.cli.common.messages.MessageCollector] instead of this class.
* Note: The [org.jetbrains.kotlin.cli.common.messages.MessageCollector] is designed to track an individual short messages
* logged at different levels, but is not supposed to collect plain output (such as, for example, IR dump).
*/
internal class KlibToolOutput(
stdout: Appendable,
val stderr: Appendable
) : Appendable by stdout {
var hasErrors: Boolean = false
private set
internal fun logInfo(text: String) {
stderr.append("info: ").appendLine(text)
}
internal fun logWarning(text: String) {
stderr.append("warning: ").appendLine(text)
}
internal fun logError(text: String) {
hasErrors = true
stderr.append("error: ").appendLine(text)
}
internal fun logErrorWithStackTrace(t: Throwable) {
hasErrors = true
stderr.appendLine(t.stackTraceToString())
}
}
@@ -22,21 +22,16 @@ import org.jetbrains.kotlin.kotlinp.Printer
import org.jetbrains.kotlin.kotlinp.Settings
import org.jetbrains.kotlin.kotlinp.klib.*
import org.jetbrains.kotlin.kotlinp.klib.TypeArgumentId.VarianceId
import org.jetbrains.kotlin.library.KotlinIrSignatureVersion
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.calls.components.isVararg
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.utils.addToStdlib.runIf
internal class KotlinpBasedMetadataDumper(
output: Appendable,
printSignatures: Boolean,
signatureVersion: KotlinIrSignatureVersion?
private val output: KlibToolOutput,
private val signatureRenderer: IdSignatureRenderer?, // `null` means no signatures should be rendered.
) {
// `null` means no signatures should be rendered.
private val signatureRenderer = runIf(printSignatures) { signatureVersion.getMostSuitableSignatureRenderer() }
private val printer = Printer(output)
@@ -102,7 +97,7 @@ internal class KotlinpBasedMetadataDumper(
private fun prepareSignatureComputer(library: KotlinLibrary, moduleMetadata: KlibModuleMetadata): ExternalSignatureComputer? {
val signatureCollector = SignaturesCollector(signatureRenderer ?: return null)
val moduleDescriptor = ModuleDescriptorLoader.load(library)
val moduleDescriptor = ModuleDescriptorLoader(output).load(library)
moduleDescriptor.accept(signatureCollector, Unit)
return ExternalSignatureComputer(moduleMetadata, signatureCollector.signatures::get)
@@ -19,7 +19,9 @@ import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.utils.KotlinNativePaths
internal object ModuleDescriptorLoader {
internal class ModuleDescriptorLoader(output: KlibToolOutput) {
private val logger = KlibToolLogger(output)
fun load(library: KotlinLibrary): ModuleDescriptorImpl {
val storageManager = LockBasedStorageManager("klib")
@@ -31,7 +33,7 @@ internal object ModuleDescriptorLoader {
emptyList(),
distributionKlib = Distribution(KotlinNativePaths.homePath.absolutePath).klib,
skipCurrentDir = true,
logger = KlibToolLogger
logger = logger
)
resolver.defaultLinks(noStdLib = false, noDefaultLibs = true, noEndorsedLibs = true).mapTo(defaultModules) {
KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptor(it, languageVersionSettings, storageManager, module.builtIns, null)
@@ -45,7 +47,9 @@ internal object ModuleDescriptorLoader {
return module
}
val languageVersionSettings = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE)
companion object {
val languageVersionSettings = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE)
private val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer)
private val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer)
}
}
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.util.DumpIrTreeOptions
import org.jetbrains.kotlin.ir.util.IdSignatureRenderer
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.konan.library.KonanLibrary
@@ -27,25 +28,27 @@ import org.jetbrains.kotlin.library.unpackZippedKonanLibraryTo
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl
import org.jetbrains.kotlin.util.removeSuffixIfPresent
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import java.io.File
import kotlin.system.exitProcess
import org.jetbrains.kotlin.konan.file.File as KFile
private val defaultRepository = KFile(DependencyDirectories.localKonanDir.resolve("klib").absolutePath)
private class KlibRepoDeprecationWarning {
private class KlibRepoDeprecationWarning(private val output: KlibToolOutput) {
private var alreadyLogged = false
fun logOnceIfNecessary() {
if (!alreadyLogged) {
alreadyLogged = true
logWarning("Local KLIB repositories to be dropped soon. See https://youtrack.jetbrains.com/issue/KT-61098")
output.logWarning("Local KLIB repositories to be dropped soon. See https://youtrack.jetbrains.com/issue/KT-61098")
}
}
}
internal class KlibToolCommand(private val args: KlibToolArguments) {
internal class KlibToolCommand(private val output: KlibToolOutput, private val args: KlibToolArguments) {
private val klibRepoDeprecationWarning = KlibRepoDeprecationWarning()
private val klibRepoDeprecationWarning = KlibRepoDeprecationWarning(output)
private val repository = args.repository?.let {
klibRepoDeprecationWarning.logOnceIfNecessary() // Due to use of "-repository" option.
@@ -60,17 +63,16 @@ internal class KlibToolCommand(private val args: KlibToolArguments) {
val headerMetadataVersion = library.versions.metadataVersion
val moduleName = parseModuleHeader(library.moduleHeaderData).moduleName
println("")
println("Resolved to: ${KFile(library.libraryName).absolutePath}")
println("Module name: $moduleName")
println("ABI version: $headerAbiVersion")
println("Compiler version: $headerCompilerVersion")
println("Library version: $headerLibraryVersion")
println("Metadata version: $headerMetadataVersion")
output.appendLine()
output.appendLine("Resolved to: ${KFile(library.libraryName).absolutePath}")
output.appendLine("Module name: $moduleName")
output.appendLine("ABI version: $headerAbiVersion")
output.appendLine("Compiler version: $headerCompilerVersion")
output.appendLine("Library version: $headerLibraryVersion")
output.appendLine("Metadata version: $headerMetadataVersion")
if (library is KonanLibrary) {
val targets = library.targetList.joinToString(", ")
print("Available targets: $targets\n")
output.appendLine("Available targets: ${library.targetList.joinToString()}")
}
}
@@ -78,7 +80,7 @@ internal class KlibToolCommand(private val args: KlibToolArguments) {
klibRepoDeprecationWarning.logOnceIfNecessary()
if (!repository.exists) {
logWarning("Repository does not exist: $repository. Creating...")
output.logWarning("Repository does not exist: $repository. Creating...")
repository.mkdirs()
}
@@ -95,36 +97,35 @@ internal class KlibToolCommand(private val args: KlibToolArguments) {
fun remove() {
klibRepoDeprecationWarning.logOnceIfNecessary()
if (!repository.exists) logError("Repository does not exist: $repository")
val library = try {
libraryInRepo(repository, args.libraryNameOrPath)
} catch (e: Throwable) {
println(e.message)
null
if (!repository.exists) {
output.logError("Repository does not exist: $repository")
return
}
runCatching {
libraryInRepo(repository, args.libraryNameOrPath).libraryFile.deleteRecursively()
}
library?.libraryFile?.deleteRecursively()
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
fun dumpIr(output: Appendable) {
fun dumpIr() {
val library = libraryInRepoOrCurrentDir(repository, args.libraryNameOrPath)
checkLibraryHasIr(library)
if (!checkLibraryHasIr(library)) return
if (args.signatureVersion != null && args.signatureVersion != KotlinIrSignatureVersion.V2) {
// TODO: support passing any signature version through `DumpIrTreeOptions`, KT-62828
logWarning("using a non-default signature version in \"dump-ir\" is not supported yet")
output.logWarning("using a non-default signature version in \"dump-ir\" is not supported yet")
}
val module = ModuleDescriptorLoader.load(library)
val module = ModuleDescriptorLoader(output).load(library)
val idSignaturer = KonanIdSignaturer(KonanManglerDesc)
val symbolTable = SymbolTable(idSignaturer, IrFactoryImpl)
val typeTranslator = TypeTranslatorImpl(symbolTable, ModuleDescriptorLoader.languageVersionSettings, module)
val irBuiltIns = IrBuiltInsOverDescriptors(module.builtIns, typeTranslator, symbolTable)
val linker = KlibToolIrLinker(module, irBuiltIns, symbolTable)
val linker = KlibToolIrLinker(output, module, irBuiltIns, symbolTable)
module.allDependencyModules.forEach {
linker.deserializeOnlyHeaderModule(it, it.kotlinLibrary)
linker.resolveModuleDeserializer(it, null).init()
@@ -137,19 +138,22 @@ internal class KlibToolCommand(private val args: KlibToolArguments) {
}
@OptIn(ExperimentalLibraryAbiReader::class)
fun dumpAbi(output: Appendable) {
fun dumpAbi() {
val library = libraryInCurrentDir(args.libraryNameOrPath)
checkLibraryHasIr(library)
if (!checkLibraryHasIr(library)) return
val abiSignatureVersion = args.signatureVersion?.let { signatureVersion ->
signatureVersion.checkSupportedInLibrary(library)
if (!signatureVersion.checkSupportedInLibrary(library)) return
val abiSignatureVersion = AbiSignatureVersion.resolveByVersionNumber(signatureVersion.number)
if (!abiSignatureVersion.isSupportedByAbiReader)
logError(
if (!abiSignatureVersion.isSupportedByAbiReader) {
output.logError(
"Signature version ${signatureVersion.number} is not supported by the KLIB ABI reader." +
" Supported versions: ${AbiSignatureVersion.allSupportedByAbiReader.joinToString { it.versionNumber.toString() }}"
)
return
}
abiSignatureVersion
} ?: run {
@@ -161,13 +165,15 @@ internal class KlibToolCommand(private val args: KlibToolArguments) {
.sortedDescending()
.firstNotNullOfOrNull { versionsSupportedByAbiReader[it] }
if (abiSignatureVersion == null)
logError(
if (abiSignatureVersion == null) {
output.logError(
"There is no signature version that would be both supported in library ${library.libraryFile}" +
" and by the KLIB ABI reader. Supported versions in the library:" +
" ${library.versions.irSignatureVersions.joinToString { it.number.toString() }}" +
". Supported versions by the KLIB ABI reader: ${AbiSignatureVersion.allSupportedByAbiReader.joinToString { it.versionNumber.toString() }}"
)
return
}
abiSignatureVersion
}
@@ -186,79 +192,119 @@ internal class KlibToolCommand(private val args: KlibToolArguments) {
}
// TODO: This command is deprecated. Drop it after 2.0. KT-65380
fun contents(output: Appendable) {
logWarning("\"contents\" has been renamed to \"dump-metadata\". Please, use new command name.")
val module = ModuleDescriptorLoader.load(libraryInRepoOrCurrentDir(repository, args.libraryNameOrPath))
val signatureRenderer = if (args.printSignatures)
DefaultKlibSignatureRenderer(args.signatureVersion, "// Signature: ")
fun contents() {
output.logWarning("\"contents\" has been renamed to \"dump-metadata\". Please, use new command name.")
val idSignatureRenderer = args.signatureVersion.getMostSuitableSignatureRenderer() ?: return
val module = ModuleDescriptorLoader(output).load(libraryInRepoOrCurrentDir(repository, args.libraryNameOrPath))
val klibSignatureRenderer = if (args.printSignatures)
DefaultKlibSignatureRenderer(idSignatureRenderer, "// Signature: ")
else
KlibSignatureRenderer.NO_SIGNATURE
val printer = DeclarationPrinter(output, signatureRenderer)
val printer = DeclarationPrinter(output, klibSignatureRenderer)
printer.print(module)
}
fun dumpMetadata(output: Appendable) {
KotlinpBasedMetadataDumper(output, args.printSignatures, args.signatureVersion).dumpLibrary(libraryInCurrentDir(args.libraryNameOrPath), args.testMode)
fun dumpMetadata() {
val idSignatureRenderer: IdSignatureRenderer? = runIf(args.printSignatures) {
args.signatureVersion.getMostSuitableSignatureRenderer() ?: return
}
KotlinpBasedMetadataDumper(output, idSignatureRenderer).dumpLibrary(libraryInCurrentDir(args.libraryNameOrPath), args.testMode)
}
fun signatures(output: Appendable) {
logWarning("\"signatures\" has been renamed to \"dump-metadata-signatures\". Please, use new command name.")
dumpMetadataSignatures(output)
fun signatures() {
output.logWarning("\"signatures\" has been renamed to \"dump-metadata-signatures\". Please, use new command name.")
dumpMetadataSignatures()
}
fun dumpMetadataSignatures(output: Appendable) {
val module = ModuleDescriptorLoader.load(libraryInRepoOrCurrentDir(repository, args.libraryNameOrPath))
fun dumpMetadataSignatures() {
// Don't call `checkSupportedInLibrary()` - the signatures are anyway generated on the fly.
val printer = SignaturePrinter(output, DefaultKlibSignatureRenderer(args.signatureVersion))
val idSignatureRenderer = args.signatureVersion.getMostSuitableSignatureRenderer() ?: return
val module = ModuleDescriptorLoader(output).load(libraryInRepoOrCurrentDir(repository, args.libraryNameOrPath))
val printer = SignaturePrinter(output, DefaultKlibSignatureRenderer(idSignatureRenderer))
printer.print(module)
}
fun dumpIrSignatures(output: Appendable) {
fun dumpIrSignatures() {
val library = libraryInCurrentDir(args.libraryNameOrPath)
checkLibraryHasIr(library)
args.signatureVersion?.checkSupportedInLibrary(library)
if (!checkLibraryHasIr(library) || !args.signatureVersion.checkSupportedInLibrary(library)) return
val idSignatureRenderer = args.signatureVersion.getMostSuitableSignatureRenderer() ?: return
val signatures = IrSignaturesExtractor(library).extract()
IrSignaturesRenderer(output, args.signatureVersion).render(signatures)
IrSignaturesRenderer(output, idSignatureRenderer).render(signatures)
}
private fun checkLibraryHasIr(library: KotlinLibrary) {
if (!library.hasIr) logError("Library ${library.libraryFile} is an IR-less library")
private fun checkLibraryHasIr(library: KotlinLibrary): Boolean {
if (!library.hasIr) {
output.logError("Library ${library.libraryFile} is an IR-less library")
return false
}
return true
}
private fun KotlinIrSignatureVersion.checkSupportedInLibrary(library: KotlinLibrary) {
val supportedSignatureVersions = library.versions.irSignatureVersions
if (this !in supportedSignatureVersions)
logError("Signature version ${this.number} is not supported in library ${library.libraryFile}." +
" Supported versions: ${supportedSignatureVersions.joinToString { it.number.toString() }}")
private fun KotlinIrSignatureVersion?.checkSupportedInLibrary(library: KotlinLibrary): Boolean {
if (this != null) {
val supportedSignatureVersions = library.versions.irSignatureVersions
if (this !in supportedSignatureVersions) {
output.logError("Signature version ${this.number} is not supported in library ${library.libraryFile}." +
" Supported versions: ${supportedSignatureVersions.joinToString { it.number.toString() }}")
return false
}
}
return true
}
private fun KotlinIrSignatureVersion?.getMostSuitableSignatureRenderer(): IdSignatureRenderer? = when (this) {
KotlinIrSignatureVersion.V1 -> IdSignatureRenderer.LEGACY
null, KotlinIrSignatureVersion.V2 -> IdSignatureRenderer.DEFAULT
else -> {
output.logError("Unsupported signature version: $number")
null
}
}
private fun libraryInRepo(repository: KFile, name: String) =
resolverByName(listOf(repository.absolutePath), skipCurrentDir = true, logger = KlibToolLogger(output)).resolve(name)
private fun libraryInCurrentDir(name: String) = resolverByName(emptyList(), logger = KlibToolLogger(output)).resolve(name)
private fun libraryInRepoOrCurrentDir(repository: KFile, name: String) =
resolverByName(listOf(repository.absolutePath), logger = KlibToolLogger(output)).resolve(name)
}
private fun libraryInRepo(repository: KFile, name: String) =
resolverByName(listOf(repository.absolutePath), skipCurrentDir = true, logger = KlibToolLogger).resolve(name)
private fun libraryInCurrentDir(name: String) = resolverByName(emptyList(), logger = KlibToolLogger).resolve(name)
private fun libraryInRepoOrCurrentDir(repository: KFile, name: String) =
resolverByName(listOf(repository.absolutePath), logger = KlibToolLogger).resolve(name)
fun main(rawArgs: Array<String>) {
val args = KlibToolArgumentsParser().parseArguments(rawArgs)
val command = KlibToolCommand(args)
val output = KlibToolOutput(stdout = System.out, stderr = System.err)
when (args.commandName) {
"dump-abi" -> command.dumpAbi(System.out)
"dump-ir" -> command.dumpIr(System.out)
"dump-ir-signatures" -> command.dumpIrSignatures(System.out)
"dump-metadata" -> command.dumpMetadata(System.out)
"dump-metadata-signatures" -> command.dumpMetadataSignatures(System.out)
"contents" -> command.contents(System.out)
"signatures" -> command.signatures(System.out)
"info" -> command.info()
"install" -> command.install()
"remove" -> command.remove()
else -> logError("Unknown command: ${args.commandName}")
val args = KlibToolArgumentsParser(output).parseArguments(rawArgs)
if (args != null) {
val command = KlibToolCommand(output, args)
try {
when (args.commandName) {
"dump-abi" -> command.dumpAbi()
"dump-ir" -> command.dumpIr()
"dump-ir-signatures" -> command.dumpIrSignatures()
"dump-metadata" -> command.dumpMetadata()
"dump-metadata-signatures" -> command.dumpMetadataSignatures()
"contents" -> command.contents()
"signatures" -> command.signatures()
"info" -> command.info()
"install" -> command.install()
"remove" -> command.remove()
else -> output.logError("Unknown command: ${args.commandName}")
}
} catch (t: Throwable) {
output.logErrorWithStackTrace(t)
}
}
if (output.hasErrors)
exitProcess(1)
}
@@ -1,15 +0,0 @@
/*
* Copyright 2010-2023 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.cli.klib
import org.jetbrains.kotlin.ir.util.IdSignatureRenderer
import org.jetbrains.kotlin.library.KotlinIrSignatureVersion
internal fun KotlinIrSignatureVersion?.getMostSuitableSignatureRenderer() = when (this) {
KotlinIrSignatureVersion.V1 -> IdSignatureRenderer.LEGACY
null, KotlinIrSignatureVersion.V2 -> IdSignatureRenderer.DEFAULT
else -> error("Unsupported signature version: $number")
}