From 1e7295c64e9248419df40e3866df3ea06df13ee2 Mon Sep 17 00:00:00 2001 From: pyos Date: Wed, 30 Jun 2021 19:35:20 +0200 Subject: [PATCH] JVM: add `$delegate` method support to kotlinx-metadata and kotlinp as well -- it is now possible to see the effect of the previous commit. --- .../jvm/impl/JvmMetadataExtensions.kt | 53 ++++++++++--------- .../metadata/jvm/impl/jvmExtensionNodes.kt | 6 +++ .../metadata/jvm/jvmExtensionVisitors.kt | 13 +++++ .../org/jetbrains/kotlin/kotlinp/printers.kt | 8 +++ 4 files changed, 54 insertions(+), 26 deletions(-) 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 85fcf73d734..1875c862660 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 @@ -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()) } } } 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 8d56fa80e53..067af5e1e04 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 @@ -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() } } 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 3bbce8ce2a1..b13d851384f 100644 --- a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/jvmExtensionVisitors.kt +++ b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/jvmExtensionVisitors.kt @@ -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. */ diff --git a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt index 3b47a580c46..1819491cd16 100644 --- a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt +++ b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt @@ -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") }