Skip to content

Kotlin: Add support for Kotlin 2.4.0#21952

Draft
andersfugmann wants to merge 10 commits into
mainfrom
andersfugmann/kotlin-2.4
Draft

Kotlin: Add support for Kotlin 2.4.0#21952
andersfugmann wants to merge 10 commits into
mainfrom
andersfugmann/kotlin-2.4

Conversation

@andersfugmann

Copy link
Copy Markdown
Contributor

Summary

Adds support for Kotlin 2.4.0 to the CodeQL Kotlin extractor. This follows the established two-phase upgrade process documented in java/kotlin-extractor/UPGRADING.md.

Changes

Phase 1 — Version limit

  • Raised the supported version ceiling from 2.3.30 to 2.4.10
  • Updated documentation (supported-versions-compilers.rst)

Phase 2 — API compatibility

  • Downloaded 2.4.0 compiler jars (LFS)
  • Created compatibility layer (v_2_4_0/IrCompat.kt) for the unified parameters model:
    • valueParametersparameters.filter { it.kind == Regular }
    • extensionReceiverParameterparameters.firstOrNull { it.kind == ExtensionReceiver }
    • getValueArgument(i) / putValueArgument(i, v) → offset-adjusted arguments[i + offset]
  • Migrated plugin registration to CompilerPluginRegistrar (service file is version-conditional in BUILD.bazel)
  • Fixed annotation creation to use IrAnnotationImpl.fromSymbolOwner() (2.4.0 type hierarchy change)

Test expectations

  • Updated exprs and reflection library test expectations for IrRichPropertyReference — a new IR node in 2.4.0 for bound callable references that is not yet handled by the extractor

Known limitations (follow-up PR)

Kotlin 2.4.0 introduces IrRichFunctionReference and IrRichPropertyReference nodes for bound callable references. The extractor does not yet visit these nodes, resulting in slightly reduced extraction coverage for bound property/function references. This causes:

  • 2 CONSISTENCY callArgs entries (parameter count mismatch on unhandled bound refs)
  • ~13 fewer extracted sub-expressions in delegated property references

This will be addressed in a dedicated follow-up PR.

Testing

  • CI "Check Kotlin versions" workflow: all versions 1.8.0–2.4.0 pass ✅
  • Local language-tests-2 (20 slices, 3,398 tests): all pass ✅
  • Backward compatibility: versions 1.8.0–2.3.21 unaffected ✅

andersfugmann and others added 6 commits June 4, 2026 12:58
Raise the acceptable version limit to 2.4.10 and update documentation
to reflect Kotlin 2.4.x support.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Download kotlin-compiler-2.4.0.jar, kotlin-compiler-embeddable-2.4.0.jar,
and kotlin-stdlib-2.4.0.jar from Maven Central. Add 2.4.0 to the VERSIONS
list and update MODULE.bazel via bazel mod tidy.

The extractor does not yet compile against 2.4.0 due to removed APIs
(valueParameters, extensionReceiverParameter, getValueArgument, etc.).
Version-specific compatibility shims are needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add version-specific compatibility wrappers (v_2_4_0/IrCompat.kt) for
  removed APIs: valueParameters, extensionReceiverParameter, extensionReceiver,
  getValueArgument, putValueArgument, valueArgumentsCount, typeArgumentsCount,
  getTypeArgument, addAnnotations, setAnnotations, setDispatchReceiverParameter
- Add pre-2.4.0 pass-through implementations (v_1_8_0/IrCompat.kt)
- Migrate plugin registration from ComponentRegistrar to CompilerPluginRegistrar
  for 2.4.0 (v_2_4_0/Kotlin2ComponentRegistrar.kt)
- Add META-INF service file for CompilerPluginRegistrar
- Update all extractor source files to use codeQl* compat functions
- All versions (1.8.0 through 2.4.0) build successfully

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The CompilerPluginRegistrar service file must only be included in the
2.4.0 jar. Older Kotlin versions (2.3.x and below) read this service
file and try to cast the class to CompilerPluginRegistrar, but the
older version extractor only implements ComponentRegistrar, causing a
ClassCastException at runtime.

For 2.4.0, the registrar implements both ComponentRegistrar (no-op, as
extensionArea was removed) and CompilerPluginRegistrar (actual
registration via ExtensionStorage).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
In 2.4.0, IrMemberAccessExpression.arguments includes all parameters
(dispatch receiver, extension receiver, and regular value args). The
old getValueArgument/putValueArgument/valueArgumentsCount APIs indexed
only value arguments. Fix the compat layer to apply the correct offset
when translating between the old index-based API and the new unified
arguments list.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
In 2.4.0, annotation lists are typed as List<IrAnnotation> and
IrConstructorCallImpl does not extend IrAnnotation. Replace all
IrConstructorCallImpl.fromSymbolOwner() calls that create annotations
with a compat wrapper codeQlAnnotationFromSymbolOwner() that uses
IrAnnotationImpl.fromSymbolOwner() in 2.4.0 (returning proper
IrAnnotation instances) and IrConstructorCallImpl.fromSymbolOwner()
in pre-2.4.0 versions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@andersfugmann

andersfugmann commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up: Handle IrRichFunctionReference (minor)

Kotlin 2.4.0 introduces two new IR nodes for bound callable references.

Update: The IrRichPropertyReference issue was a red herring. The actual bug was that our codeQlExtensionReceiver compat function did not handle IrPropertyReference (where symbol.owner is IrProperty, not IrFunction). Fixed in the latest commit — no test expectation changes needed, full extraction parity maintained.

The IrRichFunctionReference and IrRichPropertyReference nodes are introduced in a later lowering phase (JVM backend) — they do NOT appear in the IR that reaches our IrGenerationExtension. Our plugin sees the pre-lowered IrPropertyReference/IrFunctionReference nodes with bound receivers stored in the unified arguments list.

Remaining (truly minor) follow-up

No follow-up PR is currently needed. All 3,398 kotlin2 language tests pass with the original expected files. If future Kotlin versions change when rich references appear in the pipeline, we may need to revisit.

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>
@andersfugmann andersfugmann force-pushed the andersfugmann/kotlin-2.4 branch from 86af0c8 to 5732a99 Compare June 8, 2026 09:51
andersfugmann and others added 3 commits June 8, 2026 15:02
Kotlin 2.4.0 no longer supports -language-version 1.9 (the last 1.x
version). Clamp get_language_version() in versions.bzl to minimum 2.0
for extractor builds, and update the supported versions documentation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…l query style

- Fix BUILD.bazel formatting (buildifier line wrapping)
- Fix change-note category: 'deprecation' -> 'deprecated'
- Replace unsafe list casts with filterIsInstance to satisfy
  the possiblyThrowingExpressions internal query

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Kotlin 2.4.0 no longer supports -language-version 1.9. Update all
integration tests that explicitly pass this flag to use 2.0 instead.
Also update the extractor_information_kotlin1 expected output since
-language-version 2.0 causes the extractor to report 'Uses Kotlin 2: true'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@andersfugmann andersfugmann force-pushed the andersfugmann/kotlin-2.4 branch from 0117e40 to f3037d6 Compare June 8, 2026 14:25
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.

1 participant