Skip to content

Kotlin: add Kotlin 2.4.0 support#21970

Open
andersfugmann wants to merge 2 commits into
mainfrom
andersfugmann/kotlin-2.4-v2
Open

Kotlin: add Kotlin 2.4.0 support#21970
andersfugmann wants to merge 2 commits into
mainfrom
andersfugmann/kotlin-2.4-v2

Conversation

@andersfugmann

@andersfugmann andersfugmann commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Add extractor support for Kotlin 2.4.0 and adjust the integration tests that depend on a pre-2.4 compiler.

Changes

  • Extractor support for 2.4.0. Adds the Kotlin 2.4.0 compiler-plugin variant (component registrar, IR compatibility shims, and version-specific utilities), bundles the 2.4.0 compiler dependencies, updates the build wiring (BUILD.bazel, versions.bzl, MODULE.bazel, dev/wrapper.py), refreshes the supported-versions documentation, and raises the "Kotlin version too new" diagnostic bound from 2.3.30 to 2.4.10.
  • Mark kotlin1 integration tests. Six integration tests pass -language-version 1.9, which Kotlin 2.4 no longer accepts. They are marked with @pytest.mark.kotlin1 so CI can run them on a pinned pre-2.4 compiler.

Notes

  • This PR does not change query results: the only expected-file change is the version bound in the kotlin-version-too-new diagnostic.
  • The known K2 mixed Java/Kotlin extractor differences (which become visible once -language-version 1.9 is no longer available) are a needed follow-up investigation.

Copilot AI review requested due to automatic review settings June 11, 2026 07:34
@andersfugmann andersfugmann requested review from a team as code owners June 11, 2026 07:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request updates the Java/Kotlin extractor and its test infrastructure to support Kotlin 2.4.0, while dropping Kotlin 1.x support (minimum Kotlin version becomes 2.0.0) and updating baselines/docs accordingly.

Changes:

  • Add Kotlin 2.4.0 compiler/stdlib dependencies and extractor compatibility shims for Kotlin IR API changes in 2.4.0.
  • Switch Kotlin integration tests that previously used Kotlin 1.x language mode to use -language-version 2.0, and update expected outputs.
  • Update docs and change notes to reflect the new supported Kotlin version range and deprecation of Kotlin < 2.0.
