From 5732a99f9d3924459723a3c82625cfb9adf5b512 Mon Sep 17 00:00:00 2001 From: Anders Fugmann Date: Mon, 8 Jun 2026 11:50:56 +0200 Subject: [PATCH] Kotlin 2.4.0: Fix extension receiver on property references In 2.4.0's unified parameters model, IrPropertyReference stores the bound extension receiver in the arguments list (indexed via the getter's extension receiver parameter). Our codeQlExtensionReceiver compat function only handled the case where symbol.owner is an IrFunction, returning null for IrPropertyReference (where symbol.owner is IrProperty). Fix: when the direct cast to IrFunction fails, look at the getter/setter function's parameters to find the extension receiver index. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../kotlin/utils/versions/v_2_4_0/IrCompat.kt | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/IrCompat.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/IrCompat.kt index e388a09c37a..7e461e6da62 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/IrCompat.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/IrCompat.kt @@ -49,16 +49,35 @@ fun IrMemberAccessExpression<*>.codeQlPutValueArgument(index: Int, value: IrExpr } // IrMemberAccessExpression: extensionReceiver +// For IrCall/IrFunctionReference, look at symbol.owner (IrFunction) directly. +// For IrPropertyReference, symbol.owner is IrProperty; use the getter's parameters instead. var IrMemberAccessExpression<*>.codeQlExtensionReceiver: IrExpression? get() { - val erp = symbol.owner.let { it as? IrFunction }?.codeQlExtensionReceiverParameter ?: return null - return arguments[erp.indexInParameters] + val erp = extensionReceiverParameterIndex() ?: return null + return arguments[erp] } set(value) { - val erp = symbol.owner.let { it as? IrFunction }?.codeQlExtensionReceiverParameter ?: return - arguments[erp.indexInParameters] = value + val erp = extensionReceiverParameterIndex() ?: return + arguments[erp] = value } +private fun IrMemberAccessExpression<*>.extensionReceiverParameterIndex(): Int? { + // Direct function owner (IrCall, IrFunctionReference, etc.) + (symbol.owner as? IrFunction)?.codeQlExtensionReceiverParameter?.let { + return it.indexInParameters + } + // Property reference: look at getter or setter function + (this as? org.jetbrains.kotlin.ir.expressions.IrPropertyReference)?.let { propRef -> + propRef.getter?.owner?.codeQlExtensionReceiverParameter?.let { + return it.indexInParameters + } + propRef.setter?.owner?.codeQlExtensionReceiverParameter?.let { + return it.indexInParameters + } + } + return null +} + // IrMemberAccessExpression: typeArgumentsCount val IrMemberAccessExpression<*>.codeQlTypeArgumentsCount: Int get() = typeArguments.size