From 3345dc81fd629ea48d1f33c41fcd4e549ba2313a Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 10 Aug 2018 17:19:08 +0200 Subject: [PATCH] Do not return field signature if there's none in the metadata Otherwise this code behaves incorrectly on getter-only properties: it returns a meaningless field signature whereas the property has no field. It's hard to come up with an example of when this could matter in compiler code, but it's very noticeable in kotlinx-metadata-jvm #KT-26188 Fixed --- .../jvm/deserialization/JvmProtoBufUtil.kt | 9 ++-- libraries/kotlinx-metadata/jvm/ChangeLog.md | 1 + .../kotlinp/test/KotlinpTestGenerated.java | 5 +++ .../tools/kotlinp/testData/Properties.kt | 12 ++++++ .../tools/kotlinp/testData/Properties.txt | 41 +++++++++++++++++++ 5 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 libraries/tools/kotlinp/testData/Properties.kt create mode 100644 libraries/tools/kotlinp/testData/Properties.txt diff --git a/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmProtoBufUtil.kt b/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmProtoBufUtil.kt index a98095d0cc0..d304315c255 100644 --- a/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmProtoBufUtil.kt +++ b/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmProtoBufUtil.kt @@ -104,13 +104,12 @@ object JvmProtoBufUtil { typeTable: TypeTable ): JvmMemberSignature.Field? { val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return null - val field = - if (signature.hasField()) signature.field else null + val field = if (signature.hasField()) signature.field else return null - val name = if (field != null && field.hasName()) field.name else proto.name + val name = if (field.hasName()) field.name else proto.name val desc = - if (field != null && field.hasDesc()) nameResolver.getString(field.desc) - else mapTypeDefault(proto.returnType(typeTable), nameResolver) ?: return null + if (field.hasDesc()) nameResolver.getString(field.desc) + else mapTypeDefault(proto.returnType(typeTable), nameResolver) ?: return null return JvmMemberSignature.Field(nameResolver.getString(name), desc) } diff --git a/libraries/kotlinx-metadata/jvm/ChangeLog.md b/libraries/kotlinx-metadata/jvm/ChangeLog.md index 8d49c3ca9fc..0ff6f705010 100644 --- a/libraries/kotlinx-metadata/jvm/ChangeLog.md +++ b/libraries/kotlinx-metadata/jvm/ChangeLog.md @@ -4,6 +4,7 @@ - [`KT-25920`](https://youtrack.jetbrains.com/issue/KT-25920) Compile kotlinx-metadata-jvm with JVM target bytecode version 1.6 instead of 1.8 - [`KT-25223`](https://youtrack.jetbrains.com/issue/KT-25223) Add JvmFunctionExtensionVisitor.visitEnd +- [`KT-26188`](https://youtrack.jetbrains.com/issue/KT-26188) Do not pass field signature for accessor-only properties ## 0.0.3 diff --git a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestGenerated.java b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestGenerated.java index 96d2f93f1d3..22ee4c9b0df 100644 --- a/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestGenerated.java +++ b/libraries/tools/kotlinp/test/org/jetbrains/kotlin/kotlinp/test/KotlinpTestGenerated.java @@ -64,6 +64,11 @@ public class KotlinpTestGenerated extends AbstractKotlinpTest { runTest("libraries/tools/kotlinp/testData/PlatformType.kt"); } + @TestMetadata("Properties.kt") + public void testProperties() throws Exception { + runTest("libraries/tools/kotlinp/testData/Properties.kt"); + } + @TestMetadata("SimpleClass.kt") public void testSimpleClass() throws Exception { runTest("libraries/tools/kotlinp/testData/SimpleClass.kt"); diff --git a/libraries/tools/kotlinp/testData/Properties.kt b/libraries/tools/kotlinp/testData/Properties.kt new file mode 100644 index 00000000000..6b7b54aac74 --- /dev/null +++ b/libraries/tools/kotlinp/testData/Properties.kt @@ -0,0 +1,12 @@ +class C(val constructorParam: String = "") { + val getterOnlyVal: Double get() = 0.0 + var accessorOnlyVar: Int + get() = 1 + set(value) {} + + var withBackingField: String = "42" + + val T.delegated: List by null + + operator fun Nothing?.getValue(x: Any?, y: Any?) = emptyList() +} diff --git a/libraries/tools/kotlinp/testData/Properties.txt b/libraries/tools/kotlinp/testData/Properties.txt new file mode 100644 index 00000000000..36b9b2e5d55 --- /dev/null +++ b/libraries/tools/kotlinp/testData/Properties.txt @@ -0,0 +1,41 @@ +// C.class +// ------------------------------------------ +public final class C : kotlin/Any { + + // signature: (Ljava/lang/String;)V + public /* primary */ constructor(constructorParam: kotlin/String /* = ... */) + + // signature: getValue(Ljava/lang/Void;Ljava/lang/Object;Ljava/lang/Object;)Ljava/util/List; + public final operator fun kotlin/Nothing?.getValue(x: kotlin/Any?, y: kotlin/Any?): kotlin/collections/List + + // getter: getAccessorOnlyVar()I + // setter: setAccessorOnlyVar(I)V + public final var accessorOnlyVar: kotlin/Int + public final /* non-default */ get + public final /* non-default */ set(value: kotlin/Int) + + // field: constructorParam:Ljava/lang/String; + // getter: getConstructorParam()Ljava/lang/String; + public final val constructorParam: kotlin/String + public final get + + // getter: getGetterOnlyVal()D + public final val getterOnlyVal: kotlin/Double + public final /* non-default */ get + + // field: withBackingField:Ljava/lang/String; + // getter: getWithBackingField()Ljava/lang/String; + // setter: setWithBackingField(Ljava/lang/String;)V + public final var withBackingField: kotlin/String + public final get + public final set + + // field: delegated$delegate:Ljava/lang/Void; + // getter: getDelegated(Ljava/lang/Number;)Ljava/util/List; + public final /* delegated */ val T#0.delegated: kotlin/collections/List + public final /* non-default */ get +} +// META-INF/test-module.kotlin_module +// ------------------------------------------ +module { +}