Fix reflection for local delegated properties inside interface
#KT-19690
This commit is contained in:
committed by
Mikhael Bogdanov
parent
97d46e76f5
commit
4d2fbf1801
+4
-1
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.serialization.*;
|
||||
import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite;
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
|
||||
@@ -85,7 +86,9 @@ public class JvmSerializerExtension extends SerializerExtension {
|
||||
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName));
|
||||
}
|
||||
|
||||
writeLocalProperties(proto, typeMapper.mapClass(descriptor), JvmProtoBuf.classLocalVariable);
|
||||
Type containerAsmType =
|
||||
DescriptorUtils.isInterface(descriptor) ? typeMapper.mapDefaultImpls(descriptor) : typeMapper.mapClass(descriptor);
|
||||
writeLocalProperties(proto, containerAsmType, JvmProtoBuf.classLocalVariable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
object Delegate {
|
||||
operator fun getValue(z: Any?, p: KProperty<*>): String? {
|
||||
assertEquals("val x: kotlin.String?", p.toString())
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
interface Foo {
|
||||
fun bar(): String {
|
||||
val x by Delegate
|
||||
return x!!
|
||||
}
|
||||
}
|
||||
|
||||
object O : Foo
|
||||
|
||||
fun box(): String = O.bar()
|
||||
+6
@@ -16281,6 +16281,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/properties/localDelegated"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultImpls.kt")
|
||||
public void testDefaultImpls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/defaultImpls.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFun.kt")
|
||||
public void testInlineFun() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt");
|
||||
|
||||
@@ -16281,6 +16281,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/properties/localDelegated"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultImpls.kt")
|
||||
public void testDefaultImpls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/defaultImpls.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFun.kt")
|
||||
public void testInlineFun() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt");
|
||||
|
||||
@@ -16281,6 +16281,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/properties/localDelegated"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultImpls.kt")
|
||||
public void testDefaultImpls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/defaultImpls.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFun.kt")
|
||||
public void testInlineFun() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt");
|
||||
|
||||
@@ -199,6 +199,15 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
|
||||
staticScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
|
||||
|
||||
override fun getLocalProperty(index: Int): PropertyDescriptor? {
|
||||
// TODO: also check that this is a synthetic class (Metadata.k == 3)
|
||||
if (jClass.simpleName == JvmAbi.DEFAULT_IMPLS_CLASS_NAME) {
|
||||
jClass.declaringClass?.let { interfaceClass ->
|
||||
if (interfaceClass.isInterface) {
|
||||
return (interfaceClass.kotlin as KClassImpl<*>).getLocalProperty(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (descriptor as? DeserializedClassDescriptor)?.let { descriptor ->
|
||||
val proto = descriptor.classProto.getExtension(JvmProtoBuf.classLocalVariable, index)
|
||||
val nameResolver = descriptor.c.nameResolver
|
||||
|
||||
Reference in New Issue
Block a user