Files
codeql/java/ql/test-kotlin1
Anders Fugmann f8f1472641 Kotlin: span assignment-desugared setter calls through the assigned value
An assignment to a property, delegated property or `@JvmStatic` property
(`lhs = rhs`) desugars to a setter call. The two frontends anchor that
synthesised call differently:

  - K1 records the call (and its synthetic implicit-`this` receiver and any
    synthetic reflection arguments) at the assignment's left-hand side only
    (`varResource0 = 3` -> `37:9:37:20`, `curValue = value` -> `29:17:29:24`).
  - K2 spans the whole assignment, through the assigned value
    (`37:9:37:24`, `29:17:29:32`).

The setter call *is* the desugaring of the whole assignment, so K2's
whole-assignment span is the more intuitive, information-preserving one: it keeps
the call on the source construct it represents rather than dropping the
right-hand side. This matches the existing array-`set` EQ-origin widening
precedent, which already widens K1 onto the whole-assignment span.

We converge K1 onto the K2 span with a scoped offset remap set only while
extracting the setter call, keyed on the call's exact offset pair. Because the
compiler gives the synthetic implicit-`this` receiver and the synthetic
reflection arguments the same offsets as the call, the single remap widens them
along with the `MethodCall` node, while real source arguments (the assigned
value itself, e.g. the `2` / `3` / `value`) keep their own offsets and are
unaffected. The remap fires only for an `IrStatementOrigin.EQ` call whose last
value argument (the assigned value) ends past the call's own end offset, so it is
a no-op under K2 (where the call already spans the assigned value) and for every
non-assignment call.

Tradeoff: the direction is fixed (K1 -> K2) because K1 cannot, from its raw IR,
recover the whole-assignment span for these synthetic children; K2 produces it
natively. That is acceptable here because the whole-assignment span is the more
correct one on the merits and is already the established convention for array
`set`.

Expected updates (K1 only; K2 already emitted these):
  - library-tests/exprs/exprs.expected (delegated + direct property setters)
  - library-tests/generic-instance-methods/test.expected (setStored)
  - library-tests/jvmstatic-annotation/test.expected (@JvmStatic setters)

Both suites relearned; all tests pass. Divergence 798 -> 758 rows.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 86bfc022-3ecc-4746-ba23-3b76c4e4c3e4
2026-07-14 22:35:07 +02:00
..