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 if (propertySignature != null && propertySignature.hasSyntheticMethod()) propertySignature.syntheticMethod else null
ext.visitSyntheticMethodForAnnotations(syntheticMethod?.run { JvmMethodSignature(c[name], c[desc]) }) 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() ext.visitEnd()
} }
@@ -180,8 +184,11 @@ internal class JvmMetadataExtensions : MetadataExtensions {
): KmPropertyExtensionVisitor? { ): KmPropertyExtensionVisitor? {
if (type != JvmPropertyExtensionVisitor.TYPE) return null if (type != JvmPropertyExtensionVisitor.TYPE) return null
return object : JvmPropertyExtensionVisitor() { return object : JvmPropertyExtensionVisitor() {
var jvmFlags: Flags = ProtoBuf.Property.getDefaultInstance().getExtension(JvmProtoBuf.flags) private var jvmFlags: Flags = ProtoBuf.Property.getDefaultInstance().getExtension(JvmProtoBuf.flags)
var signature: JvmProtoBuf.JvmPropertySignature.Builder? = null private var signatureOrNull: JvmProtoBuf.JvmPropertySignature.Builder? = null
private val signature: JvmProtoBuf.JvmPropertySignature.Builder
get() = signatureOrNull ?: JvmProtoBuf.JvmPropertySignature.newBuilder().also { signatureOrNull = it }
override fun visit( override fun visit(
jvmFlags: Flags, jvmFlags: Flags,
@@ -190,44 +197,38 @@ internal class JvmMetadataExtensions : MetadataExtensions {
setterSignature: JvmMethodSignature? setterSignature: JvmMethodSignature?
) { ) {
this.jvmFlags = jvmFlags this.jvmFlags = jvmFlags
if (fieldSignature != null) {
if (fieldSignature == null && getterSignature == null && setterSignature == null) return signature.field = JvmProtoBuf.JvmFieldSignature.newBuilder().also { field ->
field.name = c[fieldSignature.name]
if (signature == null) { field.desc = c[fieldSignature.desc]
signature = JvmProtoBuf.JvmPropertySignature.newBuilder() }.build()
} }
signature!!.apply { if (getterSignature != null) {
if (fieldSignature != null) { signature.getter = getterSignature.toJvmMethodSignature(c)
field = JvmProtoBuf.JvmFieldSignature.newBuilder().also { field -> }
field.name = c[fieldSignature.name] if (setterSignature != null) {
field.desc = c[fieldSignature.desc] signature.setter = setterSignature.toJvmMethodSignature(c)
}.build()
}
if (getterSignature != null) {
getter = getterSignature.toJvmMethodSignature(c)
}
if (setterSignature != null) {
setter = setterSignature.toJvmMethodSignature(c)
}
} }
} }
override fun visitSyntheticMethodForAnnotations(signature: JvmMethodSignature?) { override fun visitSyntheticMethodForAnnotations(signature: JvmMethodSignature?) {
if (signature == null) return if (signature == null) return
if (this.signature == null) { this.signature.syntheticMethod = signature.toJvmMethodSignature(c)
this.signature = JvmProtoBuf.JvmPropertySignature.newBuilder() }
}
this.signature!!.syntheticMethod = signature.toJvmMethodSignature(c) override fun visitSyntheticMethodForDelegate(signature: JvmMethodSignature?) {
if (signature == null) return
this.signature.delegateMethod = signature.toJvmMethodSignature(c)
} }
override fun visitEnd() { override fun visitEnd() {
if (jvmFlags != ProtoBuf.Property.getDefaultInstance().getExtension(JvmProtoBuf.flags)) { if (jvmFlags != ProtoBuf.Property.getDefaultInstance().getExtension(JvmProtoBuf.flags)) {
proto.setExtension(JvmProtoBuf.flags, jvmFlags) proto.setExtension(JvmProtoBuf.flags, jvmFlags)
} }
if (signature != null) { if (signatureOrNull != null) {
proto.setExtension(JvmProtoBuf.propertySignature, signature!!.build()) proto.setExtension(JvmProtoBuf.propertySignature, signature.build())
} }
} }
} }
@@ -105,6 +105,7 @@ internal class JvmPropertyExtension : JvmPropertyExtensionVisitor(), KmPropertyE
var getterSignature: JvmMethodSignature? = null var getterSignature: JvmMethodSignature? = null
var setterSignature: JvmMethodSignature? = null var setterSignature: JvmMethodSignature? = null
var syntheticMethodForAnnotations: JvmMethodSignature? = null var syntheticMethodForAnnotations: JvmMethodSignature? = null
var syntheticMethodForDelegate: JvmMethodSignature? = null
override fun visit( override fun visit(
jvmFlags: Flags, jvmFlags: Flags,
@@ -122,10 +123,15 @@ internal class JvmPropertyExtension : JvmPropertyExtensionVisitor(), KmPropertyE
this.syntheticMethodForAnnotations = signature this.syntheticMethodForAnnotations = signature
} }
override fun visitSyntheticMethodForDelegate(signature: JvmMethodSignature?) {
this.syntheticMethodForDelegate = signature
}
override fun accept(visitor: KmPropertyExtensionVisitor) { override fun accept(visitor: KmPropertyExtensionVisitor) {
require(visitor is JvmPropertyExtensionVisitor) require(visitor is JvmPropertyExtensionVisitor)
visitor.visit(jvmFlags, fieldSignature, getterSignature, setterSignature) visitor.visit(jvmFlags, fieldSignature, getterSignature, setterSignature)
visitor.visitSyntheticMethodForAnnotations(syntheticMethodForAnnotations) visitor.visitSyntheticMethodForAnnotations(syntheticMethodForAnnotations)
visitor.visitSyntheticMethodForDelegate(syntheticMethodForDelegate)
visitor.visitEnd() visitor.visitEnd()
} }
} }
@@ -212,6 +212,19 @@ open class JvmPropertyExtensionVisitor @JvmOverloads constructor(
delegate?.visitSyntheticMethodForAnnotations(signature) 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. * Visits the end of JVM extensions for the property.
*/ */
@@ -103,6 +103,7 @@ private fun visitProperty(
var jvmGetterSignature: JvmMemberSignature? = null var jvmGetterSignature: JvmMemberSignature? = null
var jvmSetterSignature: JvmMemberSignature? = null var jvmSetterSignature: JvmMemberSignature? = null
var jvmSyntheticMethodForAnnotationsSignature: JvmMemberSignature? = null var jvmSyntheticMethodForAnnotationsSignature: JvmMemberSignature? = null
var jvmSyntheticMethodForDelegateSignature: JvmMemberSignature? = null
var isMovedFromInterfaceCompanion: Boolean = false var isMovedFromInterfaceCompanion: Boolean = false
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? = override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
@@ -138,6 +139,10 @@ private fun visitProperty(
override fun visitSyntheticMethodForAnnotations(signature: JvmMethodSignature?) { override fun visitSyntheticMethodForAnnotations(signature: JvmMethodSignature?) {
jvmSyntheticMethodForAnnotationsSignature = signature jvmSyntheticMethodForAnnotationsSignature = signature
} }
override fun visitSyntheticMethodForDelegate(signature: JvmMethodSignature?) {
jvmSyntheticMethodForDelegateSignature = signature
}
} }
} }
@@ -158,6 +163,9 @@ private fun visitProperty(
if (jvmSyntheticMethodForAnnotationsSignature != null) { if (jvmSyntheticMethodForAnnotationsSignature != null) {
sb.appendLine(" // synthetic method for annotations: $jvmSyntheticMethodForAnnotationsSignature") sb.appendLine(" // synthetic method for annotations: $jvmSyntheticMethodForAnnotationsSignature")
} }
if (jvmSyntheticMethodForDelegateSignature != null) {
sb.appendLine(" // synthetic method for delegate: $jvmSyntheticMethodForDelegateSignature")
}
if (isMovedFromInterfaceCompanion) { if (isMovedFromInterfaceCompanion) {
sb.appendLine(" // is moved from interface companion") sb.appendLine(" // is moved from interface companion")
} }