[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.
This commit is contained in:
Mark Punzalan
2020-01-23 13:59:06 -08:00
committed by Alexander Udalov
parent f5f25224b0
commit e226561150
12 changed files with 109 additions and 66 deletions
@@ -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)
}
}
@@ -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
}
}
}
@@ -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
}
}
@@ -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"
}
@@ -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"
}
@@ -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<K, Long>
assertNotNull(p.javaField, "Fail p field")
assertNull(p.javaGetter, "Fail p getter")
assertNull(p.javaSetter, "Fail p setter")
return "OK"
}
@@ -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"
}
@@ -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"
}
@@ -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")
@@ -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")
@@ -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")
@@ -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")