Show a summary per file
File Description
MODULE.bazel Adds Bazel repos for Kotlin 2.4.0 compiler/embeddable/stdlib artifacts.
java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/DB-CHECK.expected Updated test baseline output (dbcheck).
java/ql/test/query-tests/security/CWE-312/android/CleartextStorage/CleartextStorageSharedPrefsTest.expected Updated test baseline output.
java/ql/test/library-tests/pathsanitizer/test.expected Updated test baseline output.
java/ql/test/library-tests/pathsanitizer/DB-CHECK.expected Updated test baseline output (dbcheck).
java/ql/lib/change-notes/2026-06-08-kotlin-drop-1x.md Adds change note deprecating Kotlin < 2.0.
java/ql/lib/change-notes/2026-06-04-kotlin-2.4.0.md Adds change note for Kotlin 2.4.0 support.
java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.py Moves test compilation to -language-version 2.0.
java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/test.expected Updates expected output for wildcard lowering changes.
java/ql/integration-tests/kotlin/all-platforms/kotlin_java_lowering_wildcards/DB-CHECK.expected Updated test baseline output (dbcheck).
java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.py Moves test compilation to -language-version 2.0.
java/ql/integration-tests/kotlin/all-platforms/java-interface-redeclares-tostring/test.expected Updates expected output for interface toString redeclare scenario.
java/ql/integration-tests/kotlin/all-platforms/file_classes/test.py Moves test compilation to -language-version 2.0.
java/ql/integration-tests/kotlin/all-platforms/file_classes/classes.expected Updates expected class extraction output.
java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/test.py Moves test compilation to -language-version 2.0.
java/ql/integration-tests/kotlin/all-platforms/extractor_information_kotlin1/ExtractorInformation.expected Updates expected extractor info (Uses Kotlin 2 flag).
java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.py Moves test compilation to -language-version 2.0.
java/ql/integration-tests/kotlin/all-platforms/external-property-overloads/test.expected Updates expected external binary location formatting.
java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.py Moves test compilation to -language-version 2.0.
java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/test.expected Updates expected output for enhanced nullability extraction.
java/ql/integration-tests/kotlin/all-platforms/enhanced-nullability/DB-CHECK.expected Updated test baseline output (dbcheck).
java/ql/integration-tests/kotlin/all-platforms/diagnostics/kotlin-version-too-new/diagnostics.expected Updates max-supported-version diagnostic message.
java/kotlin-extractor/versions.bzl Adds 2.4.0 to supported versions list; adjusts language-version mapping.
java/kotlin-extractor/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar Adds service registration for Kotlin 2.4+ compiler plugin registrar.
java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/parameterIndexExcludingReceivers.kt Adds Kotlin 2.4.0-specific parameter indexing logic (handles new receiver kinds).
java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/Kotlin2ComponentRegistrar.kt Introduces Kotlin 2.4.0 CompilerPluginRegistrar-based registration path.
java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/IrCompat.kt Adds Kotlin 2.4.0 IR compatibility accessors for removed APIs.
java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_0-Beta/Kotlin2ComponentRegistrar.kt Refactors older registrar to route through doRegisterExtensions and centralize extension registration.
java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/Kotlin2ComponentRegistrar.kt Refactors older registrar to route through doRegisterExtensions.
java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/IrCompat.kt Adds pre-2.4.0 IR compatibility wrappers matching the new shim API.
java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt Switches annotation handling to compatibility wrappers (codeQlAddAnnotations / codeQlAnnotationFromSymbolOwner).
java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt Switches annotation argument access to compatibility wrappers.
java/kotlin-extractor/src/main/kotlin/TrapWriter.kt Switches extension receiver access to compatibility wrapper.
java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt Switches IR annotation construction/mutation to compatibility wrappers.
java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt Switches parameter/receiver access to compatibility wrappers.
java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt Switches multiple IR access patterns to compatibility wrappers; updates related comment/docs.
java/kotlin-extractor/src/main/kotlin/KotlinExtractorComponentRegistrar.kt Refactors registrar to use doRegisterExtensions and centralized extension registration.
java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt Switches extension receiver detection to compatibility wrapper.
java/kotlin-extractor/dev/wrapper.py Bumps default wrapper Kotlin version to 2.4.0.
java/kotlin-extractor/deps/kotlin-stdlib-2.4.0.jar Adds Kotlin 2.4.0 stdlib (LFS pointer).
java/kotlin-extractor/deps/kotlin-compiler-embeddable-2.4.0.jar Adds Kotlin 2.4.0 embeddable compiler (LFS pointer).
java/kotlin-extractor/deps/kotlin-compiler-2.4.0.jar Adds Kotlin 2.4.0 compiler (LFS pointer).
java/kotlin-extractor/BUILD.bazel Conditionally packages CompilerPluginRegistrar service file for Kotlin >= 2.4.0.
docs/codeql/reusables/supported-versions-compilers.rst Updates documented supported Kotlin version range to 2.0.0–2.4.x.

Copilot's findings

  • Files reviewed: 44/44 changed files
  • Comments generated: 4

Comment on lines 7810 to 7812
* this.dispatchReceiver = dispatchReceiver
* this.extensionReceiver = extensionReceiver
* this.codeQlExtensionReceiver = extensionReceiver
* }
Comment thread java/kotlin-extractor/versions.bzl
@andersfugmann andersfugmann force-pushed the andersfugmann/kotlin-2.4-v2 branch 2 times, most recently from 30b0a30 to 547c78f Compare June 12, 2026 09:53
@andersfugmann andersfugmann marked this pull request as draft June 12, 2026 14:09
@hfhbd hfhbd mentioned this pull request Jun 13, 2026
andersfugmann and others added 2 commits June 16, 2026 16:24
Add the Kotlin 2.4.0 compiler plugin variant (component registrar,
IR compatibility shims, and version-specific utilities), bundle the
2.4.0 compiler dependencies, and update the build wiring, supported
version metadata and the too-new diagnostic bound.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mark the integration tests that require a Kotlin 1.x language version
with @pytest.mark.kotlin1 so CI can run them on a pinned pre-2.4
compiler (Kotlin 2.4 no longer accepts -language-version 1.9).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@andersfugmann andersfugmann force-pushed the andersfugmann/kotlin-2.4-v2 branch from 79437b8 to 1b785a8 Compare June 16, 2026 14:25
@andersfugmann andersfugmann changed the title Kotlin support 2.4.0 and drop 1.x test mode Kotlin: add Kotlin 2.4.0 support Jun 17, 2026
@andersfugmann andersfugmann marked this pull request as ready for review June 17, 2026 08:16

