diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/mapping/propertyAccessors.kt b/compiler/testData/codegen/boxWithStdlib/reflection/mapping/propertyAccessors.kt new file mode 100644 index 00000000000..2cfdf212a63 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/mapping/propertyAccessors.kt @@ -0,0 +1,34 @@ +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/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 1c15dbaff2b..09efea600b9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -3237,6 +3237,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("propertyAccessors.kt") + public void testPropertyAccessors() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/propertyAccessors.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("syntheticFields.kt") public void testSyntheticFields() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/mapping/syntheticFields.kt"); diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt index 30460c97e9d..bdb29d29ae4 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KPropertyImpl.kt @@ -57,6 +57,8 @@ interface KMutablePropertyImpl : KMutableProperty, KPropertyImpl { override val setter: Setter abstract class Setter : KMutableProperty.Setter, KPropertyImpl.Accessor, KCallableImpl { + abstract override val property: KMutablePropertyImpl + override val name: String get() = "" override val descriptor: PropertySetterDescriptor by ReflectProperties.lazySoft { diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt index 28d77561159..75945d3bce1 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/mapping.kt @@ -68,7 +68,12 @@ public val KMutableProperty<*>.javaSetter: Method? * or `null` if this function is a constructor or cannot be represented by a Java [Method]. */ public val KFunction<*>.javaMethod: Method? - get() = ((this as? KFunctionImpl)?.caller as? FunctionCaller.Method)?.method + get() = when (this) { + is KFunctionImpl -> (caller as? FunctionCaller.Method)?.method + is KPropertyImpl.Getter<*> -> property.javaGetter + is KMutablePropertyImpl.Setter<*> -> property.javaSetter + else -> null + } /** * Returns a Java [Constructor] instance corresponding to the given Kotlin function, @@ -76,7 +81,10 @@ public val KFunction<*>.javaMethod: Method? */ @suppress("UNCHECKED_CAST") public val KFunction.javaConstructor: Constructor? - get() = ((this as? KFunctionImpl)?.caller as? FunctionCaller.Constructor)?.constructor as? Constructor + get() = when (this) { + is KFunctionImpl -> (caller as? FunctionCaller.Constructor)?.constructor as? Constructor + else -> null + }