Fix reflective access on overridden generic property reference
Generation of callable reference's signature in codegen should use the same mechanism for obtaining the signature as the runtime in RuntimeTypeMapper, namely DescriptorUtils.unwrapFakeOverride(...).original #KT-13700 Fixed
This commit is contained in:
@@ -373,8 +373,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -525,7 +525,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
||||
// TODO: generate the container once and save to a local field instead (KT-10495)
|
||||
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
|
||||
iv.aconst(property.getName().asString());
|
||||
iv.aconst(PropertyReferenceCodegen.getPropertyReferenceSignature(property, state));
|
||||
PropertyReferenceCodegen.generateCallableReferenceSignature(iv, property, state);
|
||||
iv.invokespecial(
|
||||
implType.getInternalName(), "<init>",
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user