From 0f83586757e86965a0eb85631ddecf65485df395 Mon Sep 17 00:00:00 2001 From: Anders Fugmann Date: Fri, 19 Jun 2026 13:45:05 +0200 Subject: [PATCH] Kotlin 2.4.0: Address peer review * Update documentation to only claim support for 2.4.0x * Python test code; remove newlines between imports. * Sync comments between kotlin 1.8 and 1.9 * Update code comments to attach where actually relevant, and improve comments on IrMemberAccessExpression<*>.extensionReceiverParameterIndex() --- .../reusables/supported-versions-compilers.rst | 2 +- .../versions/v_1_8_0/Kotlin2ComponentRegistrar.kt | 2 ++ .../main/kotlin/utils/versions/v_2_4_0/IrCompat.kt | 12 +++++++----- .../all-platforms/enhanced-nullability/test.py | 1 - .../external-property-overloads/test.py | 1 - .../kotlin/all-platforms/file_classes/test.py | 1 - .../java-interface-redeclares-tostring/test.py | 1 - .../kotlin_java_lowering_wildcards/test.py | 1 - 8 files changed, 10 insertions(+), 11 deletions(-) diff --git a/docs/codeql/reusables/supported-versions-compilers.rst b/docs/codeql/reusables/supported-versions-compilers.rst index aacb188eb20..7a88dd035c2 100644 --- a/docs/codeql/reusables/supported-versions-compilers.rst +++ b/docs/codeql/reusables/supported-versions-compilers.rst @@ -21,7 +21,7 @@ Java,"Java 7 to 26 [6]_","javac (OpenJDK and Oracle JDK), Eclipse compiler for Java (ECJ) [7]_",``.java`` - Kotlin,"Kotlin 1.8.0 to 2.4.\ *x*","kotlinc",``.kt`` + Kotlin,"Kotlin 1.8.0 to 2.4.0\ *x*","kotlinc",``.kt`` JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [8]_" Python [9]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13",Not applicable,``.py`` Ruby [10]_,"up to 3.3",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``" diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/Kotlin2ComponentRegistrar.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/Kotlin2ComponentRegistrar.kt index 3aef6a7dc7a..4be3767d04f 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/Kotlin2ComponentRegistrar.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/Kotlin2ComponentRegistrar.kt @@ -28,6 +28,8 @@ abstract class Kotlin2ComponentRegistrar : ComponentRegistrar { fun registerExtractorExtension(extension: IrGenerationExtension) { val p = project ?: throw IllegalStateException("registerExtractorExtension called before registerProjectComponents") + // Register with LoadingOrder.LAST to ensure the extractor runs after other + // IR generation plugins (like kotlinx.serialization) have generated their code. val extensionPoint = p.extensionArea.getExtensionPoint(IrGenerationExtension.extensionPointName) extensionPoint.registerExtension(extension, LoadingOrder.LAST, p) } 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 69124936be9..2906b18c314 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 @@ -30,33 +30,36 @@ val IrFunction.codeQlExtensionReceiverParameter: IrValueParameter? get() = parameters.firstOrNull { it.kind == org.jetbrains.kotlin.ir.declarations.IrParameterKind.ExtensionReceiver } // Helper: get the offset of value arguments in the arguments list -// In 2.4.0, arguments[] includes dispatch/extension receivers before regular params private fun IrMemberAccessExpression<*>.valueArgumentOffset(): Int { val owner = symbol.owner as? IrFunction ?: return 0 return owner.parameters.count { it.kind != org.jetbrains.kotlin.ir.declarations.IrParameterKind.Regular } } // IrMemberAccessExpression: valueArgumentsCount +// In 2.4.0, arguments[] includes dispatch/extension receivers before regular params val IrMemberAccessExpression<*>.codeQlValueArgumentsCount: Int get() = arguments.size - valueArgumentOffset() // IrMemberAccessExpression: getValueArgument +// In 2.4.0, arguments[] includes dispatch/extension receivers before regular params fun IrMemberAccessExpression<*>.codeQlGetValueArgument(index: Int): IrExpression? = arguments[index + valueArgumentOffset()] // IrMemberAccessExpression: putValueArgument +// In 2.4.0, arguments[] includes dispatch/extension receivers before regular params fun IrMemberAccessExpression<*>.codeQlPutValueArgument(index: Int, value: IrExpression?) { arguments[index + valueArgumentOffset()] = value } -// IrMemberAccessExpression: extensionReceiver -// For IrCall/IrFunctionReference, look at symbol.owner (IrFunction) directly. -// For IrPropertyReference, symbol.owner is IrProperty; use the getter's parameters instead. +// Re-add accessor for the extensionReceiver property removed in Kotlin 2.4.0. val IrMemberAccessExpression<*>.codeQlExtensionReceiver: IrExpression? get() { val erp = extensionReceiverParameterIndex() ?: return null return arguments[erp] } +// Find the argument index corresponding to the extension receiver parameter. +// Calls and function references expose an IrFunction owner directly; property +// references need to look through their getter or setter. private fun IrMemberAccessExpression<*>.extensionReceiverParameterIndex(): Int? { // Direct function owner (IrCall, IrFunctionReference, etc.) (symbol.owner as? IrFunction)?.codeQlExtensionReceiverParameter?.let { @@ -118,4 +121,3 @@ fun codeQlAnnotationFromSymbolOwner( fun codeQlAnnotationFromSymbolOwner(type: IrType, symbol: IrConstructorSymbol): IrConstructorCall = IrAnnotationImpl.fromSymbolOwner(type, symbol) - diff --git a/java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.py b/java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.py index d4dc20e7e65..bec294a0623 100644 --- a/java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.py +++ b/java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.py @@ -1,5 +1,4 @@ import pathlib - import pytest diff --git a/java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.py b/java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.py index 6306fe00a9a..711066d9490 100644 --- a/java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.py +++ b/java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.py @@ -1,5 +1,4 @@ import commands - import pytest diff --git a/java/ql/integration-tests/kotlin/all-platforms/file_classes/test.py b/java/ql/integration-tests/kotlin/all-platforms/file_classes/test.py index 4657b69b8f1..cdd8dee68ba 100644 --- a/java/ql/integration-tests/kotlin/all-platforms/file_classes/test.py +++ b/java/ql/integration-tests/kotlin/all-platforms/file_classes/test.py @@ -1,5 +1,4 @@ import commands - import pytest diff --git a/java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.py b/java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.py index 98dabf87dde..c0fc238c2a0 100644 --- a/java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.py +++ b/java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.py @@ -1,5 +1,4 @@ import commands - import pytest diff --git a/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.py b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.py index c565721e2c8..c44bc319a95 100644 --- a/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.py +++ b/java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.py @@ -1,5 +1,4 @@ import commands - import pytest