[KLIB tool] Split KlibToolCommand into multiple individual commands
^KT-62340
This commit is contained in:
committed by
Space Team
parent
358ad272f4
commit
16a27c2e05
+93
-68
@@ -30,16 +30,74 @@ import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl
|
|||||||
import org.jetbrains.kotlin.util.removeSuffixIfPresent
|
import org.jetbrains.kotlin.util.removeSuffixIfPresent
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||||
|
|
||||||
internal class KlibToolCommand(private val output: KlibToolOutput, private val args: KlibToolArguments) {
|
internal sealed class KlibToolCommand(
|
||||||
|
protected val output: KlibToolOutput,
|
||||||
|
protected val args: KlibToolArguments
|
||||||
|
) {
|
||||||
|
protected val klibRepoDeprecationWarning = KlibRepoDeprecationWarning()
|
||||||
|
|
||||||
private val klibRepoDeprecationWarning = KlibRepoDeprecationWarning(output)
|
protected val repository: File = args.repository?.let {
|
||||||
|
|
||||||
private val repository = args.repository?.let {
|
|
||||||
klibRepoDeprecationWarning.logOnceIfNecessary() // Due to use of "-repository" option.
|
klibRepoDeprecationWarning.logOnceIfNecessary() // Due to use of "-repository" option.
|
||||||
File(it)
|
File(it)
|
||||||
} ?: defaultRepository
|
} ?: getDefaultRepository()
|
||||||
|
|
||||||
fun info() {
|
abstract fun execute()
|
||||||
|
|
||||||
|
protected fun checkLibraryHasIr(library: KotlinLibrary): Boolean {
|
||||||
|
if (!library.hasIr) {
|
||||||
|
output.logError("Library ${library.libraryFile} is an IR-less library")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
protected 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
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun KotlinIrSignatureVersion?.getMostSuitableSignatureRenderer(): IdSignatureRenderer? = when (this) {
|
||||||
|
KotlinIrSignatureVersion.V1 -> IdSignatureRenderer.LEGACY
|
||||||
|
null, KotlinIrSignatureVersion.V2 -> IdSignatureRenderer.DEFAULT
|
||||||
|
else -> {
|
||||||
|
output.logError("Unsupported signature version: $number")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun libraryInRepo(repository: File, name: String) =
|
||||||
|
resolverByName(listOf(repository.absolutePath), skipCurrentDir = true, logger = KlibToolLogger(output)).resolve(name)
|
||||||
|
|
||||||
|
protected fun libraryInCurrentDir(name: String) = resolverByName(emptyList(), logger = KlibToolLogger(output)).resolve(name)
|
||||||
|
|
||||||
|
protected fun libraryInRepoOrCurrentDir(repository: File, name: String) =
|
||||||
|
resolverByName(listOf(repository.absolutePath), logger = KlibToolLogger(output)).resolve(name)
|
||||||
|
|
||||||
|
protected inner class KlibRepoDeprecationWarning {
|
||||||
|
private var alreadyLogged = false
|
||||||
|
|
||||||
|
fun logOnceIfNecessary() {
|
||||||
|
if (!alreadyLogged) {
|
||||||
|
alreadyLogged = true
|
||||||
|
output.logWarning("Local KLIB repositories to be dropped soon. See https://youtrack.jetbrains.com/issue/KT-61098")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun getDefaultRepository(): File = File(DependencyDirectories.localKonanDir.resolve("klib").absolutePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class Info(output: KlibToolOutput, args: KlibToolArguments) : KlibToolCommand(output, args) {
|
||||||
|
override fun execute() {
|
||||||
val library = libraryInRepoOrCurrentDir(repository, args.libraryNameOrPath)
|
val library = libraryInRepoOrCurrentDir(repository, args.libraryNameOrPath)
|
||||||
val headerAbiVersion = library.versions.abiVersion
|
val headerAbiVersion = library.versions.abiVersion
|
||||||
val headerCompilerVersion = library.versions.compilerVersion
|
val headerCompilerVersion = library.versions.compilerVersion
|
||||||
@@ -59,8 +117,10 @@ internal class KlibToolCommand(private val output: KlibToolOutput, private val a
|
|||||||
output.appendLine("Available targets: ${library.targetList.joinToString()}")
|
output.appendLine("Available targets: ${library.targetList.joinToString()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun install() {
|
internal class LegacyInstall(output: KlibToolOutput, args: KlibToolArguments) : KlibToolCommand(output, args) {
|
||||||
|
override fun execute() {
|
||||||
klibRepoDeprecationWarning.logOnceIfNecessary()
|
klibRepoDeprecationWarning.logOnceIfNecessary()
|
||||||
|
|
||||||
if (!repository.exists) {
|
if (!repository.exists) {
|
||||||
@@ -77,8 +137,10 @@ internal class KlibToolCommand(private val output: KlibToolOutput, private val a
|
|||||||
|
|
||||||
library.libraryFile.unpackZippedKonanLibraryTo(installLibDir)
|
library.libraryFile.unpackZippedKonanLibraryTo(installLibDir)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun remove() {
|
internal class LegacyRemove(output: KlibToolOutput, args: KlibToolArguments) : KlibToolCommand(output, args) {
|
||||||
|
override fun execute() {
|
||||||
klibRepoDeprecationWarning.logOnceIfNecessary()
|
klibRepoDeprecationWarning.logOnceIfNecessary()
|
||||||
|
|
||||||
if (!repository.exists) {
|
if (!repository.exists) {
|
||||||
@@ -90,9 +152,11 @@ internal class KlibToolCommand(private val output: KlibToolOutput, private val a
|
|||||||
libraryInRepo(repository, args.libraryNameOrPath).libraryFile.deleteRecursively()
|
libraryInRepo(repository, args.libraryNameOrPath).libraryFile.deleteRecursively()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DumpIr(output: KlibToolOutput, args: KlibToolArguments) : KlibToolCommand(output, args) {
|
||||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||||
fun dumpIr() {
|
override fun execute() {
|
||||||
val library = libraryInRepoOrCurrentDir(repository, args.libraryNameOrPath)
|
val library = libraryInRepoOrCurrentDir(repository, args.libraryNameOrPath)
|
||||||
|
|
||||||
if (!checkLibraryHasIr(library)) return
|
if (!checkLibraryHasIr(library)) return
|
||||||
@@ -120,9 +184,11 @@ internal class KlibToolCommand(private val output: KlibToolOutput, private val a
|
|||||||
|
|
||||||
output.append(irFragment.dump(DumpIrTreeOptions(printSignatures = args.printSignatures)))
|
output.append(irFragment.dump(DumpIrTreeOptions(printSignatures = args.printSignatures)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DumpAbi(output: KlibToolOutput, args: KlibToolArguments) : KlibToolCommand(output, args) {
|
||||||
@OptIn(ExperimentalLibraryAbiReader::class)
|
@OptIn(ExperimentalLibraryAbiReader::class)
|
||||||
fun dumpAbi() {
|
override fun execute() {
|
||||||
val library = libraryInCurrentDir(args.libraryNameOrPath)
|
val library = libraryInCurrentDir(args.libraryNameOrPath)
|
||||||
|
|
||||||
if (!checkLibraryHasIr(library)) return
|
if (!checkLibraryHasIr(library)) return
|
||||||
@@ -174,9 +240,11 @@ internal class KlibToolCommand(private val output: KlibToolOutput, private val a
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: This command is deprecated. Drop it after 2.0. KT-65380
|
// TODO: This command is deprecated. Drop it after 2.0. KT-65380
|
||||||
fun contents() {
|
internal class LegacyContents(output: KlibToolOutput, args: KlibToolArguments) : KlibToolCommand(output, args) {
|
||||||
|
override fun execute() {
|
||||||
output.logWarning("\"contents\" has been renamed to \"dump-metadata\". Please, use new command name.")
|
output.logWarning("\"contents\" has been renamed to \"dump-metadata\". Please, use new command name.")
|
||||||
|
|
||||||
val idSignatureRenderer = args.signatureVersion.getMostSuitableSignatureRenderer() ?: return
|
val idSignatureRenderer = args.signatureVersion.getMostSuitableSignatureRenderer() ?: return
|
||||||
@@ -190,20 +258,26 @@ internal class KlibToolCommand(private val output: KlibToolOutput, private val a
|
|||||||
|
|
||||||
printer.print(module)
|
printer.print(module)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun dumpMetadata() {
|
internal class DumpMetadata(output: KlibToolOutput, args: KlibToolArguments) : KlibToolCommand(output, args) {
|
||||||
|
override fun execute() {
|
||||||
val idSignatureRenderer: IdSignatureRenderer? = runIf(args.printSignatures) {
|
val idSignatureRenderer: IdSignatureRenderer? = runIf(args.printSignatures) {
|
||||||
args.signatureVersion.getMostSuitableSignatureRenderer() ?: return
|
args.signatureVersion.getMostSuitableSignatureRenderer() ?: return
|
||||||
}
|
}
|
||||||
KotlinpBasedMetadataDumper(output, idSignatureRenderer).dumpLibrary(libraryInCurrentDir(args.libraryNameOrPath), args.testMode)
|
KotlinpBasedMetadataDumper(output, idSignatureRenderer).dumpLibrary(libraryInCurrentDir(args.libraryNameOrPath), args.testMode)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun signatures() {
|
internal class LegacySignatures(output: KlibToolOutput, args: KlibToolArguments) : KlibToolCommand(output, args) {
|
||||||
|
override fun execute() {
|
||||||
output.logWarning("\"signatures\" has been renamed to \"dump-metadata-signatures\". Please, use new command name.")
|
output.logWarning("\"signatures\" has been renamed to \"dump-metadata-signatures\". Please, use new command name.")
|
||||||
dumpMetadataSignatures()
|
DumpMetadataSignatures(output, args).execute()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun dumpMetadataSignatures() {
|
internal class DumpMetadataSignatures(output: KlibToolOutput, args: KlibToolArguments) : KlibToolCommand(output, args) {
|
||||||
|
override fun execute() {
|
||||||
// Don't call `checkSupportedInLibrary()` - the signatures are anyway generated on the fly.
|
// Don't call `checkSupportedInLibrary()` - the signatures are anyway generated on the fly.
|
||||||
|
|
||||||
val idSignatureRenderer = args.signatureVersion.getMostSuitableSignatureRenderer() ?: return
|
val idSignatureRenderer = args.signatureVersion.getMostSuitableSignatureRenderer() ?: return
|
||||||
@@ -213,8 +287,10 @@ internal class KlibToolCommand(private val output: KlibToolOutput, private val a
|
|||||||
|
|
||||||
printer.print(module)
|
printer.print(module)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun dumpIrSignatures() {
|
internal class DumpIrSignatures(output: KlibToolOutput, args: KlibToolArguments) : KlibToolCommand(output, args) {
|
||||||
|
override fun execute() {
|
||||||
val library = libraryInCurrentDir(args.libraryNameOrPath)
|
val library = libraryInCurrentDir(args.libraryNameOrPath)
|
||||||
|
|
||||||
if (!checkLibraryHasIr(library) || !args.signatureVersion.checkSupportedInLibrary(library)) return
|
if (!checkLibraryHasIr(library) || !args.signatureVersion.checkSupportedInLibrary(library)) return
|
||||||
@@ -224,55 +300,4 @@ internal class KlibToolCommand(private val output: KlibToolOutput, private val a
|
|||||||
val signatures = IrSignaturesExtractor(library).extract()
|
val signatures = IrSignaturesExtractor(library).extract()
|
||||||
IrSignaturesRenderer(output, idSignatureRenderer).render(signatures)
|
IrSignaturesRenderer(output, idSignatureRenderer).render(signatures)
|
||||||
}
|
}
|
||||||
|
|
||||||
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): 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: File, 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: File, name: String) =
|
|
||||||
resolverByName(listOf(repository.absolutePath), logger = KlibToolLogger(output)).resolve(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private val defaultRepository = File(DependencyDirectories.localKonanDir.resolve("klib").absolutePath)
|
|
||||||
|
|
||||||
private class KlibRepoDeprecationWarning(private val output: KlibToolOutput) {
|
|
||||||
private var alreadyLogged = false
|
|
||||||
|
|
||||||
fun logOnceIfNecessary() {
|
|
||||||
if (!alreadyLogged) {
|
|
||||||
alreadyLogged = true
|
|
||||||
output.logWarning("Local KLIB repositories to be dropped soon. See https://youtrack.jetbrains.com/issue/KT-61098")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,22 +13,25 @@ fun main(rawArgs: Array<String>) {
|
|||||||
|
|
||||||
val args = KlibToolArgumentsParser(output).parseArguments(rawArgs)
|
val args = KlibToolArgumentsParser(output).parseArguments(rawArgs)
|
||||||
if (args != null) {
|
if (args != null) {
|
||||||
val command = KlibToolCommand(output, args)
|
val command = when (args.commandName) {
|
||||||
|
"dump-abi" -> DumpAbi(output, args)
|
||||||
|
"dump-ir" -> DumpIr(output, args)
|
||||||
|
"dump-ir-signatures" -> DumpIrSignatures(output, args)
|
||||||
|
"dump-metadata" -> DumpMetadata(output, args)
|
||||||
|
"dump-metadata-signatures" -> DumpMetadataSignatures(output, args)
|
||||||
|
"contents" -> LegacyContents(output, args)
|
||||||
|
"signatures" -> LegacySignatures(output, args)
|
||||||
|
"info" -> Info(output, args)
|
||||||
|
"install" -> LegacyInstall(output, args)
|
||||||
|
"remove" -> LegacyRemove(output, args)
|
||||||
|
else -> {
|
||||||
|
output.logError("Unknown command: ${args.commandName}")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
when (args.commandName) {
|
command?.execute()
|
||||||
"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) {
|
} catch (t: Throwable) {
|
||||||
output.logErrorWithStackTrace(t)
|
output.logErrorWithStackTrace(t)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user