diff --git a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/JvmMetadataExtensions.kt b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/JvmMetadataExtensions.kt index 16d492e0daa..85fcf73d734 100644 --- a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/JvmMetadataExtensions.kt +++ b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/JvmMetadataExtensions.kt @@ -109,6 +109,8 @@ internal class JvmMetadataExtensions : MetadataExtensions { override fun readTypeAliasExtensions(v: KmTypeAliasVisitor, proto: ProtoBuf.TypeAlias, c: ReadContext) {} + override fun readValueParameterExtensions(v: KmValueParameterVisitor, proto: ProtoBuf.ValueParameter, c: ReadContext) {} + override fun writeClassExtensions(type: KmExtensionType, proto: ProtoBuf.Class.Builder, c: WriteContext): KmClassExtensionVisitor? { if (type != JvmClassExtensionVisitor.TYPE) return null return object : JvmClassExtensionVisitor() { @@ -276,6 +278,12 @@ internal class JvmMetadataExtensions : MetadataExtensions { c: WriteContext ): KmTypeAliasExtensionVisitor? = null + override fun writeValueParameterExtensions( + type: KmExtensionType, + proto: ProtoBuf.ValueParameter.Builder, + c: WriteContext + ): KmValueParameterExtensionVisitor? = null + override fun createClassExtension(): KmClassExtension = JvmClassExtension() override fun createPackageExtension(): KmPackageExtension = JvmPackageExtension() @@ -295,6 +303,8 @@ internal class JvmMetadataExtensions : MetadataExtensions { override fun createTypeAliasExtension(): KmTypeAliasExtension = JvmTypeAliasExtension() + override fun createValueParameterExtension(): KmValueParameterExtension = JvmValueParameterExtension() + private fun JvmMemberSignature.toJvmMethodSignature(c: WriteContext): JvmProtoBuf.JvmMethodSignature = JvmProtoBuf.JvmMethodSignature.newBuilder().apply { name = c[this@toJvmMethodSignature.name] diff --git a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/jvmExtensionNodes.kt b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/jvmExtensionNodes.kt index 3d2bd6f467f..b69e6e0bee9 100644 --- a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/jvmExtensionNodes.kt +++ b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/impl/jvmExtensionNodes.kt @@ -183,3 +183,10 @@ internal class JvmTypeAliasExtension : JvmTypeAliasExtensionVisitor(), KmTypeAli visitor.visitEnd() } } + +internal class JvmValueParameterExtension : JvmValueParameterExtensionVisitor(), KmValueParameterExtension { + override fun accept(visitor: KmValueParameterExtensionVisitor) { + require(visitor is JvmValueParameterExtensionVisitor) + visitor.visitEnd() + } +} diff --git a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/jvmExtensionVisitors.kt b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/jvmExtensionVisitors.kt index 11b7c4a63f3..3bbce8ce2a1 100644 --- a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/jvmExtensionVisitors.kt +++ b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/jvmExtensionVisitors.kt @@ -375,3 +375,30 @@ open class JvmTypeAliasExtensionVisitor @JvmOverloads constructor( val TYPE: KmExtensionType = KmExtensionType(JvmTypeAliasExtensionVisitor::class) } } + +/** + * A visitor to visit JVM extensions for a value parameter. + */ +open class JvmValueParameterExtensionVisitor @JvmOverloads constructor( + private val delegate: JvmValueParameterExtensionVisitor? = null +) : KmTypeAliasExtensionVisitor { + final override val type: KmExtensionType + get() = TYPE + + /** + * Visits the end of JVM extensions for the value parameter. + */ + open fun visitEnd() { + delegate?.visitEnd() + } + + companion object { + /** + * The type of this extension visitor. + * + * @see KmExtensionType + */ + @JvmField + val TYPE: KmExtensionType = KmExtensionType(JvmValueParameterExtensionVisitor::class) + } +} diff --git a/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/impl/klibExtensionNodes.kt b/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/impl/klibExtensionNodes.kt index c6546c95aef..d895fa0c62f 100644 --- a/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/impl/klibExtensionNodes.kt +++ b/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/impl/klibExtensionNodes.kt @@ -36,6 +36,9 @@ internal val KmModuleFragment.klibExtensions: KlibModuleFragmentExtension internal val KmTypeAlias.klibExtensions: KlibTypeAliasExtension get() = visitExtensions(KlibTypeAliasExtensionVisitor.TYPE) as KlibTypeAliasExtension +internal val KmValueParameter.klibExtensions: KlibValueParameterExtension + get() = visitExtensions(KlibValueParameterExtensionVisitor.TYPE) as KlibValueParameterExtension + internal class KlibFunctionExtension : KlibFunctionExtensionVisitor(), KmFunctionExtension { val annotations: MutableList = mutableListOf() @@ -233,8 +236,21 @@ internal class KlibTypeAliasExtension : KlibTypeAliasExtensionVisitor(), KmTypeA this.uniqId = uniqId } - override fun accept(visitor: KmTypeExtensionVisitor) { + override fun accept(visitor: KmTypeAliasExtensionVisitor) { require(visitor is KlibTypeAliasExtensionVisitor) uniqId?.let(visitor::visitUniqId) } +} + +internal class KlibValueParameterExtension : KlibValueParameterExtensionVisitor(), KmValueParameterExtension { + val annotations: MutableList = mutableListOf() + + override fun visitAnnotation(annotation: KmAnnotation) { + annotations += annotation + } + + override fun accept(visitor: KmValueParameterExtensionVisitor) { + require(visitor is KlibValueParameterExtensionVisitor) + annotations.forEach(visitor::visitAnnotation) + } } \ No newline at end of file diff --git a/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/impl/klibMetadataExtensions.kt b/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/impl/klibMetadataExtensions.kt index 76deea0b3a7..63703e7f2a6 100644 --- a/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/impl/klibMetadataExtensions.kt +++ b/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/impl/klibMetadataExtensions.kt @@ -134,6 +134,14 @@ internal class KlibMetadataExtensions : MetadataExtensions { } } + override fun readValueParameterExtensions(v: KmValueParameterVisitor, proto: ProtoBuf.ValueParameter, c: ReadContext) { + val extension = v.visitExtensions(KlibValueParameterExtensionVisitor.TYPE) as? KlibValueParameterExtensionVisitor ?: return + + proto.getExtension(KlibMetadataProtoBuf.parameterAnnotation).forEach { annotation -> + extension.visitAnnotation(annotation.readAnnotation(c.strings)) + } + } + override fun writeClassExtensions(type: KmExtensionType, proto: ProtoBuf.Class.Builder, c: WriteContext): KmClassExtensionVisitor? { if (type != KlibClassExtensionVisitor.TYPE) return null return object : KlibClassExtensionVisitor() { @@ -348,6 +356,22 @@ internal class KlibMetadataExtensions : MetadataExtensions { } } + override fun writeValueParameterExtensions( + type: KmExtensionType, + proto: ProtoBuf.ValueParameter.Builder, + c: WriteContext + ): KmValueParameterExtensionVisitor? { + if (type != KlibValueParameterExtensionVisitor.TYPE) return null + return object : KlibValueParameterExtensionVisitor() { + override fun visitAnnotation(annotation: KmAnnotation) { + proto.addExtension( + KlibMetadataProtoBuf.parameterAnnotation, + annotation.writeAnnotation(c.strings).build() + ) + } + } + } + override fun createClassExtension(): KmClassExtension = KlibClassExtension() @@ -374,4 +398,7 @@ internal class KlibMetadataExtensions : MetadataExtensions { override fun createTypeAliasExtension(): KmTypeAliasExtension = KlibTypeAliasExtension() + + override fun createValueParameterExtension(): KmValueParameterExtension = + KlibValueParameterExtension() } \ No newline at end of file diff --git a/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/klibExtensions.kt b/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/klibExtensions.kt index 7ec5f42c46e..a8ff49ec2ef 100644 --- a/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/klibExtensions.kt +++ b/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/klibExtensions.kt @@ -108,4 +108,7 @@ var KmTypeAlias.uniqId: UniqId? get() = klibExtensions.uniqId set(value) { klibExtensions.uniqId = value - } \ No newline at end of file + } + +val KmValueParameter.annotations: MutableList + get() = klibExtensions.annotations \ No newline at end of file diff --git a/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/klibMetadataExtensionVisitors.kt b/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/klibMetadataExtensionVisitors.kt index f7db040dffb..197b01469db 100644 --- a/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/klibMetadataExtensionVisitors.kt +++ b/libraries/kotlinx-metadata/klib/src/kotlinx/metadata/klib/klibMetadataExtensionVisitors.kt @@ -139,4 +139,16 @@ abstract class KlibTypeAliasExtensionVisitor : KmTypeAliasExtensionVisitor { companion object { val TYPE = KmExtensionType(KlibTypeAliasExtensionVisitor::class) } +} + +abstract class KlibValueParameterExtensionVisitor : KmValueParameterExtensionVisitor { + + abstract fun visitAnnotation(annotation: KmAnnotation) + + override val type: KmExtensionType + get() = TYPE + + companion object { + val TYPE = KmExtensionType(KlibValueParameterExtensionVisitor::class) + } } \ No newline at end of file diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/extensions.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/extensions.kt index 93bb31e5af1..2f7f8214ead 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/extensions.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/extensions.kt @@ -98,3 +98,8 @@ interface KmTypeExtensionVisitor : KmExtensionVisitor * A visitor to visit platform-specific extensions for a type alias. */ interface KmTypeAliasExtensionVisitor : KmExtensionVisitor + +/** + * A visitor to visit platform-specific extensions for a value parameter. + */ +interface KmValueParameterExtensionVisitor : KmExtensionVisitor diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/MetadataExtensions.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/MetadataExtensions.kt index 644f4ebcb56..92f48349a7b 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/MetadataExtensions.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/MetadataExtensions.kt @@ -30,6 +30,8 @@ interface MetadataExtensions { fun readTypeAliasExtensions(v: KmTypeAliasVisitor, proto: ProtoBuf.TypeAlias, c: ReadContext) + fun readValueParameterExtensions(v: KmValueParameterVisitor, proto: ProtoBuf.ValueParameter, c: ReadContext) + fun writeClassExtensions(type: KmExtensionType, proto: ProtoBuf.Class.Builder, c: WriteContext): KmClassExtensionVisitor? fun writePackageExtensions(type: KmExtensionType, proto: ProtoBuf.Package.Builder, c: WriteContext): KmPackageExtensionVisitor? @@ -54,6 +56,8 @@ interface MetadataExtensions { fun writeTypeAliasExtensions(type: KmExtensionType, proto: ProtoBuf.TypeAlias.Builder, c: WriteContext): KmTypeAliasExtensionVisitor? + fun writeValueParameterExtensions(type: KmExtensionType, proto: ProtoBuf.ValueParameter.Builder, c: WriteContext): KmValueParameterExtensionVisitor? + fun createClassExtension(): KmClassExtension fun createPackageExtension(): KmPackageExtension @@ -72,6 +76,8 @@ interface MetadataExtensions { fun createTypeAliasExtension(): KmTypeAliasExtension + fun createValueParameterExtension(): KmValueParameterExtension + companion object { val INSTANCES: List by lazy { ServiceLoader.load(MetadataExtensions::class.java, MetadataExtensions::class.java.classLoader).toList().also { diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/extensionNodes.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/extensionNodes.kt index ae34d2faaa9..d38c7fd726e 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/extensionNodes.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/extensions/extensionNodes.kt @@ -27,4 +27,6 @@ interface KmTypeParameterExtension : KmTypeParameterExtensionVisitor, KmExtensio interface KmTypeExtension : KmTypeExtensionVisitor, KmExtension -interface KmTypeAliasExtension : KmTypeAliasExtensionVisitor, KmExtension \ No newline at end of file +interface KmTypeAliasExtension : KmTypeAliasExtensionVisitor, KmExtension + +interface KmValueParameterExtension : KmValueParameterExtensionVisitor, KmExtension \ No newline at end of file diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/readers.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/readers.kt index 99b1f2e9c03..a9f443cdeff 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/readers.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/readers.kt @@ -282,6 +282,10 @@ private fun ProtoBuf.TypeAlias.accept(v: KmTypeAliasVisitor, outer: ReadContext) v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(versionRequirement, it, c) } } + for (extension in c.extensions) { + extension.readTypeAliasExtensions(v, this, c) + } + v.visitEnd() } @@ -294,6 +298,10 @@ private fun ProtoBuf.ValueParameter.accept(v: KmValueParameterVisitor, c: ReadCo v.visitVarargElementType(varargElementType.typeFlags)?.let { varargElementType.accept(it, c) } } + for (extension in c.extensions) { + extension.readValueParameterExtensions(v, this, c) + } + v.visitEnd() } diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/writers.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/writers.kt index 0fdded00966..52b1d7c549b 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/writers.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/impl/writers.kt @@ -233,6 +233,11 @@ private fun writeValueParameter( override fun visitVarargElementType(flags: Flags): KmTypeVisitor? = writeType(c, flags) { t.varargElementType = it.build() } + override fun visitExtensions(type: KmExtensionType): KmValueParameterExtensionVisitor? = + applySingleExtension(type) { + writeValueParameterExtensions(type, t, c) + } + override fun visitEnd() { if (flags != ProtoBuf.ValueParameter.getDefaultInstance().flags) { t.flags = flags @@ -264,6 +269,11 @@ private fun writeTypeAlias( override fun visitVersionRequirement(): KmVersionRequirementVisitor? = writeVersionRequirement(c) { t.addVersionRequirement(it) } + override fun visitExtensions(type: KmExtensionType): KmTypeAliasExtensionVisitor? = + applySingleExtension(type) { + writeTypeAliasExtensions(type, t, c) + } + override fun visitEnd() { if (flags != ProtoBuf.TypeAlias.getDefaultInstance().flags) { t.flags = flags diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/nodes.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/nodes.kt index 053b9ae6982..9ff16a0e0ac 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/nodes.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/nodes.kt @@ -549,6 +549,7 @@ class KmTypeAlias( visitor.visitExpandedType(expandedType.flags)?.let(expandedType::accept) annotations.forEach(visitor::visitAnnotation) versionRequirements.forEach { visitor.visitVersionRequirement()?.let(it::accept) } + extensions.forEach { visitor.visitExtensions(it.type)?.let(it::accept) } visitor.visitEnd() } } @@ -573,12 +574,18 @@ class KmValueParameter( */ var varargElementType: KmType? = null + private val extensions: List = + MetadataExtensions.INSTANCES.map(MetadataExtensions::createValueParameterExtension) + override fun visitType(flags: Flags): KmTypeVisitor = KmType(flags).also { type = it } override fun visitVarargElementType(flags: Flags): KmTypeVisitor = KmType(flags).also { varargElementType = it } + override fun visitExtensions(type: KmExtensionType): KmValueParameterExtensionVisitor? = + extensions.singleOfType(type) + /** * Populates the given visitor with data in this value parameter. * @@ -587,6 +594,7 @@ class KmValueParameter( fun accept(visitor: KmValueParameterVisitor) { type?.let { visitor.visitType(it.flags)?.let(it::accept) } varargElementType?.let { visitor.visitVarargElementType(it.flags)?.let(it::accept) } + extensions.forEach { visitor.visitExtensions(it.type)?.let(it::accept) } visitor.visitEnd() } } diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/visitors.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/visitors.kt index 57f43573825..97a829dd1f2 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/visitors.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/visitors.kt @@ -503,6 +503,14 @@ abstract class KmValueParameterVisitor @JvmOverloads constructor(private val del open fun visitVarargElementType(flags: Flags): KmTypeVisitor? = delegate?.visitVarargElementType(flags) + /** + * Visits the extensions of the given type on the value parameter. + * + * @param type the type of extension visitor to be returned + */ + open fun visitExtensions(type: KmExtensionType): KmValueParameterExtensionVisitor? = + delegate?.visitExtensions(type) + /** * Visits the end of the value parameter. */