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.name.FqName;
|
||||||
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite;
|
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.serialization.*;
|
import org.jetbrains.kotlin.serialization.*;
|
||||||
import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite;
|
import org.jetbrains.kotlin.serialization.jvm.ClassMapperLite;
|
||||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
|
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf;
|
||||||
@@ -85,7 +86,9 @@ public class JvmSerializerExtension extends SerializerExtension {
|
|||||||
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName));
|
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
|
@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);
|
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")
|
@TestMetadata("inlineFun.kt")
|
||||||
public void testInlineFun() throws Exception {
|
public void testInlineFun() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt");
|
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);
|
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")
|
@TestMetadata("inlineFun.kt")
|
||||||
public void testInlineFun() throws Exception {
|
public void testInlineFun() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt");
|
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);
|
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")
|
@TestMetadata("inlineFun.kt")
|
||||||
public void testInlineFun() throws Exception {
|
public void testInlineFun() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/localDelegated/inlineFun.kt");
|
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)
|
staticScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
|
||||||
|
|
||||||
override fun getLocalProperty(index: Int): PropertyDescriptor? {
|
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 ->
|
return (descriptor as? DeserializedClassDescriptor)?.let { descriptor ->
|
||||||
val proto = descriptor.classProto.getExtension(JvmProtoBuf.classLocalVariable, index)
|
val proto = descriptor.classProto.getExtension(JvmProtoBuf.classLocalVariable, index)
|
||||||
val nameResolver = descriptor.c.nameResolver
|
val nameResolver = descriptor.c.nameResolver
|
||||||
|
|||||||
Reference in New Issue
Block a user