JVM: add $delegate method support to kotlinx-metadata

and kotlinp as well -- it is now possible to see the effect of the
previous commit.
This commit is contained in:
pyos
2021-06-30 19:35:20 +02:00
committed by Alexander Udalov
parent 5d0102a966
commit 1e7295c64e
4 changed files with 54 additions and 26 deletions
@@ -82,6 +82,10 @@ internal class JvmMetadataExtensions : MetadataExtensions {
if (propertySignature != null && propertySignature.hasSyntheticMethod()) propertySignature.syntheticMethod else null
ext.visitSyntheticMethodForAnnotations(syntheticMethod?.run { JvmMethodSignature(c[name], c[desc]) })
val delegateMethod =
if (propertySignature != null && propertySignature.hasDelegateMethod()) propertySignature.delegateMethod else null
ext.visitSyntheticMethodForDelegate(delegateMethod?.run { JvmMethodSignature(c[name], c[desc]) })
ext.visitEnd()
}
@@ -180,8 +184,11 @@ internal class JvmMetadataExtensions : MetadataExtensions {
): KmPropertyExtensionVisitor? {
if (type != JvmPropertyExtensionVisitor.TYPE) return null
return object : JvmPropertyExtensionVisitor() {
var jvmFlags: Flags = ProtoBuf.Property.getDefaultInstance().getExtension(JvmProtoBuf.flags)
var signature: JvmProtoBuf.JvmPropertySignature.Builder? = null
private var jvmFlags: Flags = ProtoBuf.Property.getDefaultInstance().getExtension(JvmProtoBuf.flags)
private var signatureOrNull: JvmProtoBuf.JvmPropertySignature.Builder? = null
private val signature: JvmProtoBuf.JvmPropertySignature.Builder
get() = signatureOrNull ?: JvmProtoBuf.JvmPropertySignature.newBuilder().also { signatureOrNull = it }
override fun visit(
jvmFlags: Flags,
@@ -190,44 +197,38 @@ internal class JvmMetadataExtensions : MetadataExtensions {
setterSignature: JvmMethodSignature?
) {
this.jvmFlags = jvmFlags
if (fieldSignature == null && getterSignature == null && setterSignature == null) return
if (signature == null) {
signature = JvmProtoBuf.JvmPropertySignature.newBuilder()
if (fieldSignature != null) {
signature.field = JvmProtoBuf.JvmFieldSignature.newBuilder().also { field ->
field.name = c[fieldSignature.name]
field.desc = c[fieldSignature.desc]
}.build()
}
signature!!.apply {
if (fieldSignature != null) {
field = JvmProtoBuf.JvmFieldSignature.newBuilder().also { field ->
field.name = c[fieldSignature.name]
field.desc = c[fieldSignature.desc]
}.build()
}
if (getterSignature != null) {
getter = getterSignature.toJvmMethodSignature(c)
}
if (setterSignature != null) {
setter = setterSignature.toJvmMethodSignature(c)
}
if (getterSignature != null) {
signature.getter = getterSignature.toJvmMethodSignature(c)
}
if (setterSignature != null) {
signature.setter = setterSignature.toJvmMethodSignature(c)
}
}
override fun visitSyntheticMethodForAnnotations(signature: JvmMethodSignature?) {
if (signature == null) return
if (this.signature == null) {
this.signature = JvmProtoBuf.JvmPropertySignature.newBuilder()
}
this.signature.syntheticMethod = signature.toJvmMethodSignature(c)
}
this.signature!!.syntheticMethod = signature.toJvmMethodSignature(c)
override fun visitSyntheticMethodForDelegate(signature: JvmMethodSignature?) {
if (signature == null) return
this.signature.delegateMethod = signature.toJvmMethodSignature(c)
}
override fun visitEnd() {
if (jvmFlags != ProtoBuf.Property.getDefaultInstance().getExtension(JvmProtoBuf.flags)) {
proto.setExtension(JvmProtoBuf.flags, jvmFlags)
}
if (signature != null) {
proto.setExtension(JvmProtoBuf.propertySignature, signature!!.build())
if (signatureOrNull != null) {
proto.setExtension(JvmProtoBuf.propertySignature, signature.build())
}
}
}
@@ -105,6 +105,7 @@ internal class JvmPropertyExtension : JvmPropertyExtensionVisitor(), KmPropertyE
var getterSignature: JvmMethodSignature? = null
var setterSignature: JvmMethodSignature? = null
var syntheticMethodForAnnotations: JvmMethodSignature? = null
var syntheticMethodForDelegate: JvmMethodSignature? = null
override fun visit(
jvmFlags: Flags,
@@ -122,10 +123,15 @@ internal class JvmPropertyExtension : JvmPropertyExtensionVisitor(), KmPropertyE
this.syntheticMethodForAnnotations = signature
}
override fun visitSyntheticMethodForDelegate(signature: JvmMethodSignature?) {
this.syntheticMethodForDelegate = signature
}
override fun accept(visitor: KmPropertyExtensionVisitor) {
require(visitor is JvmPropertyExtensionVisitor)
visitor.visit(jvmFlags, fieldSignature, getterSignature, setterSignature)
visitor.visitSyntheticMethodForAnnotations(syntheticMethodForAnnotations)
visitor.visitSyntheticMethodForDelegate(syntheticMethodForDelegate)
visitor.visitEnd()
}
}
@@ -212,6 +212,19 @@ open class JvmPropertyExtensionVisitor @JvmOverloads constructor(
delegate?.visitSyntheticMethodForAnnotations(signature)
}
/**
* Visits the JVM signature of a synthetic method which is generated when a delegated property's delegate object is
* optimized out, e.g. because it is constant; in that case, a copy of that object can be obtained on demand by calling
* this method. It takes up to two arguments - the property's receivers.
*
* Example: `JvmMethodSignature("getX$delegate", "(LMyClass;)LMyDelegate;")`
*
* @param signature the signature of the synthetic method
*/
open fun visitSyntheticMethodForDelegate(signature: JvmMethodSignature?) {
delegate?.visitSyntheticMethodForDelegate(signature)
}
/**
* Visits the end of JVM extensions for the property.
*/
@@ -103,6 +103,7 @@ private fun visitProperty(
var jvmGetterSignature: JvmMemberSignature? = null
var jvmSetterSignature: JvmMemberSignature? = null
var jvmSyntheticMethodForAnnotationsSignature: JvmMemberSignature? = null
var jvmSyntheticMethodForDelegateSignature: JvmMemberSignature? = null
var isMovedFromInterfaceCompanion: Boolean = false
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
@@ -138,6 +139,10 @@ private fun visitProperty(
override fun visitSyntheticMethodForAnnotations(signature: JvmMethodSignature?) {
jvmSyntheticMethodForAnnotationsSignature = signature
}
override fun visitSyntheticMethodForDelegate(signature: JvmMethodSignature?) {
jvmSyntheticMethodForDelegateSignature = signature
}
}
}
@@ -158,6 +163,9 @@ private fun visitProperty(
if (jvmSyntheticMethodForAnnotationsSignature != null) {
sb.appendLine(" // synthetic method for annotations: $jvmSyntheticMethodForAnnotationsSignature")
}
if (jvmSyntheticMethodForDelegateSignature != null) {
sb.appendLine(" // synthetic method for delegate: $jvmSyntheticMethodForDelegateSignature")
}
if (isMovedFromInterfaceCompanion) {
sb.appendLine(" // is moved from interface companion")
}