[kotlinx-metadata] Add extensions for KmValueParameter

There is no extension on jvm, but klibs have parameter annotations.
This commit is contained in:
Sergey Bogolepov
2019-11-27 17:33:09 +07:00
parent 18bb615dd9
commit a08cf59017
14 changed files with 152 additions and 3 deletions
@@ -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]
@@ -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()
}
}
@@ -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)
}
}
@@ -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<KmAnnotation> = 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<KmAnnotation> = mutableListOf()
override fun visitAnnotation(annotation: KmAnnotation) {
annotations += annotation
}
override fun accept(visitor: KmValueParameterExtensionVisitor) {
require(visitor is KlibValueParameterExtensionVisitor)
annotations.forEach(visitor::visitAnnotation)
}
}
@@ -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()
}
@@ -108,4 +108,7 @@ var KmTypeAlias.uniqId: UniqId?
get() = klibExtensions.uniqId
set(value) {
klibExtensions.uniqId = value
}
}
val KmValueParameter.annotations: MutableList<KmAnnotation>
get() = klibExtensions.annotations
@@ -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)
}
}
@@ -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
@@ -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<MetadataExtensions> by lazy {
ServiceLoader.load(MetadataExtensions::class.java, MetadataExtensions::class.java.classLoader).toList().also {
@@ -27,4 +27,6 @@ interface KmTypeParameterExtension : KmTypeParameterExtensionVisitor, KmExtensio
interface KmTypeExtension : KmTypeExtensionVisitor, KmExtension<KmTypeExtensionVisitor>
interface KmTypeAliasExtension : KmTypeAliasExtensionVisitor, KmExtension<KmTypeExtensionVisitor>
interface KmTypeAliasExtension : KmTypeAliasExtensionVisitor, KmExtension<KmTypeAliasExtensionVisitor>
interface KmValueParameterExtension : KmValueParameterExtensionVisitor, KmExtension<KmValueParameterExtensionVisitor>
@@ -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()
}
@@ -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
@@ -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<KmValueParameterExtension> =
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()
}
}
@@ -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.
*/