[KLIB tool] Support metadata format by kotlinp
Use the unified metadata printing format in KLIB tool. The same format is already used in `kotlinp` CLI tool. ^KT-62340
This commit is contained in:
committed by
Space Team
parent
83cc0d75a7
commit
f9f97f2050
@@ -18,6 +18,9 @@ dependencies {
|
||||
implementation(project(":compiler:ir.psi2ir"))
|
||||
implementation(project(":compiler:ir.serialization.native"))
|
||||
implementation(project(":kotlin-util-klib-abi"))
|
||||
implementation(project(":tools:kotlinp-klib"))
|
||||
implementation(project(":kotlinx-metadata-klib")) { isTransitive = false }
|
||||
implementation(project(":kotlinx-metadata")) { isTransitive = false }
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
|
||||
|
||||
+239
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import kotlinx.metadata.KmConstructor
|
||||
import kotlinx.metadata.KmFunction
|
||||
import kotlinx.metadata.KmPackage
|
||||
import kotlinx.metadata.KmProperty
|
||||
import kotlinx.metadata.internal.common.KmModuleFragment
|
||||
import kotlinx.metadata.klib.KlibModuleMetadata
|
||||
import kotlinx.metadata.klib.className
|
||||
import kotlinx.metadata.klib.fqName
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
|
||||
import org.jetbrains.kotlin.ir.util.IdSignatureRenderer
|
||||
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?
|
||||
) {
|
||||
// `null` means no signatures should be rendered.
|
||||
private val signatureRenderer = runIf(printSignatures) { signatureVersion.getMostSuitableSignatureRenderer() }
|
||||
|
||||
private val printer = Printer(output)
|
||||
|
||||
fun dumpLibrary(library: KotlinLibrary, testMode: Boolean) {
|
||||
val moduleMetadata = loadModuleMetadata(library)
|
||||
.let { originalModuleMetadata -> if (testMode) preprocessMetadataForTests(originalModuleMetadata) else originalModuleMetadata }
|
||||
|
||||
val signatureComputer = prepareSignatureComputer(library, moduleMetadata)
|
||||
|
||||
KlibKotlinp(DEFAULT_SETTINGS, signatureComputer).renderModule(moduleMetadata, printer)
|
||||
}
|
||||
|
||||
private fun preprocessMetadataForTests(originalModuleMetadata: KlibModuleMetadata) = KlibModuleMetadata(
|
||||
name = originalModuleMetadata.name,
|
||||
fragments = originalModuleMetadata.fragments.groupBy { it.fqName }.mapNotNull { (packageFqName, fragments) ->
|
||||
val classNames = fragments.flatMap { it.className }.sorted()
|
||||
val classes = fragments.flatMap { it.classes }.sortedBy { it.name }
|
||||
val functions = fragments.flatMap { it.pkg?.functions.orEmpty() }.sortedBy { it.sortingKey() }
|
||||
val properties = fragments.flatMap { it.pkg?.properties.orEmpty() }.sortedBy { it.sortingKey() }
|
||||
val typeAliases = fragments.flatMap { it.pkg?.typeAliases.orEmpty() }.sortedBy { it.name }
|
||||
|
||||
if (classNames.isEmpty() && classes.isEmpty() && functions.isEmpty() && properties.isEmpty() && typeAliases.isEmpty())
|
||||
return@mapNotNull null
|
||||
|
||||
classes.forEach { clazz ->
|
||||
clazz.constructors.sortBy { it.sortingKey() }
|
||||
clazz.functions.sortBy { it.sortingKey() }
|
||||
clazz.properties.sortBy { it.sortingKey() }
|
||||
clazz.typeAliases.sortBy { it.name }
|
||||
}
|
||||
|
||||
KmModuleFragment().apply {
|
||||
this.fqName = packageFqName
|
||||
this.className += classNames
|
||||
this.classes += classes
|
||||
|
||||
if (functions.isNotEmpty() || properties.isNotEmpty() || typeAliases.isNotEmpty()) {
|
||||
this.pkg = KmPackage().apply {
|
||||
this.functions += functions
|
||||
this.properties += properties
|
||||
this.typeAliases += typeAliases
|
||||
}
|
||||
}
|
||||
}
|
||||
}.sortedBy { it.fqName.orEmpty() },
|
||||
annotations = originalModuleMetadata.annotations
|
||||
)
|
||||
|
||||
private fun loadModuleMetadata(library: KotlinLibrary) = KlibModuleMetadata.read(
|
||||
object : KlibModuleMetadata.MetadataLibraryProvider {
|
||||
override val moduleHeaderData get() = library.moduleHeaderData
|
||||
override fun packageMetadata(fqName: String, partName: String) = library.packageMetadata(fqName, partName)
|
||||
override fun packageMetadataParts(fqName: String) = library.packageMetadataParts(fqName)
|
||||
}
|
||||
)
|
||||
|
||||
private fun prepareSignatureComputer(library: KotlinLibrary, moduleMetadata: KlibModuleMetadata): ExternalSignatureComputer? {
|
||||
val signatureCollector = SignaturesCollector(signatureRenderer ?: return null)
|
||||
|
||||
val moduleDescriptor = ModuleDescriptorLoader.load(library)
|
||||
moduleDescriptor.accept(signatureCollector, Unit)
|
||||
|
||||
return ExternalSignatureComputer(moduleMetadata, signatureCollector.signatures::get)
|
||||
}
|
||||
|
||||
private fun KmConstructor.sortingKey() = constructorId("")
|
||||
private fun KmFunction.sortingKey() = functionId("")
|
||||
private fun KmProperty.sortingKey() = propertyId("")
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_SETTINGS = Settings(isVerbose = true, sortDeclarations = true)
|
||||
}
|
||||
}
|
||||
|
||||
private class SignaturesCollector(private val renderer: IdSignatureRenderer) : DeclarationDescriptorVisitorEmptyBodies<Unit, Unit>() {
|
||||
private val signaturer = KonanIdSignaturer(KonanManglerDesc)
|
||||
|
||||
val signatures = hashMapOf<DeclarationId, String>()
|
||||
|
||||
override fun visitModuleDeclaration(module: ModuleDescriptor, data: Unit) {
|
||||
module.getPackageFragments().forEach { it.accept(this, data) }
|
||||
}
|
||||
|
||||
override fun visitPackageFragmentDescriptor(fragment: PackageFragmentDescriptor, data: Unit) {
|
||||
fragment.getMemberScope().getContributedDescriptors().forEach { it.accept(this, data) }
|
||||
}
|
||||
|
||||
override fun visitClassDescriptor(clazz: ClassDescriptor, data: Unit) {
|
||||
if (clazz.kind == ClassKind.ENUM_ENTRY) {
|
||||
collectEnumEntrySignature(clazz)
|
||||
} else {
|
||||
collectSignature(clazz) { clazz.id() }
|
||||
}
|
||||
|
||||
clazz.constructors.forEach { it.accept(this, data) }
|
||||
clazz.unsubstitutedMemberScope.getContributedDescriptors().forEach { it.accept(this, data) }
|
||||
}
|
||||
|
||||
override fun visitConstructorDescriptor(constructor: ConstructorDescriptor, data: Unit) {
|
||||
collectSignature(constructor) { constructor.id() }
|
||||
}
|
||||
|
||||
override fun visitFunctionDescriptor(function: FunctionDescriptor, data: Unit) {
|
||||
collectSignature(function) { function.id() }
|
||||
}
|
||||
|
||||
override fun visitPropertyDescriptor(property: PropertyDescriptor, data: Unit) {
|
||||
collectSignature(property) { property.id() }
|
||||
property.getter?.accept(this, data)
|
||||
property.setter?.accept(this, data)
|
||||
}
|
||||
|
||||
override fun visitPropertyGetterDescriptor(getter: PropertyGetterDescriptor, data: Unit) {
|
||||
collectSignature(getter) { getter.id() }
|
||||
}
|
||||
|
||||
override fun visitPropertySetterDescriptor(setter: PropertySetterDescriptor, data: Unit) {
|
||||
collectSignature(setter) { setter.id(ignoreParameterNames = true) }
|
||||
}
|
||||
|
||||
override fun visitTypeAliasDescriptor(typeAlias: TypeAliasDescriptor, data: Unit) {
|
||||
collectSignature(typeAlias) { typeAlias.id() }
|
||||
}
|
||||
|
||||
private inline fun <T : DeclarationDescriptor> collectSignature(descriptor: T, id: T.() -> DeclarationId?) {
|
||||
val rawSignature = signaturer.composeSignature(descriptor) ?: return
|
||||
val renderedSignature = renderer.render(rawSignature)
|
||||
val declarationId = descriptor.id() ?: return
|
||||
signatures[declarationId] = renderedSignature
|
||||
}
|
||||
|
||||
private fun collectEnumEntrySignature(clazz: ClassDescriptor) {
|
||||
val rawSignature = signaturer.composeEnumEntrySignature(clazz) ?: return
|
||||
val renderedSignature = renderer.render(rawSignature)
|
||||
val declarationId = clazz.id() ?: return
|
||||
signatures[declarationId] = renderedSignature
|
||||
}
|
||||
|
||||
private fun ClassifierDescriptorWithTypeParameters.id() = classId?.asString()?.let(::ClassOrTypeAliasId)
|
||||
|
||||
private fun DeclarationDescriptor.qualifiedName(): String {
|
||||
fun ClassifierDescriptorWithTypeParameters.classIdOrFail() = classId
|
||||
?: error("Failed to compute class ID for ${this::class.java}, $this")
|
||||
|
||||
return when (this) {
|
||||
is ClassifierDescriptorWithTypeParameters -> classIdOrFail()
|
||||
is CallableDescriptor -> when (val containingDeclaration = containingDeclaration) {
|
||||
is ClassifierDescriptorWithTypeParameters -> containingDeclaration.classIdOrFail().createNestedClassId(name)
|
||||
is PackageFragmentDescriptor -> ClassId(containingDeclaration.fqName, name)
|
||||
else -> containingDeclaration.unexpectedDeclarationType()
|
||||
}
|
||||
else -> unexpectedDeclarationType()
|
||||
}.asString()
|
||||
}
|
||||
|
||||
private fun ConstructorDescriptor.id() = ConstructorId(
|
||||
qualifiedName = qualifiedName(),
|
||||
parameters = valueParameters.map { it.id(ignoreName = false) }
|
||||
)
|
||||
|
||||
private fun PropertyDescriptor.id() = PropertyId(
|
||||
qualifiedName = qualifiedName(),
|
||||
contextReceivers = contextReceiverParameters.map { it.type.id() },
|
||||
extensionReceiver = extensionReceiverParameter?.type?.id(),
|
||||
returnType = type.id()
|
||||
)
|
||||
|
||||
private fun FunctionDescriptor.id(ignoreParameterNames: Boolean = false) = FunctionId(
|
||||
qualifiedName = qualifiedName(),
|
||||
contextReceivers = contextReceiverParameters.map { it.type.id() },
|
||||
extensionReceiver = extensionReceiverParameter?.type?.id(),
|
||||
parameters = valueParameters.map { it.id(ignoreParameterNames) },
|
||||
returnType = returnType?.id() ?: error("Function without return type: ${this::class.java}, $this")
|
||||
)
|
||||
|
||||
private fun Variance.id() = when (this) {
|
||||
Variance.INVARIANT -> VarianceId.INVARIANT
|
||||
Variance.IN_VARIANCE -> VarianceId.IN
|
||||
Variance.OUT_VARIANCE -> VarianceId.OUT
|
||||
}
|
||||
|
||||
private fun SimpleType.classifierId(): ClassifierId = when (val typeConstructorDescriptor = constructor.declarationDescriptor) {
|
||||
is TypeParameterDescriptor -> TypeParameterId(typeConstructorDescriptor.index)
|
||||
is ClassifierDescriptorWithTypeParameters -> ClassOrTypeAliasId(typeConstructorDescriptor.qualifiedName())
|
||||
else -> typeConstructorDescriptor.unexpectedDeclarationType()
|
||||
}
|
||||
|
||||
private fun TypeProjection.id() = if (isStarProjection) TypeArgumentId.Star else TypeArgumentId.Regular(type.id(), projectionKind.id())
|
||||
|
||||
private fun KotlinType.id(): TypeId {
|
||||
val simpleType = asSimpleType()
|
||||
return TypeId(simpleType.classifierId(), simpleType.arguments.map { it.id() })
|
||||
}
|
||||
|
||||
private fun ValueParameterDescriptor.id(ignoreName: Boolean) =
|
||||
if (ignoreName) ParameterId(type.id(), isVararg) else ParameterId(name.asString(), type.id(), isVararg)
|
||||
|
||||
private fun DeclarationDescriptor?.unexpectedDeclarationType(): Nothing =
|
||||
error(if (this == null) "Declaration descriptor is null" else "Unexpected declaration type: ${this::class.java}, $this")
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.config.ApiVersion
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||
import org.jetbrains.kotlin.konan.library.resolverByName
|
||||
import org.jetbrains.kotlin.konan.target.Distribution
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.utils.KotlinNativePaths
|
||||
|
||||
internal object ModuleDescriptorLoader {
|
||||
fun load(library: KotlinLibrary): ModuleDescriptorImpl {
|
||||
val storageManager = LockBasedStorageManager("klib")
|
||||
|
||||
val module = KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(library, languageVersionSettings, storageManager, null)
|
||||
|
||||
val defaultModules = mutableListOf<ModuleDescriptorImpl>()
|
||||
if (!module.isNativeStdlib()) {
|
||||
val resolver = resolverByName(
|
||||
emptyList(),
|
||||
distributionKlib = Distribution(KotlinNativePaths.homePath.absolutePath).klib,
|
||||
skipCurrentDir = true,
|
||||
logger = KlibToolLogger
|
||||
)
|
||||
resolver.defaultLinks(noStdLib = false, noDefaultLibs = true, noEndorsedLibs = true).mapTo(defaultModules) {
|
||||
KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptor(it, languageVersionSettings, storageManager, module.builtIns, null)
|
||||
}
|
||||
}
|
||||
|
||||
(defaultModules + module).let { allModules ->
|
||||
allModules.forEach { it.setDependencies(allModules) }
|
||||
}
|
||||
|
||||
return module
|
||||
}
|
||||
|
||||
val languageVersionSettings = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE)
|
||||
|
||||
private val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer)
|
||||
}
|
||||
@@ -12,17 +12,10 @@ import org.jetbrains.kotlin.backend.common.serialization.BasicIrModuleDeserializ
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
|
||||
import org.jetbrains.kotlin.backend.common.serialization.IrModuleDeserializer
|
||||
import org.jetbrains.kotlin.backend.common.serialization.KotlinIrLinker
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.config.ApiVersion
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
|
||||
@@ -34,26 +27,19 @@ import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.library.resolverByName
|
||||
import org.jetbrains.kotlin.konan.target.Distribution
|
||||
import org.jetbrains.kotlin.konan.util.DependencyDirectories
|
||||
import org.jetbrains.kotlin.utils.KotlinNativePaths
|
||||
import org.jetbrains.kotlin.library.*
|
||||
import org.jetbrains.kotlin.library.abi.*
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||
import org.jetbrains.kotlin.library.metadata.kotlinLibrary
|
||||
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
|
||||
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
|
||||
import org.jetbrains.kotlin.psi2ir.generators.TypeTranslatorImpl
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.util.Logger
|
||||
import org.jetbrains.kotlin.util.removeSuffixIfPresent
|
||||
import java.io.File
|
||||
import kotlin.system.exitProcess
|
||||
import org.jetbrains.kotlin.konan.file.File as KFile
|
||||
|
||||
private val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer)
|
||||
|
||||
fun printUsage() {
|
||||
println(
|
||||
"""
|
||||
@@ -79,9 +65,9 @@ fun printUsage() {
|
||||
(such as Compose) were used during compilation of the library, there would be different
|
||||
signatures for patched declarations.
|
||||
signatures [DEPRECATED] Renamed to "dump-metadata-signatures". Please, use new command name.
|
||||
dump-metadata Dump the metadata of all non-private declarations in the library in the form of Kotlin-alike code.
|
||||
The output of this command is intended to be used for debugging purposes only.
|
||||
contents [DEPRECATED] Renamed to "dump-metadata". Please, use new command name.
|
||||
dump-metadata Dump the metadata of all declarations in the library. The output of this command is intended
|
||||
to be used for debugging purposes only.
|
||||
contents [DEPRECATED] Reworked and renamed to "dump-metadata". Please, use new command name.
|
||||
|
||||
and the options are:
|
||||
-repository <path> [DEPRECATED] Local KLIB repositories to be dropped soon. See https://youtrack.jetbrains.com/issue/KT-61098
|
||||
@@ -178,18 +164,6 @@ object KlibToolLogger : Logger, IrMessageLogger {
|
||||
|
||||
val defaultRepository = KFile(DependencyDirectories.localKonanDir.resolve("klib").absolutePath)
|
||||
|
||||
open class ModuleDeserializer(val library: ByteArray) {
|
||||
protected val moduleHeader: KlibMetadataProtoBuf.Header
|
||||
get() = parseModuleHeader(library)
|
||||
|
||||
val moduleName: String
|
||||
get() = moduleHeader.moduleName
|
||||
|
||||
val packageFragmentNameList: List<String>
|
||||
get() = moduleHeader.packageFragmentNameList
|
||||
|
||||
}
|
||||
|
||||
private class KlibRepoDeprecationWarning {
|
||||
private var alreadyLogged = false
|
||||
|
||||
@@ -216,7 +190,7 @@ class Library(val libraryNameOrPath: String, val requestedRepository: String?) {
|
||||
val headerCompilerVersion = library.versions.compilerVersion
|
||||
val headerLibraryVersion = library.versions.libraryVersion
|
||||
val headerMetadataVersion = library.versions.metadataVersion
|
||||
val moduleName = ModuleDeserializer(library.moduleHeaderData).moduleName
|
||||
val moduleName = parseModuleHeader(library.moduleHeaderData).moduleName
|
||||
|
||||
println("")
|
||||
println("Resolved to: ${KFile(library.libraryName).absolutePath}")
|
||||
@@ -269,15 +243,15 @@ class Library(val libraryNameOrPath: String, val requestedRepository: String?) {
|
||||
}
|
||||
|
||||
class KlibToolLinker(
|
||||
module: ModuleDescriptor, irBuiltIns: IrBuiltIns, symbolTable: SymbolTable
|
||||
module: ModuleDescriptor, irBuiltIns: IrBuiltIns, symbolTable: SymbolTable
|
||||
) : KotlinIrLinker(module, KlibToolLogger, irBuiltIns, symbolTable, emptyList()) {
|
||||
override val fakeOverrideBuilder = IrLinkerFakeOverrideProvider(
|
||||
linker = this,
|
||||
symbolTable = symbolTable,
|
||||
mangler = KonanManglerIr,
|
||||
typeSystem = IrTypeSystemContextImpl(builtIns),
|
||||
friendModules = emptyMap(),
|
||||
partialLinkageSupport = PartialLinkageSupportForLinker.DISABLED,
|
||||
linker = this,
|
||||
symbolTable = symbolTable,
|
||||
mangler = KonanManglerIr,
|
||||
typeSystem = IrTypeSystemContextImpl(builtIns),
|
||||
friendModules = emptyMap(),
|
||||
partialLinkageSupport = PartialLinkageSupportForLinker.DISABLED,
|
||||
)
|
||||
|
||||
override val returnUnboundSymbolsIfSignatureNotFound: Boolean
|
||||
@@ -313,8 +287,7 @@ class Library(val libraryNameOrPath: String, val requestedRepository: String?) {
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
fun dumpIr(output: Appendable, printSignatures: Boolean, signatureVersion: KotlinIrSignatureVersion?) {
|
||||
val module = loadModule()
|
||||
val library = module.kotlinLibrary
|
||||
val library = libraryInRepoOrCurrentDir(repository, libraryNameOrPath)
|
||||
checkLibraryHasIr(library)
|
||||
|
||||
if (signatureVersion != null && signatureVersion != KotlinIrSignatureVersion.V2) {
|
||||
@@ -322,10 +295,11 @@ class Library(val libraryNameOrPath: String, val requestedRepository: String?) {
|
||||
logWarning("using a non-default signature version in \"dump-ir\" is not supported yet")
|
||||
}
|
||||
|
||||
val versionSpec = LanguageVersionSettingsImpl(currentLanguageVersion, currentApiVersion)
|
||||
val module = ModuleDescriptorLoader.load(library)
|
||||
|
||||
val idSignaturer = KonanIdSignaturer(KonanManglerDesc)
|
||||
val symbolTable = SymbolTable(idSignaturer, IrFactoryImpl)
|
||||
val typeTranslator = TypeTranslatorImpl(symbolTable, versionSpec, module)
|
||||
val typeTranslator = TypeTranslatorImpl(symbolTable, ModuleDescriptorLoader.languageVersionSettings, module)
|
||||
val irBuiltIns = IrBuiltInsOverDescriptors(module.builtIns, typeTranslator, symbolTable)
|
||||
|
||||
val linker = KlibToolLinker(module, irBuiltIns, symbolTable)
|
||||
@@ -391,11 +365,7 @@ class Library(val libraryNameOrPath: String, val requestedRepository: String?) {
|
||||
|
||||
fun contents(output: Appendable, printSignatures: Boolean, signatureVersion: KotlinIrSignatureVersion?) {
|
||||
logWarning("\"contents\" has been renamed to \"dump-metadata\". Please, use new command name.")
|
||||
dumpMetadata(output, printSignatures, signatureVersion)
|
||||
}
|
||||
|
||||
fun dumpMetadata(output: Appendable, printSignatures: Boolean, signatureVersion: KotlinIrSignatureVersion?) {
|
||||
val module = loadModule()
|
||||
val module = ModuleDescriptorLoader.load(libraryInRepoOrCurrentDir(repository, libraryNameOrPath))
|
||||
val signatureRenderer = if (printSignatures)
|
||||
DefaultKlibSignatureRenderer(signatureVersion, "// Signature: ")
|
||||
else
|
||||
@@ -405,13 +375,23 @@ class Library(val libraryNameOrPath: String, val requestedRepository: String?) {
|
||||
printer.print(module)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param testMode if `true` then a special pre-processing is performed towards the metadata before rendering:
|
||||
* - empty package fragments are removed
|
||||
* - package fragments with the same package FQN are merged
|
||||
* - classes are sorted in alphabetical order
|
||||
*/
|
||||
fun dumpMetadata(output: Appendable, printSignatures: Boolean, signatureVersion: KotlinIrSignatureVersion?, testMode: Boolean) {
|
||||
KotlinpBasedMetadataDumper(output, printSignatures, signatureVersion).dumpLibrary(libraryInCurrentDir(libraryNameOrPath), testMode)
|
||||
}
|
||||
|
||||
fun signatures(output: Appendable, signatureVersion: KotlinIrSignatureVersion?) {
|
||||
logWarning("\"signatures\" has been renamed to \"dump-metadata-signatures\". Please, use new command name.")
|
||||
dumpMetadataSignatures(output, signatureVersion)
|
||||
}
|
||||
|
||||
fun dumpMetadataSignatures(output: Appendable, signatureVersion: KotlinIrSignatureVersion?) {
|
||||
val module = loadModule()
|
||||
val module = ModuleDescriptorLoader.load(libraryInRepoOrCurrentDir(repository, libraryNameOrPath))
|
||||
// Don't call `checkSupportedInLibrary()` - the signatures are anyway generated on the fly.
|
||||
val printer = SignaturePrinter(output, DefaultKlibSignatureRenderer(signatureVersion))
|
||||
|
||||
@@ -437,37 +417,8 @@ class Library(val libraryNameOrPath: String, val requestedRepository: String?) {
|
||||
logError("Signature version ${this.number} is not supported in library ${library.libraryFile}." +
|
||||
" Supported versions: ${supportedSignatureVersions.joinToString { it.number.toString() }}")
|
||||
}
|
||||
|
||||
private fun loadModule(): ModuleDescriptor {
|
||||
val storageManager = LockBasedStorageManager("klib")
|
||||
val library = libraryInRepoOrCurrentDir(repository, libraryNameOrPath)
|
||||
val versionSpec = LanguageVersionSettingsImpl(currentLanguageVersion, currentApiVersion)
|
||||
val module = KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(library, versionSpec, storageManager, null)
|
||||
|
||||
val defaultModules = mutableListOf<ModuleDescriptorImpl>()
|
||||
if (!module.isNativeStdlib()) {
|
||||
val resolver = resolverByName(
|
||||
emptyList(),
|
||||
distributionKlib = Distribution(KotlinNativePaths.homePath.absolutePath).klib,
|
||||
skipCurrentDir = true,
|
||||
logger = KlibToolLogger
|
||||
)
|
||||
resolver.defaultLinks(false, true, true).mapTo(defaultModules) {
|
||||
KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptor(it, versionSpec, storageManager, module.builtIns, null)
|
||||
}
|
||||
}
|
||||
|
||||
(defaultModules + module).let { allModules ->
|
||||
allModules.forEach { it.setDependencies(allModules) }
|
||||
}
|
||||
|
||||
return module
|
||||
}
|
||||
}
|
||||
|
||||
val currentLanguageVersion = LanguageVersion.LATEST_STABLE
|
||||
val currentApiVersion = ApiVersion.LATEST_STABLE
|
||||
|
||||
fun libraryInRepo(repository: KFile, name: String) =
|
||||
resolverByName(listOf(repository.absolutePath), skipCurrentDir = true, logger = KlibToolLogger).resolve(name)
|
||||
|
||||
@@ -500,7 +451,7 @@ fun main(args: Array<String>) {
|
||||
"dump-abi" -> library.dumpAbi(System.out, signatureVersion)
|
||||
"dump-ir" -> library.dumpIr(System.out, printSignatures, signatureVersion)
|
||||
"dump-ir-signatures" -> library.dumpIrSignatures(System.out, signatureVersion)
|
||||
"dump-metadata" -> library.dumpMetadata(System.out, printSignatures, signatureVersion)
|
||||
"dump-metadata" -> library.dumpMetadata(System.out, printSignatures, signatureVersion, testMode = false)
|
||||
"dump-metadata-signatures" -> library.dumpMetadataSignatures(System.out, signatureVersion)
|
||||
"contents" -> library.contents(System.out, printSignatures, signatureVersion)
|
||||
"signatures" -> library.signatures(System.out, signatureVersion)
|
||||
|
||||
Reference in New Issue
Block a user