[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.backend.common.serialization.metadata.DynamicTypeDeserializer
|
||||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer
|
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer
|
||||||
import org.jetbrains.kotlin.util.Logger
|
import org.jetbrains.kotlin.util.Logger
|
||||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
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.konan.util.KonanHomeProvider
|
||||||
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
|
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
|
||||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
import java.lang.System.out
|
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
internal val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer, PlatformDependentTypeTransformer.None)
|
internal val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer, PlatformDependentTypeTransformer.None)
|
||||||
@@ -39,15 +39,17 @@ fun printUsage() {
|
|||||||
println("\tinfo\tgeneral information about the library")
|
println("\tinfo\tgeneral information about the library")
|
||||||
println("\tinstall\tinstall the library to the local repository")
|
println("\tinstall\tinstall the library to the local repository")
|
||||||
println("\tcontents\tlist contents of the library")
|
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("\tremove\tremove the library from the local repository")
|
||||||
println("and the options are:")
|
println("and the options are:")
|
||||||
println("\t-repository <path>\twork with the specified repository")
|
println("\t-repository <path>\twork with the specified repository")
|
||||||
println("\t-target <name>\tinspect specifics of the given target")
|
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>> {
|
private fun parseArgs(args: Array<String>): Map<String, List<String>> {
|
||||||
val commandLine = mutableMapOf<String, MutableList<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]
|
val key = args[index]
|
||||||
if (key[0] != '-') {
|
if (key[0] != '-') {
|
||||||
throw IllegalArgumentException("Expected a flag with initial dash: $key")
|
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 {
|
init {
|
||||||
if (args.size < 2) {
|
if (args.size < 2) {
|
||||||
printUsage()
|
printUsage()
|
||||||
exitProcess(0)
|
exitProcess(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val verb = args[0]
|
val verb = args[0]
|
||||||
val library = args[1]
|
val library = args[1]
|
||||||
val options = parseArgs(args.drop(2).toTypedArray())
|
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()
|
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 storageManager = LockBasedStorageManager("klib")
|
||||||
val library = libraryInRepoOrCurrentDir(repository, name)
|
val library = libraryInRepoOrCurrentDir(repository, name)
|
||||||
val versionSpec = LanguageVersionSettingsImpl(currentLanguageVersion, currentApiVersion)
|
val versionSpec = LanguageVersionSettingsImpl(currentLanguageVersion, currentApiVersion)
|
||||||
@@ -173,19 +190,18 @@ class Library(val name: String, val requestedRepository: String?, val target: St
|
|||||||
emptyList(),
|
emptyList(),
|
||||||
distributionKlib = Distribution(KonanHomeProvider.determineKonanHome()).klib,
|
distributionKlib = Distribution(KonanHomeProvider.determineKonanHome()).klib,
|
||||||
skipCurrentDir = true,
|
skipCurrentDir = true,
|
||||||
logger = KlibToolLogger)
|
logger = KlibToolLogger
|
||||||
resolver.defaultLinks(false, true, true)
|
)
|
||||||
.mapTo(defaultModules) {
|
resolver.defaultLinks(false, true, true).mapTo(defaultModules) {
|
||||||
KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptor(
|
KlibFactories.DefaultDeserializedDescriptorFactory.createDescriptor(it, versionSpec, storageManager, module.builtIns, null)
|
||||||
it, versionSpec, storageManager, module.builtIns, null)
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(defaultModules + module).let { allModules ->
|
(defaultModules + module).let { allModules ->
|
||||||
allModules.forEach { it.setDependencies(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 target = targetManager.targetName
|
||||||
|
|
||||||
val repository = command.options["-repository"]?.last()
|
val repository = command.options["-repository"]?.last()
|
||||||
|
val printSignatures = command.options["-print-signatures"]?.last()?.toBoolean() == true
|
||||||
|
|
||||||
val library = Library(command.library, repository, target)
|
val library = Library(command.library, repository, target)
|
||||||
|
|
||||||
when (command.verb) {
|
when (command.verb) {
|
||||||
"contents" -> library.contents()
|
"contents" -> library.contents(System.out, printSignatures)
|
||||||
"info" -> library.info()
|
"signatures" -> library.signatures(System.out)
|
||||||
"install" -> library.install()
|
"info" -> library.info()
|
||||||
"remove" -> library.remove()
|
"install" -> library.install()
|
||||||
else -> error("Unknown command ${command.verb}.")
|
"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) {
|
private fun klibContents(library: String, printOutput: Boolean = false, expected: () -> String) {
|
||||||
val output = StringBuilder()
|
val output = StringBuilder()
|
||||||
val lib = Library(library, null, "host")
|
val lib = Library(library, null, "host")
|
||||||
lib.contents(output)
|
lib.contents(output, false)
|
||||||
if (printOutput) {
|
if (printOutput) {
|
||||||
println(output.trim().toString())
|
println(output.trim().toString())
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ class ContentsTest {
|
|||||||
fun `Stdlib content should be printed without exceptions`() {
|
fun `Stdlib content should be printed without exceptions`() {
|
||||||
val output = StringBuilder()
|
val output = StringBuilder()
|
||||||
val distributionPath = System.getProperty("konan.home")
|
val distributionPath = System.getProperty("konan.home")
|
||||||
Library(Distribution(distributionPath).stdlib, null, "host").contents(output)
|
Library(Distribution(distributionPath).stdlib, null, "host").contents(output, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user