mirror of
https://github.com/github/codeql.git
synced 2026-07-12 15:05:33 +02:00
The K1 and K2 frontends record different source locations for the
compiler-synthesised primary constructor of a class that declares no primary
constructor in source. K2 uses the class declaration's raw IR offsets, which
include any leading modifier keywords, while K1's raw offsets start at the
`class` keyword and omit the modifiers.
Since K1 (unlike K2) retains the PSI, we recover the modifier-inclusive span
from the enclosing KtClassOrObject so K1 matches the K2-native span.
Example, for `open class C0<V> {}` on line 11 (the `open` modifier is at
column 1, the `class` keyword at column 6):
before (K1): generics.kt:11:6:11:19 | C0 | C0()
after (K1): generics.kt:11:1:11:19 | C0 | C0() (matches K2)
The fix is deliberately narrow and leaves all other constructors untouched:
- explicit primary constructors (`class C1(val t: T)`, `class C2()`) keep
their own parameter-list location, which both frontends already agree on;
- explicit secondary constructors keep their own location (only the
`isPrimary` constructor is adjusted);
- specialised/parameterised copies of a generic constructor
(`typeSubstitution != null`) are excluded, so they do not gain a spurious
source location and appear in source-filtered queries.
Relearned test-kotlin1 (K1) and test-kotlin2 (K2): all 3333 tests pass with
database-consistency checks. Only test-kotlin1 expected files change (K2 output
is unchanged, as K2 already emits these spans natively). No previously matching
row diverges; net K1-vs-K2 divergence decreases on every affected file, with
generics, generic-inner-classes and modifiers now fully identical.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>