Repository navigation
feat(scanner): add a Kotlin scanner - #124
matteocodogno wants to merge 12 commits into
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The parser rejected a file starting with a UTF-8 byte order mark, which failed the whole scan. The mark is replaced by a space, as carriage returns already are, so offsets and lines still refer to the file on disk. Refs: TASK-576 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The outline kept the backticks of a quoted identifier while scan symbols and operations report the unquoted name, so a Code link written with the symbol name never marked its outline entry. The outline now reports the same name as scans. Refs: TASK-576 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… too deep A long generated chain overflowed the stack in the recursive call walk and the scan died with a raw JVM trace naming no file. The adapter now starts the worker with a 512 MB stack, and a file nested deeper than that fails the scan by name like any other unreadable file. Refs: TASK-576 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The default exclusion build/ also dropped real source in a package directory named build, such as com.android.build. The defaults now restore a build folder under a source set's kotlin/ or java/ root, where it is a package and never Gradle output. Refs: TASK-576 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The default src/*Test/ missed src/testDebug/, src/androidTestDebug/ and src/testFixtures/, so their test code was scanned as product code although the documentation says test source sets are excluded. The defaults now also name a test source set followed by a capitalised variant. Refs: TASK-576 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One observation covers every selected file at about 115 bytes per source line, so a repository of roughly a million lines exceeded the 64 MB buffer and the scan was rejected. The adapter now reads the worker's output without a fixed limit. Refs: TASK-576 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A secondary constructor searched its whole declaration for calls while a function searched only its body, so a call in a parameter default was evidence for one and not the other. A function now searches its whole declaration too, because it runs its defaults. Refs: TASK-576 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A mutable var with a lambda initializer was reported as a function symbol and operation, which showed reassignable state as a fixed function. Only a val is a function value now. Refs: TASK-576 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The build shipped whatever Maven Central returned for the pinned versions, so a truncated or altered jar would still be published. Each artifact now carries the SHA-256 of the reviewed jar, matched against Maven Central's published SHA-1 for the same bytes, and a download that differs fails the build. Refs: TASK-576 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Kotlin adapter and build were near copies of the Scala scanner's, and the notices writer existed in three build scripts. plugins/scanners/jvm-worker.ts now owns running a worker on the bundled Java runtime and mapping its outline to Code entries for Kotlin and Scala. plugins/scanners/jvm-package.ts owns package assembly for both, and the notices writer and JDK tool lookup the Java build also uses. The shared runner has no fixed output limit, so the Scala adapter loses its 64 MB limit too. The worker module joins the Scala scanner component; the build helper is excluded from the architecture scan like the other build scripts. Refs: TASK-576 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
f6a58dd to
d4d7faf
Compare
|
Hey @MrLesk @matteocodogno, sorry to post an unrelated question but it's the only way I found to contact you, I would love to raise an issue but I see it's turned off for this repo, is this intentional? the README showed links to the /issues page but when landing there I see "Issue creation is restricted in this repository" below the "Issues" button...
|
Sorry about that @evertdhont |


Backlog task: TASK-576 - Add an experimental Kotlin scanner (
backlog/tasks/task-576 - Add-an-experimental-Kotlin-scanner.md).What this adds
groma scanner add @groma/scanner-kotlin, thengroma scan.The package (
plugins/scanners/kotlin) follows the Scala scanner's delivery: a TypeScript entry and adapter run a bundled worker on a bundled Java runtime. The worker is written in Kotlin and parses withkotlin-compiler-embeddable2.4.21 (parse only: no analysis, classpath, Gradle or Maven). Scanning needs no installed JDK, Kotlin compiler, build or network. A parse or read failure rejects the whole observation and names the file.It is registered in the official catalog and the scanner release assembly beside Scala, and documented in
docs/scanners/kotlin/index.md. No new scan flow is introduced, so there is no new Gherkin scenario; the approved example is the fixturetest/fixtures/kotlin-source.Out of scope: HTTP facts, Gradle/Maven module discovery, Kotlin scripts (
.kts), body fingerprints.Kotlin-specific rules worth a look
Orders.create).constructor; a primary constructor is an outline member but not an operation.build/,.gradle/,**/src/test/and**/src/*Test/(the**/prefix is needed because an inner-slash pattern is otherwise anchored at the repository root, which would scan tests in every Gradle module).Checks
Run on macOS arm64 with Bun 1.4.2 and JDK 25:
test-bun/kotlin-scanner.test.ts(builds an isolated package): passes.test-bun/scanner-fresh-checkout.test.tsforkotlinagainst the built package (empty home, only git onPATH): passes.test-bun/scanner-release.test.ts: passes.bun run check: lint (existing findings only) and typecheck pass; Node 16/16; Bun 771 pass, 52 skip, 6 fail. All six are Swift scanner tests failing atswiftcwithno such module 'SwiftParser'on my machine (Command Line Tools without swift-syntax). None involves Kotlin; CI should confirm.Not run: Linux and Windows hosts, and the multi-host release assembly with real artifacts.
Known limitations and decisions for the maintainer
javax.swing.Icon, so the jlinked runtime needsjava.desktop: about 78 MB per host (about 24 MB compressed), plus 59 MB of compiler jars shared by all hosts. Estimated about 175 MB compressed for five hosts, below the 214.6 MB C# archive that was rejected but not by much. A stubjavax.swing.Iconon ajava.base-sized runtime also parsed correctly in a spike (about 120 MB total) but was not adopted; say if you prefer it or a per-host split.KotlinCoreEnvironment, which requires opt-ins and is marked by JetBrains as planned for rework, so a compiler upgrade may need worker changes.overridewithout a modifier reads aspubliceven when it inheritsprotected.kotlin-src-index(Kotlin source scanner), in the CLI container's Language scanners group.This is a fork PR, so the Groma architecture comparison needs a manual run.
🤖 Generated with Claude Code