Fix reflection for local delegated properties inside interface

#KT-19690
This commit is contained in:
Alexander Udalov
2017-08-17 12:29:16 +03:00
committed by Mikhael Bogdanov
parent 97d46e76f5
commit 4d2fbf1801
6 changed files with 54 additions and 1 deletions
@@ -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
@@ -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()
@@ -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