Skip to content

Commit 4d2fbf1

Browse files
udalovMikhael Bogdanov
authored andcommitted
Fix reflection for local delegated properties inside interface
#KT-19690
1 parent 97d46e7 commit 4d2fbf1

File tree

6 files changed

+54
-1
lines changed

6 files changed

+54
-1
lines changed

compiler/backend/src/org/jetbrains/kotlin/codegen/serialization/JvmSerializerExtension.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.jetbrains.kotlin.name.FqName;
3636
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite;
3737
import org.jetbrains.kotlin.resolve.BindingContext;
38+
import org.jetbrains.kotlin.resolve.DescriptorUtils;
3839
import org.jetbrains.kotlin.serialization.*;
3940
import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite;
4041
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
@@ -85,7 +86,9 @@ public void serializeClass(@NotNull ClassDescriptor descriptor, @NotNull ProtoBu
8586
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName));
8687
}
8788

88-
writeLocalProperties(proto, typeMapper.mapClass(descriptor), JvmProtoBuf.classLocalVariable);
89+
Type containerAsmType =
90+
DescriptorUtils.isInterface(descriptor) ? typeMapper.mapDefaultImpls(descriptor) : typeMapper.mapClass(descriptor);
91+
writeLocalProperties(proto, containerAsmType, JvmProtoBuf.classLocalVariable);
8992
}
9093

9194
@Override
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// TARGET_BACKEND: JVM
2+
// WITH_REFLECT
3+
4+
import kotlin.reflect.KProperty
5+
import kotlin.test.assertEquals
6+
7+
object Delegate {
8+
operator fun getValue(z: Any?, p: KProperty<*>): String? {
9+
assertEquals("val x: kotlin.String?", p.toString())
10+
return "OK"
11+
}
12+
}
13+
14+
interface Foo {
15+
fun bar(): String {
16+
val x by Delegate
17+
return x!!
18+
}
19+
}
20+
21+
object O : Foo
22+
23+
fun box(): String = O.bar()

compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16281,6 +16281,12 @@ public void testAllFilesPresentInLocalDelegated() throws Exception {
1628116281
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/properties/localDelegated"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
1628216282
}
1628316283

16284+
@TestMetadata("defaultImpls.kt")
16285+
public void testDefaultImpls() throws Exception {
16286+
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/defaultImpls.kt");
16287+
doTest(fileName);
16288+
}
16289+
1628416290
@TestMetadata("inlineFun.kt")
1628516291
public void testInlineFun() throws Exception {
1628616292
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt");

compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16281,6 +16281,12 @@ public void testAllFilesPresentInLocalDelegated() throws Exception {
1628116281
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/properties/localDelegated"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
1628216282
}
1628316283

16284+
@TestMetadata("defaultImpls.kt")
16285+
public void testDefaultImpls() throws Exception {
16286+
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/defaultImpls.kt");
16287+
doTest(fileName);
16288+
}
16289+
1628416290
@TestMetadata("inlineFun.kt")
1628516291
public void testInlineFun() throws Exception {
1628616292
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt");

compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16281,6 +16281,12 @@ public void testAllFilesPresentInLocalDelegated() throws Exception {
1628116281
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/properties/localDelegated"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
1628216282
}
1628316283

16284+
@TestMetadata("defaultImpls.kt")
16285+
public void testDefaultImpls() throws Exception {
16286+
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/defaultImpls.kt");
16287+
doTest(fileName);
16288+
}
16289+
1628416290
@TestMetadata("inlineFun.kt")
1628516291
public void testInlineFun() throws Exception {
1628616292
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt");

core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,15 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
199199
staticScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
200200

201201
override fun getLocalProperty(index: Int): PropertyDescriptor? {
202+
// TODO: also check that this is a synthetic class (Metadata.k == 3)
203+
if (jClass.simpleName == JvmAbi.DEFAULT_IMPLS_CLASS_NAME) {
204+
jClass.declaringClass?.let { interfaceClass ->
205+
if (interfaceClass.isInterface) {
206+
return (interfaceClass.kotlin as KClassImpl<*>).getLocalProperty(index)
207+
}
208+
}
209+
}
210+
202211
return (descriptor as? DeserializedClassDescriptor)?.let { descriptor ->
203212
val proto = descriptor.classProto.getExtension(JvmProtoBuf.classLocalVariable, index)
204213
val nameResolver = descriptor.c.nameResolver

0 commit comments

Comments
 (0)