@jketema jketema left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments and questions. Nothing major here.

Comment on lines +32 to +33
// Register with LoadingOrder.LAST to ensure the extractor runs after other
// IR generation plugins (like kotlinx.serialization) have generated their code.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is here, but not in the 1.8 version. Should we make this uniform?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, there were some changes on how the component was registered so we needed this for force that our plugin last. I agree it would make sense to see if we can make this more uniform.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks identical to me between 1.8 and 1.9, or are there differences?

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment about arguments[] is important, but seems a bit misplaced. Should probably be attached to the next three functions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to update.

Comment on lines +52 to +53
// For IrCall/IrFunctionReference, look at symbol.owner (IrFunction) directly.
// For IrPropertyReference, symbol.owner is IrProperty; use the getter's parameters instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not able to related this to this implementation of this function. Is this supposed to be about the next function?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. Its related to the lookup logic in  extensionReceiverParameterIndex() , not the getter specifically.
Should we change it to:

// Re-add accessor for the extensionReceiver property removed in Kotlin 2.4.0.extensionReceiver property.                                                                                                                                                             
val IrMemberAccessExpression<*>.codeQlExtensionReceiver: IrExpression? {

and

   // 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? {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would make sense to me. If you're changing this, it's probably best if you also address https://github.com/github/codeql/pull/21970/files#r3434446772

private fun IrMemberAccessExpression<*>.extensionReceiverParameterIndex(): Int? {
// Direct function owner (IrCall, IrFunctionReference, etc.)
(symbol.owner as? IrFunction)?.codeQlExtensionReceiverParameter?.let {
return it.indexInParameters

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is me being naive about Kotlin: where is it coming from?

@andersfugmann andersfugmann Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kotlin automatically binds 'it' to ....codeQlExtensionReceiverParameter inside the let { ... } construct when evaluating the body when its not null.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chould make it more explicit by changing it to

private fun IrMemberAccessExpression<*>.extensionReceiverParameterIndex(): Int? {
    // Direct function owner (IrCall, IrFunctionReference, etc.)
    (symbol.owner as? IrFunction)?.codeQlExtensionReceiverParameter?.let {
         extensionReceiverParameter -> return extensionReceiverParameter.indexInParameters
   }

to increase readability

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine as it is. I would only change it if it were uncommon Kotlin idiom, but I doubt that's the case.

Comment on lines +7 to +13
fun parameterIndexExcludingReceivers(vp: IrValueParameter): Int {
val offset =
(vp.parent as? IrFunction)?.let { f ->
f.parameters.count { it.kind == IrParameterKind.DispatchReceiver || it.kind == IrParameterKind.ExtensionReceiver || it.kind == IrParameterKind.Context }
} ?: 0
return vp.indexInParameters - offset
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this is not in IrCompat.kt?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not particular reason. I'd have to ask the LLM.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking futher, I think it could very well be rolled into IrCompat.kt to reduce number of files.

@@ -1,5 +1,5 @@
{
"markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 2.3.30.",
"markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 2.4.10.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's probably a better place to comment on this, but given what I read here about Kotlin release numbering, would it make sense to just allow anything below 2.5.0?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have an opinion on that tbh. It's following the existing pattern that has been used for previous kotlin updates.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine. I'm just wondering out loud here, and this is not something we necessarily need to address here.

@github github deleted a comment from jketema Jun 18, 2026
Comment thread java/kotlin-extractor/BUILD.bazel

@jketema jketema left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We generally do not leave empty lines between imports in integration tests.

Comment on lines 1 to +3
import pathlib

import pytest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import pathlib
import pytest
import pathlib
import pytest

Comment on lines 1 to +3
import commands

import pytest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import commands
import pytest
import commands
import pytest

Comment on lines 1 to +3
import commands

import pytest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import commands
import pytest
import commands
import pytest

Comment on lines 1 to +3
import commands

import pytest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import commands
import pytest
import commands
import pytest

Comment on lines 1 to +3
import commands

import pytest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import commands
import pytest
import commands
import pytest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants