[KLIB tool] Print ID signatures
This commit is contained in:
committed by
Dmitriy Dolovov
parent
0ea834ea1f
commit
13cf470e33
@@ -0,0 +1,7 @@
|
||||
package org.jetbrains.kotlin.cli.klib
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
|
||||
interface DeclarationHeaderRenderer {
|
||||
fun render(descriptor: DeclarationDescriptor): String
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.jetbrains.kotlin.cli.klib
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class DeclarationPrinter(
|
||||
out: Appendable,
|
||||
private val headerRenderer: DeclarationHeaderRenderer,
|
||||
private val signatureRenderer: IdSignatureRenderer
|
||||
) {
|
||||
private val printer = Printer(out, 1, " ")
|
||||
|
||||
private val DeclarationDescriptorWithVisibility.isPublicOrProtected: Boolean
|
||||
get() = visibility == DescriptorVisibilities.PUBLIC || visibility == DescriptorVisibilities.PROTECTED
|
||||
|
||||
private val CallableMemberDescriptor.isFakeOverride: Boolean
|
||||
get() = kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||
|
||||
private val DeclarationDescriptor.shouldBePrinted: Boolean
|
||||
get() = this is ClassifierDescriptorWithTypeParameters && isPublicOrProtected
|
||||
|| this is CallableMemberDescriptor && isPublicOrProtected && !isFakeOverride
|
||||
|
||||
fun print(module: ModuleDescriptor) {
|
||||
module.accept(PrinterVisitor(), Unit)
|
||||
}
|
||||
|
||||
private fun Printer.printWithBody(header: String, signature: String? = null, body: () -> Unit) {
|
||||
println()
|
||||
printPlain(header, signature, suffix = " {")
|
||||
pushIndent()
|
||||
body()
|
||||
popIndent()
|
||||
println("}")
|
||||
println()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
private inner class PrinterVisitor : DeclarationDescriptorVisitorEmptyBodies<Unit, Unit>() {
|
||||
override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Unit) {
|
||||
descriptor.getPackageFragments().forEach { it.accept(this, data) }
|
||||
}
|
||||
|
||||
override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: Unit) {
|
||||
val children = descriptor.getMemberScope().getContributedDescriptors().filter { it.shouldBePrinted }
|
||||
if (children.isNotEmpty()) {
|
||||
printer.printWithBody(header = headerRenderer.render(descriptor)) {
|
||||
children.forEach { it.accept(this, data) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Unit) {
|
||||
val header = headerRenderer.render(descriptor)
|
||||
val signature = signatureRenderer.render(descriptor)
|
||||
|
||||
val children = descriptor.unsubstitutedMemberScope.getContributedDescriptors().filter { it.shouldBePrinted }
|
||||
val constructors = descriptor.constructors.filter { !it.isPrimary && it.shouldBePrinted }
|
||||
if (children.isNotEmpty() || constructors.isNotEmpty()) {
|
||||
printer.printWithBody(header, signature) {
|
||||
constructors.forEach { it.accept(this, data) }
|
||||
children.forEach { it.accept(this, data) }
|
||||
}
|
||||
} else {
|
||||
printer.printPlain(header, signature)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit) {
|
||||
printer.printPlain(header = headerRenderer.render(descriptor), signature = signatureRenderer.render(descriptor))
|
||||
}
|
||||
|
||||
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit) {
|
||||
printer.printPlain(header = headerRenderer.render(descriptor), signature = signatureRenderer.render(descriptor))
|
||||
descriptor.getter?.takeIf { !it.annotations.isEmpty() }?.let { getter ->
|
||||
printer.pushIndent()
|
||||
printer.printPlain(header = headerRenderer.render(getter), signature = signatureRenderer.render(getter))
|
||||
printer.popIndent()
|
||||
}
|
||||
descriptor.setter?.takeIf { !it.annotations.isEmpty() || it.visibility != descriptor.visibility }?.let { setter ->
|
||||
printer.pushIndent()
|
||||
printer.printPlain(header = headerRenderer.render(setter), signature = signatureRenderer.render(setter))
|
||||
printer.popIndent()
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit) {
|
||||
printer.printPlain(header = headerRenderer.render(descriptor), signature = signatureRenderer.render(descriptor))
|
||||
}
|
||||
|
||||
override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: Unit) {
|
||||
printer.printPlain(header = headerRenderer.render(descriptor), signature = signatureRenderer.render(descriptor))
|
||||
}
|
||||
}
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package org.jetbrains.kotlin.cli.klib
|
||||
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.renderer.AnnotationArgumentsRenderingPolicy
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRendererModifier
|
||||
import org.jetbrains.kotlin.renderer.OverrideRenderingPolicy
|
||||
|
||||
object DefaultDeclarationHeaderRenderer : DeclarationHeaderRenderer {
|
||||
override fun render(descriptor: DeclarationDescriptor): String = when (descriptor) {
|
||||
is PackageFragmentDescriptor -> render(descriptor)
|
||||
is ClassifierDescriptorWithTypeParameters -> render(descriptor)
|
||||
is PropertyAccessorDescriptor -> render(descriptor)
|
||||
is CallableMemberDescriptor -> render(descriptor)
|
||||
else -> throw AssertionError("Unknown declaration descriptor type: $descriptor")
|
||||
}
|
||||
|
||||
private fun render(descriptor: PackageFragmentDescriptor): String {
|
||||
val packageName = descriptor.fqName.let { if (it.isRoot) "<root>" else it.asString() }
|
||||
return "package $packageName"
|
||||
}
|
||||
|
||||
private fun render(descriptor: ClassifierDescriptorWithTypeParameters): String {
|
||||
val renderer = when (descriptor.modality) {
|
||||
// Don't render 'final' modality
|
||||
Modality.FINAL -> Renderers.WITHOUT_MODALITY
|
||||
else -> Renderers.DEFAULT
|
||||
}
|
||||
return renderer.render(descriptor)
|
||||
}
|
||||
|
||||
private fun render(descriptor: CallableMemberDescriptor): String {
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
val renderer = when {
|
||||
// Don't render modality for non-override final methods and interface methods.
|
||||
containingDeclaration is ClassDescriptor && containingDeclaration.kind == ClassKind.INTERFACE ||
|
||||
descriptor.modality == Modality.FINAL && descriptor.overriddenDescriptors.isEmpty() -> Renderers.WITHOUT_MODALITY
|
||||
else -> Renderers.DEFAULT
|
||||
}
|
||||
return renderer.render(descriptor)
|
||||
}
|
||||
|
||||
private fun render(descriptor: PropertyAccessorDescriptor) = buildString {
|
||||
descriptor.annotations.forEach {
|
||||
append(Renderers.DEFAULT.renderAnnotation(it)).append(" ")
|
||||
}
|
||||
if (descriptor.visibility != DescriptorVisibilities.DEFAULT_VISIBILITY) {
|
||||
append(descriptor.visibility.internalDisplayName).append(" ")
|
||||
}
|
||||
when (descriptor) {
|
||||
is PropertyGetterDescriptor -> append("get")
|
||||
is PropertySetterDescriptor -> append("set")
|
||||
else -> throw AssertionError("Unknown accessor descriptor type: $descriptor")
|
||||
}
|
||||
}
|
||||
|
||||
private object Renderers {
|
||||
val DEFAULT = DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.withOptions {
|
||||
modifiers = DescriptorRendererModifier.ALL
|
||||
overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OVERRIDE
|
||||
annotationArgumentsRenderingPolicy = AnnotationArgumentsRenderingPolicy.UNLESS_EMPTY
|
||||
excludedAnnotationClasses += StandardNames.FqNames.suppress
|
||||
|
||||
classWithPrimaryConstructor = true
|
||||
renderConstructorKeyword = true
|
||||
includePropertyConstant = true
|
||||
|
||||
unitReturnType = false
|
||||
withDefinedIn = false
|
||||
renderDefaultVisibility = false
|
||||
secondaryConstructorsAsPrimary = false
|
||||
}
|
||||
|
||||
val WITHOUT_MODALITY = DEFAULT.withOptions {
|
||||
modifiers -= DescriptorRendererModifier.MODALITY
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.jetbrains.kotlin.cli.klib
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer
|
||||
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
|
||||
|
||||
class DefaultIdSignatureRenderer(private val prefix: String? = null) : IdSignatureRenderer {
|
||||
private val idSignaturer = KonanIdSignaturer(KonanManglerDesc)
|
||||
|
||||
override fun render(descriptor: DeclarationDescriptor): String? {
|
||||
val idSignature = if (descriptor is ClassDescriptor && descriptor.kind == ClassKind.ENUM_ENTRY) {
|
||||
idSignaturer.composeEnumEntrySignature(descriptor)
|
||||
} else {
|
||||
idSignaturer.composeSignature(descriptor)
|
||||
} ?: return null
|
||||
|
||||
return if (prefix != null)
|
||||
prefix + idSignature.render()
|
||||
else
|
||||
idSignature.render()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.jetbrains.kotlin.cli.klib
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
|
||||
interface IdSignatureRenderer {
|
||||
fun render(descriptor: DeclarationDescriptor): String?
|
||||
|
||||
companion object {
|
||||
val NO_SIGNATURE = object : IdSignatureRenderer {
|
||||
override fun render(descriptor: DeclarationDescriptor): String? = null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.klib
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
|
||||
import org.jetbrains.kotlin.renderer.*
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class KlibPrinter(out: Appendable) {
|
||||
|
||||
val printer = Printer(out, 1, " ")
|
||||
|
||||
val DeclarationDescriptorWithVisibility.isPublicOrProtected: Boolean
|
||||
get() = visibility == DescriptorVisibilities.PUBLIC || visibility == DescriptorVisibilities.PROTECTED
|
||||
|
||||
val CallableMemberDescriptor.isFakeOverride: Boolean
|
||||
get() = kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||
|
||||
val DeclarationDescriptor.shouldBePrinted: Boolean
|
||||
get() = this is ClassifierDescriptorWithTypeParameters && isPublicOrProtected
|
||||
|| this is CallableMemberDescriptor && isPublicOrProtected && !isFakeOverride
|
||||
|
||||
private fun Printer.printBody(header: CharSequence, block: () -> Unit) {
|
||||
println()
|
||||
println("$header {")
|
||||
pushIndent()
|
||||
block()
|
||||
popIndent()
|
||||
println("}")
|
||||
println()
|
||||
}
|
||||
|
||||
private fun ClassifierDescriptorWithTypeParameters.render(): String {
|
||||
val renderer = when (modality) {
|
||||
// Don't render 'final' modality
|
||||
Modality.FINAL -> Renderers.WITHOUT_MODALITY
|
||||
else -> Renderers.DEFAULT
|
||||
}
|
||||
return renderer.render(this)
|
||||
}
|
||||
|
||||
private fun CallableMemberDescriptor.render(): String {
|
||||
val containingDeclaration = containingDeclaration
|
||||
val renderer = when {
|
||||
// Don't render modality for non-override final methods and interface methods.
|
||||
containingDeclaration is ClassDescriptor && containingDeclaration.kind == ClassKind.INTERFACE ||
|
||||
modality == Modality.FINAL && overriddenDescriptors.isEmpty() ->
|
||||
Renderers.WITHOUT_MODALITY
|
||||
else -> Renderers.DEFAULT
|
||||
}
|
||||
return renderer.render(this)
|
||||
}
|
||||
|
||||
private fun PropertyAccessorDescriptor.render() = buildString {
|
||||
annotations.forEach {
|
||||
append(Renderers.DEFAULT.renderAnnotation(it)).append(" ")
|
||||
}
|
||||
if (visibility != DescriptorVisibilities.DEFAULT_VISIBILITY) {
|
||||
append(visibility.internalDisplayName).append(" ")
|
||||
}
|
||||
when (this@render) {
|
||||
is PropertyGetterDescriptor -> append("get")
|
||||
is PropertySetterDescriptor -> append("set")
|
||||
else -> throw AssertionError("Unknown accessor descriptor type: ${this@render}")
|
||||
}
|
||||
}
|
||||
|
||||
fun print(module: ModuleDescriptor) {
|
||||
module.accept(PrinterVisitor(), Unit)
|
||||
}
|
||||
|
||||
private inner class PrinterVisitor : DeclarationDescriptorVisitorEmptyBodies<Unit, Unit>() {
|
||||
override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Unit) {
|
||||
descriptor.getPackageFragments().forEach {
|
||||
it.accept(this, data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: Unit) {
|
||||
val children = descriptor.getMemberScope().getContributedDescriptors().filter { it.shouldBePrinted }
|
||||
if (children.isNotEmpty()) {
|
||||
val packageName = descriptor.fqName.let { if (it.isRoot) "<root>" else it.asString() }
|
||||
val header = "package $packageName"
|
||||
printer.printBody(header) {
|
||||
children.forEach { it.accept(this, data) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Unit) {
|
||||
val children = descriptor.unsubstitutedMemberScope.getContributedDescriptors().filter { it.shouldBePrinted }
|
||||
val constructors = descriptor.constructors.filter { !it.isPrimary && it.shouldBePrinted }
|
||||
val header = descriptor.render()
|
||||
if (children.isNotEmpty() || constructors.isNotEmpty()) {
|
||||
printer.printBody(header) {
|
||||
constructors.forEach { it.accept(this, data) }
|
||||
children.forEach { it.accept(this, data) }
|
||||
}
|
||||
} else {
|
||||
printer.println(header)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit) {
|
||||
printer.println(descriptor.render())
|
||||
}
|
||||
|
||||
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit) {
|
||||
printer.println(descriptor.render())
|
||||
descriptor.getter?.let { getter ->
|
||||
if (!getter.annotations.isEmpty()) {
|
||||
printer.pushIndent()
|
||||
printer.println(getter.render())
|
||||
printer.popIndent()
|
||||
}
|
||||
}
|
||||
descriptor.setter?.let { setter ->
|
||||
if (!setter.annotations.isEmpty() || setter.visibility != descriptor.visibility) {
|
||||
printer.pushIndent()
|
||||
printer.println(setter.render())
|
||||
printer.popIndent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit) {
|
||||
printer.println(descriptor.render())
|
||||
}
|
||||
|
||||
override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: Unit) {
|
||||
printer.println(descriptor.render())
|
||||
}
|
||||
}
|
||||
|
||||
object Renderers {
|
||||
val DEFAULT = DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.withOptions {
|
||||
modifiers = DescriptorRendererModifier.ALL
|
||||
overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OVERRIDE
|
||||
annotationArgumentsRenderingPolicy = AnnotationArgumentsRenderingPolicy.UNLESS_EMPTY
|
||||
excludedAnnotationClasses += setOf(StandardNames.FqNames.suppress)
|
||||
|
||||
classWithPrimaryConstructor = true
|
||||
renderConstructorKeyword = true
|
||||
includePropertyConstant = true
|
||||
|
||||
unitReturnType = false
|
||||
withDefinedIn = false
|
||||
renderDefaultVisibility = false
|
||||
secondaryConstructorsAsPrimary = false
|
||||
}
|
||||
val WITHOUT_MODALITY = DEFAULT.withOptions {
|
||||
modifiers -= DescriptorRendererModifier.MODALITY
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package org.jetbrains.kotlin.cli.klib
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.getPackageFragments
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class SignaturePrinter(
|
||||
out: Appendable,
|
||||
private val signatureRenderer: IdSignatureRenderer
|
||||
) {
|
||||
private val printer = Printer(out)
|
||||
|
||||
fun print(module: ModuleDescriptor) {
|
||||
module.accept(PrinterVisitor(), Unit)
|
||||
}
|
||||
|
||||
private fun Printer.printlnIfNotNull(line: String?) {
|
||||
if (line != null) println(line)
|
||||
}
|
||||
|
||||
private inner class PrinterVisitor : DeclarationDescriptorVisitorEmptyBodies<Unit, Unit>() {
|
||||
override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: Unit) {
|
||||
descriptor.getPackageFragments().forEach { it.accept(this, data) }
|
||||
}
|
||||
|
||||
override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: Unit) {
|
||||
descriptor.getMemberScope().getContributedDescriptors().forEach { it.accept(this, data) }
|
||||
}
|
||||
|
||||
override fun visitClassDescriptor(descriptor: ClassDescriptor, data: Unit) {
|
||||
printer.printlnIfNotNull(signatureRenderer.render(descriptor))
|
||||
descriptor.constructors.forEach { it.accept(this, data) }
|
||||
descriptor.unsubstitutedMemberScope.getContributedDescriptors().forEach { it.accept(this, data) }
|
||||
}
|
||||
|
||||
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit) {
|
||||
printer.printlnIfNotNull(signatureRenderer.render(descriptor))
|
||||
}
|
||||
|
||||
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit) {
|
||||
printer.printlnIfNotNull(signatureRenderer.render(descriptor))
|
||||
descriptor.getter?.let { printer.printlnIfNotNull(signatureRenderer.render(it)) }
|
||||
descriptor.setter?.let { printer.printlnIfNotNull(signatureRenderer.render(it)) }
|
||||
}
|
||||
|
||||
override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit) {
|
||||
printer.printlnIfNotNull(signatureRenderer.render(descriptor))
|
||||
}
|
||||
|
||||
override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: Unit) {
|
||||
printer.printlnIfNotNull(signatureRenderer.render(descriptor))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer
|
||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer
|
||||
import org.jetbrains.kotlin.util.Logger
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||
@@ -28,7 +29,6 @@ import org.jetbrains.kotlin.konan.library.resolverByName
|
||||
import org.jetbrains.kotlin.konan.util.KonanHomeProvider
|
||||
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import java.lang.System.out
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
internal val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer, PlatformDependentTypeTransformer.None)
|
||||
@@ -39,15 +39,17 @@ fun printUsage() {
|
||||
println("\tinfo\tgeneral information about the library")
|
||||
println("\tinstall\tinstall the library to the local repository")
|
||||
println("\tcontents\tlist contents of the library")
|
||||
println("\tsignatures\tlist of ID signatures in the library")
|
||||
println("\tremove\tremove the library from the local repository")
|
||||
println("and the options are:")
|
||||
println("\t-repository <path>\twork with the specified repository")
|
||||
println("\t-target <name>\tinspect specifics of the given target")
|
||||
println("\t-print-signatures [true|false]\tprint ID signature for every declaration (only for \"contents\" command)")
|
||||
}
|
||||
|
||||
private fun parseArgs(args: Array<String>): Map<String, List<String>> {
|
||||
val commandLine = mutableMapOf<String, MutableList<String>>()
|
||||
for (index in 0..args.size - 1 step 2) {
|
||||
for (index in args.indices step 2) {
|
||||
val key = args[index]
|
||||
if (key[0] != '-') {
|
||||
throw IllegalArgumentException("Expected a flag with initial dash: $key")
|
||||
@@ -62,13 +64,14 @@ private fun parseArgs(args: Array<String>): Map<String, List<String>> {
|
||||
}
|
||||
|
||||
|
||||
class Command(args: Array<String>){
|
||||
class Command(args: Array<String>) {
|
||||
init {
|
||||
if (args.size < 2) {
|
||||
printUsage()
|
||||
exitProcess(0)
|
||||
}
|
||||
}
|
||||
|
||||
val verb = args[0]
|
||||
val library = args[1]
|
||||
val options = parseArgs(args.drop(2).toTypedArray())
|
||||
@@ -160,8 +163,22 @@ class Library(val name: String, val requestedRepository: String?, val target: St
|
||||
library?.libraryFile?.deleteRecursively()
|
||||
}
|
||||
|
||||
fun contents(output: Appendable = out) {
|
||||
fun contents(output: Appendable, printSignatures: Boolean) {
|
||||
val module = loadModule()
|
||||
val signatureRenderer = if (printSignatures) DefaultIdSignatureRenderer("// ID signature: ") else IdSignatureRenderer.NO_SIGNATURE
|
||||
val printer = DeclarationPrinter(output, DefaultDeclarationHeaderRenderer, signatureRenderer)
|
||||
|
||||
printer.print(module)
|
||||
}
|
||||
|
||||
fun signatures(output: Appendable) {
|
||||
val module = loadModule()
|
||||
val printer = SignaturePrinter(output, DefaultIdSignatureRenderer())
|
||||
|
||||
printer.print(module)
|
||||
}
|
||||
|
||||
private fun loadModule(): ModuleDescriptor {
|
||||
val storageManager = LockBasedStorageManager("klib")
|
||||
val library = libraryInRepoOrCurrentDir(repository, name)
|
||||
val versionSpec = LanguageVersionSettingsImpl(currentLanguageVersion, currentApiVersion)
|
||||
@@ -173,19 +190,18 @@ class Library(val name: String, val requestedRepository: String?, val target: St
|
||||
emptyList(),
|
||||
distributionKlib = Distribution(KonanHomeProvider.determineKonanHome()).klib,
|
||||
skipCurrentDir = true,
|
||||
logger = KlibToolLogger)
|
||||
resolver.defaultLinks(false, true, true)
|
||||
.mapTo(defaultModules) {
|
||||
KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptor(
|
||||
it, versionSpec, storageManager, module.builtIns, null)
|
||||
}
|
||||
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) }
|
||||
}
|
||||
|
||||
KlibPrinter(output).print(module)
|
||||
return module
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,15 +224,17 @@ fun main(args: Array<String>) {
|
||||
val target = targetManager.targetName
|
||||
|
||||
val repository = command.options["-repository"]?.last()
|
||||
val printSignatures = command.options["-print-signatures"]?.last()?.toBoolean() == true
|
||||
|
||||
val library = Library(command.library, repository, target)
|
||||
|
||||
when (command.verb) {
|
||||
"contents" -> library.contents()
|
||||
"info" -> library.info()
|
||||
"install" -> library.install()
|
||||
"remove" -> library.remove()
|
||||
else -> error("Unknown command ${command.verb}.")
|
||||
"contents" -> library.contents(System.out, printSignatures)
|
||||
"signatures" -> library.signatures(System.out)
|
||||
"info" -> library.info()
|
||||
"install" -> library.install()
|
||||
"remove" -> library.remove()
|
||||
else -> error("Unknown command ${command.verb}.")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ class ContentsTest {
|
||||
private fun klibContents(library: String, printOutput: Boolean = false, expected: () -> String) {
|
||||
val output = StringBuilder()
|
||||
val lib = Library(library, null, "host")
|
||||
lib.contents(output)
|
||||
lib.contents(output, false)
|
||||
if (printOutput) {
|
||||
println(output.trim().toString())
|
||||
}
|
||||
@@ -34,7 +34,7 @@ class ContentsTest {
|
||||
fun `Stdlib content should be printed without exceptions`() {
|
||||
val output = StringBuilder()
|
||||
val distributionPath = System.getProperty("konan.home")
|
||||
Library(Distribution(distributionPath).stdlib, null, "host").contents(output)
|
||||
Library(Distribution(distributionPath).stdlib, null, "host").contents(output, false)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user