Retain "is moved from interface companion" property flag in kotlinx-metadata-jvm

#KT-31338 Fixed
This commit is contained in:
Alexander Udalov
2019-05-07 12:32:33 +02:00
parent cfa3509860
commit 2a3786e3f8
11 changed files with 120 additions and 11 deletions
@@ -0,0 +1,11 @@
package test
interface I {
companion object {
@JvmField
val x = "x"
@JvmField
val y = "y"
}
}
@@ -0,0 +1,12 @@
package test
public interface I {
public companion object Companion {
/*primary*/ private constructor Companion()
@field:kotlin.jvm.JvmField public final val x: kotlin.String = "x"
public final fun <get-x>(): kotlin.String
@field:kotlin.jvm.JvmField public final val y: kotlin.String = "y"
public final fun <get-y>(): kotlin.String
}
}
@@ -4618,6 +4618,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/ConstValInMultifileClass.kt");
}
@TestMetadata("JvmFieldInInterfaceCompanion.kt")
public void testJvmFieldInInterfaceCompanion() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/JvmFieldInInterfaceCompanion.kt");
}
@TestMetadata("WithUnsignedTypeParameters.kt")
public void testWithUnsignedTypeParameters() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/WithUnsignedTypeParameters.kt");
@@ -4618,6 +4618,11 @@ public class LoadJavaUsingJavacTestGenerated extends AbstractLoadJavaUsingJavacT
runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/ConstValInMultifileClass.kt");
}
@TestMetadata("JvmFieldInInterfaceCompanion.kt")
public void testJvmFieldInInterfaceCompanion() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/JvmFieldInInterfaceCompanion.kt");
}
@TestMetadata("WithUnsignedTypeParameters.kt")
public void testWithUnsignedTypeParameters() throws Exception {
runTest("compiler/testData/loadJava/compiledKotlinWithStdlib/annotations/WithUnsignedTypeParameters.kt");
@@ -3,6 +3,8 @@
## 0.0.6
- [`KT-31308`](https://youtrack.jetbrains.com/issue/KT-31308) Add module name extensions to kotlinx-metadata-jvm
- [`KT-31338`](https://youtrack.jetbrains.com/issue/KT-31338) Retain "is moved from interface companion" property flag in kotlinx-metadata-jvm
- Breaking change: JvmPropertyExtensionVisitor.visit has a new parameter `jvmFlags: Flags`
- Rename `desc` parameters to `signature` in JvmFunctionExtensionVisitor, JvmPropertyExtensionVisitor, JvmConstructorExtensionVisitor
## 0.0.5
@@ -0,0 +1,36 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlinx.metadata.jvm
import kotlinx.metadata.Flag
import kotlinx.metadata.Flags
import org.jetbrains.kotlin.metadata.deserialization.Flags as F
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmFlags as JF
/**
* JVM-specific flags in addition to common flags declared in [Flag].
*
* @see Flag
* @see Flags
*/
object JvmFlag {
/**
* JVM-specific property flags in addition to common property flags declared in [Flag.Property].
*/
object Property {
/**
* Applied to a property declared in an interface's companion object, signifies that its backing field is declared as a static
* field in the interface. In Kotlin code, this usually happens if the property is annotated with [JvmField].
*
* Has no effect if the property is not declared in a companion object of some interface.
*/
@JvmField
val IS_MOVED_FROM_INTERFACE_COMPANION = booleanFlag(JF.IS_MOVED_FROM_INTERFACE_COMPANION)
}
private fun booleanFlag(f: F.BooleanFlagField): Flag =
Flag(f.offset, f.bitWidth, 1)
}
@@ -69,6 +69,7 @@ internal class JvmMetadataExtensions : MetadataExtensions {
val setterSignature =
if (propertySignature != null && propertySignature.hasSetter()) propertySignature.setter else null
ext.visit(
proto.getExtension(JvmProtoBuf.flags),
fieldSignature?.wrapAsPublic(),
getterSignature?.run { JvmMethodSignature(c[name], c[desc]) },
setterSignature?.run { JvmMethodSignature(c[name], c[desc]) }
@@ -165,11 +166,17 @@ 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
override fun visit(
fieldSignature: JvmFieldSignature?, getterSignature: JvmMethodSignature?, setterSignature: JvmMethodSignature?
jvmFlags: Flags,
fieldSignature: JvmFieldSignature?,
getterSignature: JvmMethodSignature?,
setterSignature: JvmMethodSignature?
) {
this.jvmFlags = jvmFlags
if (fieldSignature == null && getterSignature == null && setterSignature == null) return
if (signature == null) {
@@ -202,6 +209,9 @@ internal class JvmMetadataExtensions : MetadataExtensions {
}
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())
}
@@ -156,16 +156,37 @@ open class JvmPropertyExtensionVisitor @JvmOverloads constructor(
/**
* Visits JVM signatures of field and accessors generated for the property.
*
* @param jvmFlags JVM-specific flags of the property, consisting of [JvmFlag.Property] flags
* @param fieldSignature the signature of the field, or `null` if this property has no field.
* Example: `JvmFieldSignature("X", "Ljava/lang/Object;")`
*
* @param getterSignature the signature of the property getter, or `null` if this property has no getter or its signature is unknown.
* Example: `JvmMethodSignature("getX()", "Ljava/lang/Object;")`
*
* @param setterSignature the signature of the property setter, or `null` if this property has no setter or its signature is unknown.
* Example: `JvmMethodSignature("setX", "(Ljava/lang/Object;)V")`
*/
open fun visit(fieldSignature: JvmFieldSignature?, getterSignature: JvmMethodSignature?, setterSignature: JvmMethodSignature?) {
open fun visit(
jvmFlags: Flags,
fieldSignature: JvmFieldSignature?,
getterSignature: JvmMethodSignature?,
setterSignature: JvmMethodSignature?
) {
delegate?.visit(jvmFlags, fieldSignature, getterSignature, setterSignature)
@Suppress("DEPRECATION_ERROR")
visit(fieldSignature, getterSignature, setterSignature)
}
@Deprecated(
"Use visit(Flags, JvmFieldSignature?, JvmMethodSignature?, JvmMethodSignature?) instead.",
level = DeprecationLevel.ERROR,
replaceWith = ReplaceWith("visit(flagsOf(), fieldSignature, getterSignature, setterSignature)", "kotlinx.metadata.flagsOf")
)
open fun visit(
fieldSignature: JvmFieldSignature?,
getterSignature: JvmMethodSignature?,
setterSignature: JvmMethodSignature?
) {
@Suppress("DEPRECATION_ERROR")
delegate?.visit(fieldSignature, getterSignature, setterSignature)
}
@@ -37,11 +37,7 @@ import org.jetbrains.kotlin.metadata.ProtoBuf.Class.Kind as ClassKind
* @see Flags
* @see flagsOf
*/
class Flag internal constructor(
private val offset: Int,
private val bitWidth: Int,
private val value: Int
) {
class Flag(private val offset: Int, private val bitWidth: Int, private val value: Int) {
internal constructor(field: F.FlagField<*>, value: Int) : this(field.offset, field.bitWidth, value)
internal constructor(field: F.BooleanFlagField) : this(field, 1)
@@ -96,7 +96,10 @@ private fun visitProperty(flags: Flags, name: String, getterFlags: Flags, setter
if (type != JvmPropertyExtensionVisitor.TYPE) return null
return object : JvmPropertyExtensionVisitor() {
override fun visit(
fieldSignature: JvmFieldSignature?, getterSignature: JvmMethodSignature?, setterSignature: JvmMethodSignature?
jvmFlags: Flags,
fieldSignature: JvmFieldSignature?,
getterSignature: JvmMethodSignature?,
setterSignature: JvmMethodSignature?
) {
fieldDesc = fieldSignature
getterDesc = getterSignature
@@ -95,6 +95,7 @@ private fun visitProperty(
var jvmGetterSignature: JvmMemberSignature? = null
var jvmSetterSignature: JvmMemberSignature? = null
var jvmSyntheticMethodForAnnotationsSignature: JvmMemberSignature? = null
var isMovedFromInterfaceCompanion: Boolean = false
override fun visitReceiverParameterType(flags: Flags): KmTypeVisitor? =
printType(flags) { receiverParameterType = it }
@@ -115,8 +116,12 @@ private fun visitProperty(
if (type != JvmPropertyExtensionVisitor.TYPE) return null
return object : JvmPropertyExtensionVisitor() {
override fun visit(
fieldSignature: JvmFieldSignature?, getterSignature: JvmMethodSignature?, setterSignature: JvmMethodSignature?
jvmFlags: Flags,
fieldSignature: JvmFieldSignature?,
getterSignature: JvmMethodSignature?,
setterSignature: JvmMethodSignature?
) {
isMovedFromInterfaceCompanion = JvmFlag.Property.IS_MOVED_FROM_INTERFACE_COMPANION(jvmFlags)
jvmFieldSignature = fieldSignature
jvmGetterSignature = getterSignature
jvmSetterSignature = setterSignature
@@ -145,6 +150,9 @@ private fun visitProperty(
if (jvmSyntheticMethodForAnnotationsSignature != null) {
sb.appendln(" // synthetic method for annotations: $jvmSyntheticMethodForAnnotationsSignature")
}
if (isMovedFromInterfaceCompanion) {
sb.appendln(" // is moved from interface companion")
}
sb.append(" ")
sb.appendFlags(flags, PROPERTY_FLAGS_MAP)
sb.append(if (Flag.Property.IS_VAR(flags)) "var " else "val ")