From e226561150c2f36c4af9a292d21bfe80b0860e75 Mon Sep 17 00:00:00 2001 From: Mark Punzalan Date: Thu, 23 Jan 2020 13:59:06 -0800 Subject: [PATCH] [JVM IR] Copy metadata in IrFieldBuilder. This fixes an issue with lateinit properties where the metadata from the original field was not copied to the nullable field in LateinitLowering. Also consolidated related tests. --- .../declarations/declarationBuilders.kt | 1 + .../jvm/descriptors/JvmDeclarationFactory.kt | 1 - .../builders/declarations/IrFieldBuilder.kt | 3 ++ .../reflection/mapping/lateinitProperty.kt | 33 ++++++++++++++++ .../box/reflection/mapping/memberProperty.kt | 15 ++++--- .../box/reflection/mapping/privateProperty.kt | 21 ++++++++++ .../reflection/mapping/propertyAccessors.kt | 39 ------------------- .../reflection/mapping/topLevelProperty.kt | 18 +++++---- .../codegen/BlackBoxCodegenTestGenerated.java | 11 ++++-- .../LightAnalysisModeTestGenerated.java | 11 ++++-- .../ir/FirBlackBoxCodegenTestGenerated.java | 11 ++++-- .../ir/IrBlackBoxCodegenTestGenerated.java | 11 ++++-- 12 files changed, 109 insertions(+), 66 deletions(-) create mode 100644 compiler/testData/codegen/box/reflection/mapping/lateinitProperty.kt create mode 100644 compiler/testData/codegen/box/reflection/mapping/privateProperty.kt delete mode 100644 compiler/testData/codegen/box/reflection/mapping/propertyAccessors.kt diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt index 8e7545f8340..88dd0a6ae26 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt @@ -47,6 +47,7 @@ fun IrFieldBuilder.buildField(): IrField { name, type, visibility, isFinal, isExternal, isStatic, origin == IrDeclarationOrigin.FAKE_OVERRIDE ).also { + it.metadata = metadata wrappedDescriptor.bind(it) } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt index 484dbdce7e0..a78b64d4484 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/descriptors/JvmDeclarationFactory.kt @@ -181,7 +181,6 @@ class JvmDeclarationFactory( initializer = oldField.initializer ?.replaceThisByStaticReference(this@JvmDeclarationFactory, oldParent, oldParent.thisReceiver!!) ?.patchDeclarationParents(this) as IrExpressionBody? - (this as IrFieldImpl).metadata = oldField.metadata } } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFieldBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFieldBuilder.kt index 76b4399dd38..b1038194164 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFieldBuilder.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/IrFieldBuilder.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.ir.builders.declarations import org.jetbrains.kotlin.ir.declarations.IrField +import org.jetbrains.kotlin.ir.declarations.MetadataSource import org.jetbrains.kotlin.ir.types.IrType class IrFieldBuilder : IrDeclarationBuilder() { @@ -15,6 +16,7 @@ class IrFieldBuilder : IrDeclarationBuilder() { var isFinal: Boolean = false var isExternal: Boolean = false var isStatic: Boolean = false + var metadata: MetadataSource.Property? = null fun updateFrom(from: IrField) { super.updateFrom(from) @@ -23,5 +25,6 @@ class IrFieldBuilder : IrDeclarationBuilder() { isFinal = from.isFinal isExternal = from.isExternal isStatic = from.isStatic + metadata = from.metadata } } diff --git a/compiler/testData/codegen/box/reflection/mapping/lateinitProperty.kt b/compiler/testData/codegen/box/reflection/mapping/lateinitProperty.kt new file mode 100644 index 00000000000..1e7d15dac46 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/mapping/lateinitProperty.kt @@ -0,0 +1,33 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM + +// WITH_REFLECT + +import kotlin.reflect.jvm.* +import kotlin.test.* + +class K { + lateinit var value: String +} + +fun box(): String { + val p = K::value + + assertNotNull(p.javaField, "Fail p field") + + val getter = p.javaGetter!! + val setter = p.javaSetter!! + + assertEquals(K::class.java.getMethod("getValue"), getter) + assertEquals(K::class.java.getMethod("setValue", String::class.java), setter) + + assertNull(p.getter.javaConstructor) + assertNull(p.setter.javaConstructor) + + val k = K() + assertFails("Fail k getter") { getter.invoke(k) } // lateinit not yet initialized + setter.invoke(k, "foo") + assertEquals("foo", getter.invoke(k), "Fail k setter") + + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/mapping/memberProperty.kt b/compiler/testData/codegen/box/reflection/mapping/memberProperty.kt index 0dd26def3d7..6abdd502b46 100644 --- a/compiler/testData/codegen/box/reflection/mapping/memberProperty.kt +++ b/compiler/testData/codegen/box/reflection/mapping/memberProperty.kt @@ -4,25 +4,28 @@ // WITH_REFLECT import kotlin.reflect.jvm.* -import kotlin.test.assertEquals +import kotlin.test.* class K(var value: Long) fun box(): String { val p = K::value - assert(p.javaField != null) { "Fail p field" } + assertNotNull(p.javaField, "Fail p field") val getter = p.javaGetter!! val setter = p.javaSetter!! - assertEquals(getter, K::class.java.getMethod("getValue")) - assertEquals(setter, K::class.java.getMethod("setValue", Long::class.java)) + assertEquals(K::class.java.getMethod("getValue"), getter) + assertEquals(K::class.java.getMethod("setValue", Long::class.java), setter) + + assertNull(p.getter.javaConstructor) + assertNull(p.setter.javaConstructor) val k = K(42L) - assert(getter.invoke(k) == 42L) { "Fail k getter" } + assertEquals(42L, getter.invoke(k), "Fail k getter") setter.invoke(k, -239L) - assert(getter.invoke(k) == -239L) { "Fail k setter" } + assertEquals(-239L, getter.invoke(k), "Fail k setter") return "OK" } diff --git a/compiler/testData/codegen/box/reflection/mapping/privateProperty.kt b/compiler/testData/codegen/box/reflection/mapping/privateProperty.kt new file mode 100644 index 00000000000..91980480f53 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/mapping/privateProperty.kt @@ -0,0 +1,21 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM + +// WITH_REFLECT + +import kotlin.reflect.* +import kotlin.reflect.full.* +import kotlin.reflect.jvm.* +import kotlin.test.* + +class K(private var value: Long) + +fun box(): String { + val p = K::class.declaredMemberProperties.single() as KMutableProperty1 + + assertNotNull(p.javaField, "Fail p field") + assertNull(p.javaGetter, "Fail p getter") + assertNull(p.javaSetter, "Fail p setter") + + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/mapping/propertyAccessors.kt b/compiler/testData/codegen/box/reflection/mapping/propertyAccessors.kt deleted file mode 100644 index 09a6058493f..00000000000 --- a/compiler/testData/codegen/box/reflection/mapping/propertyAccessors.kt +++ /dev/null @@ -1,39 +0,0 @@ -// IGNORE_BACKEND_FIR: JVM_IR -// TARGET_BACKEND: JVM - -// WITH_REFLECT - -import kotlin.reflect.jvm.* -import kotlin.test.* - -var foo = "foo" - -class A { - var bar = "bar" -} - -fun box(): String { - val fooGetter = ::foo.getter.javaMethod ?: return "Fail fooGetter" - assertEquals("foo", fooGetter.invoke(null)) - - val fooSetter = ::foo.setter.javaMethod ?: return "Fail fooSetter" - fooSetter.invoke(null, "foof") - assertEquals("foof", foo) - - assertNull(::foo.getter.javaConstructor) - assertNull(::foo.setter.javaConstructor) - - - val a = A() - val barGetter = A::bar.getter.javaMethod ?: return "Fail barGetter" - assertEquals("bar", barGetter.invoke(a)) - - val barSetter = A::bar.setter.javaMethod ?: return "Fail barSetter" - barSetter.invoke(a, "barb") - assertEquals("barb", a.bar) - - assertNull(A::bar.getter.javaConstructor) - assertNull(A::bar.setter.javaConstructor) - - return "OK" -} diff --git a/compiler/testData/codegen/box/reflection/mapping/topLevelProperty.kt b/compiler/testData/codegen/box/reflection/mapping/topLevelProperty.kt index 75a9b3c3c21..8168e8a8454 100644 --- a/compiler/testData/codegen/box/reflection/mapping/topLevelProperty.kt +++ b/compiler/testData/codegen/box/reflection/mapping/topLevelProperty.kt @@ -4,7 +4,7 @@ // WITH_REFLECT import kotlin.reflect.jvm.* -import kotlin.test.assertEquals +import kotlin.test.* var topLevel = "123" @@ -13,19 +13,21 @@ val fileFacadeClass = object {}::class.java.enclosingClass fun box(): String { val p = ::topLevel - assert(p.javaField != null) { "Fail p field" } - val field = p.javaField!! - assertEquals(fileFacadeClass, field.getDeclaringClass()) + assertNotNull(p.javaField, "Fail p field") + assertEquals(p.javaField!!.getDeclaringClass(), fileFacadeClass) val getter = p.javaGetter!! val setter = p.javaSetter!! - assertEquals(getter, fileFacadeClass.getMethod("getTopLevel")) - assertEquals(setter, fileFacadeClass.getMethod("setTopLevel", String::class.java)) + assertEquals(fileFacadeClass.getMethod("getTopLevel"), getter) + assertEquals(fileFacadeClass.getMethod("setTopLevel", String::class.java), setter) - assert(getter.invoke(null) == "123") { "Fail k getter" } + assertNull(p.getter.javaConstructor) + assertNull(p.setter.javaConstructor) + + assertEquals("123", getter.invoke(null), "Fail k getter") setter.invoke(null, "456") - assert(getter.invoke(null) == "456") { "Fail k setter" } + assertEquals("456", getter.invoke(null), "Fail k setter") return "OK" } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 737e2f6f054..d253181bc17 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -24439,6 +24439,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/reflection/mapping/interfaceCompanionPropertyWithJvmField.kt"); } + @TestMetadata("lateinitProperty.kt") + public void testLateinitProperty() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/lateinitProperty.kt"); + } + @TestMetadata("mappedClassIsEqualToClassLiteral.kt") public void testMappedClassIsEqualToClassLiteral() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/mappedClassIsEqualToClassLiteral.kt"); @@ -24464,9 +24469,9 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/reflection/mapping/openSuspendFun.kt"); } - @TestMetadata("propertyAccessors.kt") - public void testPropertyAccessors() throws Exception { - runTest("compiler/testData/codegen/box/reflection/mapping/propertyAccessors.kt"); + @TestMetadata("privateProperty.kt") + public void testPrivateProperty() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/privateProperty.kt"); } @TestMetadata("propertyAccessorsWithJvmName.kt") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 6fa72386220..01f0ca05260 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -23256,6 +23256,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/reflection/mapping/interfaceCompanionPropertyWithJvmField.kt"); } + @TestMetadata("lateinitProperty.kt") + public void testLateinitProperty() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/lateinitProperty.kt"); + } + @TestMetadata("mappedClassIsEqualToClassLiteral.kt") public void testMappedClassIsEqualToClassLiteral() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/mappedClassIsEqualToClassLiteral.kt"); @@ -23281,9 +23286,9 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/reflection/mapping/openSuspendFun.kt"); } - @TestMetadata("propertyAccessors.kt") - public void testPropertyAccessors() throws Exception { - runTest("compiler/testData/codegen/box/reflection/mapping/propertyAccessors.kt"); + @TestMetadata("privateProperty.kt") + public void testPrivateProperty() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/privateProperty.kt"); } @TestMetadata("propertyAccessorsWithJvmName.kt") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index e50cf227169..3023d317b18 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -22948,6 +22948,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/reflection/mapping/interfaceCompanionPropertyWithJvmField.kt"); } + @TestMetadata("lateinitProperty.kt") + public void testLateinitProperty() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/lateinitProperty.kt"); + } + @TestMetadata("mappedClassIsEqualToClassLiteral.kt") public void testMappedClassIsEqualToClassLiteral() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/mappedClassIsEqualToClassLiteral.kt"); @@ -22973,9 +22978,9 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/reflection/mapping/openSuspendFun.kt"); } - @TestMetadata("propertyAccessors.kt") - public void testPropertyAccessors() throws Exception { - runTest("compiler/testData/codegen/box/reflection/mapping/propertyAccessors.kt"); + @TestMetadata("privateProperty.kt") + public void testPrivateProperty() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/privateProperty.kt"); } @TestMetadata("propertyAccessorsWithJvmName.kt") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index cb2aff3b2cf..4f2c3361664 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -22948,6 +22948,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/reflection/mapping/interfaceCompanionPropertyWithJvmField.kt"); } + @TestMetadata("lateinitProperty.kt") + public void testLateinitProperty() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/lateinitProperty.kt"); + } + @TestMetadata("mappedClassIsEqualToClassLiteral.kt") public void testMappedClassIsEqualToClassLiteral() throws Exception { runTest("compiler/testData/codegen/box/reflection/mapping/mappedClassIsEqualToClassLiteral.kt"); @@ -22973,9 +22978,9 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/reflection/mapping/openSuspendFun.kt"); } - @TestMetadata("propertyAccessors.kt") - public void testPropertyAccessors() throws Exception { - runTest("compiler/testData/codegen/box/reflection/mapping/propertyAccessors.kt"); + @TestMetadata("privateProperty.kt") + public void testPrivateProperty() throws Exception { + runTest("compiler/testData/codegen/box/reflection/mapping/privateProperty.kt"); } @TestMetadata("propertyAccessorsWithJvmName.kt")