diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java index e734f00ac21..e401e101755 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClosureCodegen.java @@ -373,8 +373,7 @@ public class ClosureCodegen extends MemberCodegen { if (generateBody) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); - Method method = typeMapper.mapAsmMethod(descriptor.getOriginal()); - iv.aconst(method.getName() + method.getDescriptor()); + PropertyReferenceCodegen.generateCallableReferenceSignature(iv, descriptor, state); iv.areturn(JAVA_STRING_TYPE); FunctionCodegen.endVisit(iv, "function reference getSignature", element); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 20789073dd0..38cdc7ca617 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -525,7 +525,7 @@ public abstract class MemberCodegen", Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt index 03b02ad1dba..e36dc3e3f47 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyReferenceCodegen.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.resolve.DescriptorFactory +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.PropertyImportedFromObject import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.jvm.AsmTypes.* @@ -110,7 +111,7 @@ class PropertyReferenceCodegen( } generateMethod("property reference getSignature", ACC_PUBLIC, method("getSignature", JAVA_STRING_TYPE)) { - aconst(getPropertyReferenceSignature(target as VariableDescriptorWithAccessors, state)) + generateCallableReferenceSignature(this, target, state) } if (!isLocalDelegatedProperty) { @@ -180,14 +181,19 @@ class PropertyReferenceCodegen( companion object { @JvmStatic - fun getPropertyReferenceSignature(property: VariableDescriptorWithAccessors, state: GenerationState): String { - val getter = - property.getter ?: DescriptorFactory.createDefaultGetter(property as PropertyDescriptor, Annotations.EMPTY).apply { - initialize(property.type) + fun generateCallableReferenceSignature(iv: InstructionAdapter, callable: CallableDescriptor, state: GenerationState) { + val accessor = when (callable) { + is FunctionDescriptor -> callable + is VariableDescriptorWithAccessors -> + callable.getter ?: + DescriptorFactory.createDefaultGetter(callable as PropertyDescriptor, Annotations.EMPTY).apply { + initialize(callable.type) } - - val method = state.typeMapper.mapAsmMethod(getter.original) - return method.name + method.descriptor + else -> error("Unsupported callable reference: $callable") + } + val declaration = DescriptorUtils.unwrapFakeOverride(accessor).original + val method = state.typeMapper.mapAsmMethod(declaration) + iv.aconst(method.name + method.descriptor) } @JvmStatic diff --git a/compiler/testData/codegen/box/reflection/functions/genericOverriddenFunction.kt b/compiler/testData/codegen/box/reflection/functions/genericOverriddenFunction.kt new file mode 100644 index 00000000000..20a2c35921f --- /dev/null +++ b/compiler/testData/codegen/box/reflection/functions/genericOverriddenFunction.kt @@ -0,0 +1,16 @@ +// WITH_REFLECT + +import kotlin.test.assertEquals + +interface H { + fun foo(): T? +} + +interface A : H + +fun box(): String { + assertEquals("A?", A::foo.returnType.toString()) + assertEquals("T?", H::foo.returnType.toString()) + + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/properties/genericOverriddenProperty.kt b/compiler/testData/codegen/box/reflection/properties/genericOverriddenProperty.kt new file mode 100644 index 00000000000..bca17295094 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/properties/genericOverriddenProperty.kt @@ -0,0 +1,17 @@ +// WITH_REFLECT +// KT-13700 Exception obtaining descriptor for property reference + +import kotlin.test.assertEquals + +interface H { + val parent : T? +} + +interface A : H + +fun box(): String { + assertEquals("A?", A::parent.returnType.toString()) + assertEquals("T?", H::parent.returnType.toString()) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 2f22f769cc0..67784063f25 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -12258,6 +12258,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("genericOverriddenFunction.kt") + public void testGenericOverriddenFunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/functions/genericOverriddenFunction.kt"); + doTest(fileName); + } + @TestMetadata("javaClassGetFunctions.kt") public void testJavaClassGetFunctions() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/functions/javaClassGetFunctions.kt"); @@ -12999,6 +13005,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("genericOverriddenProperty.kt") + public void testGenericOverriddenProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/genericOverriddenProperty.kt"); + doTest(fileName); + } + @TestMetadata("genericProperty.kt") public void testGenericProperty() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/properties/genericProperty.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java index 3a6b4c937e0..8d771b2e39f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorUtils.java @@ -33,7 +33,10 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.constants.StringValue; import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter; import org.jetbrains.kotlin.resolve.scopes.MemberScope; -import org.jetbrains.kotlin.types.*; +import org.jetbrains.kotlin.types.ErrorUtils; +import org.jetbrains.kotlin.types.KotlinType; +import org.jetbrains.kotlin.types.TypeConstructor; +import org.jetbrains.kotlin.types.TypeUtils; import org.jetbrains.kotlin.types.checker.KotlinTypeChecker; import java.util.*; @@ -418,8 +421,8 @@ public class DescriptorUtils { /** * Given a fake override, finds any declaration of it in the overridden descriptors. Keep in mind that there may be many declarations - * of the fake override in the supertypes, this method finds just the only one. - * TODO: probably all call-sites of this method are wrong, they should handle all super-declarations + * of the fake override in the supertypes, this method finds just only one of them. + * TODO: probably some call-sites of this method are wrong, they should handle all super-declarations */ @NotNull @SuppressWarnings("unchecked")