feat: kotlin (Spring + Ktor) structural support#93
Conversation
📝 WalkthroughWalkthroughAdds structural Kotlin support: wires tree-sitter-kotlin, recognizes ChangesKotlin Structural Scanner Support
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Summary
This PR successfully adds Kotlin structural support to the scanner with comprehensive coverage of Spring Security and Ktor frameworks. The implementation is thorough and well-tested.
Key Additions:
- ✅ Parser integration with
tree-sitter-kotlin-ngv1.1 - ✅ File discovery for
.ktand.ktsextensions in both structural and deep scan modes - ✅ 8 high-confidence Kotlin rules covering Spring Security (@PreAuthorize, @secured, @RolesAllowed, hasRole/hasAuthority calls, role checks) and Ktor (authenticate blocks, plugin installation)
- ✅ All rules properly embedded in
src/rules/embedded.rs - ✅ Comprehensive test coverage: 17 matcher tests + 1 dedup test, 18 inline rule-TOML tests
- ✅ Real-world corpus validation (ktor-samples: 13 findings, 0 false positives)
Implementation Quality:
The Kotlin integration follows established patterns from Java/C# language additions. The annotation handling using (^|\.)Annotation$ regex on user_type captures is a clever solution to handle both bare and fully-qualified annotation forms in a single rule, avoiding duplicate matches. Tests demonstrate proper handling of edge cases like multi-string @Secured("A", "B") with deduplication.
No blocking issues found. The code is ready to merge.
You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@rules/kotlin/role-equals-check.toml`:
- Around line 10-17: The matcher currently captures any binary_expression with a
navigation_expression identifier (`@prop`) and a string_literal (`@role_value`) but
doesn't constrain the operator, causing false positives for !=; update the query
in rules/kotlin/role-equals-check.toml to require the equality operator by
adding an operator constraint to the binary_expression (e.g. specify operator:
"==") so the pattern only matches expressions using == (keep the existing
navigation_expression/identifier `@prop` and string_literal `@role_value` bindings).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 6c88411b-5c97-411e-aaa2-a781d1324780
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (19)
AGENTS.mdCargo.tomlREADME.mddocs/DESIGN.mddocs/corpus/README.mddocs/corpus/kotlin.mdrules/kotlin/has-role-call.tomlrules/kotlin/ktor-authenticate-block.tomlrules/kotlin/ktor-install-authentication.tomlrules/kotlin/role-collection-contains.tomlrules/kotlin/role-equals-check.tomlrules/kotlin/roles-allowed.tomlrules/kotlin/spring-preauthorize.tomlrules/kotlin/spring-secured.tomlsrc/deep/candidate.rssrc/rules/embedded.rssrc/scanner/discovery.rssrc/scanner/matcher.rssrc/scanner/parser.rs
Adds Kotlin to the structural scanner: tree-sitter-kotlin-ng grammar, discovery for .kt/.kts, and eight rules covering Spring Security (@PreAuthorize, @secured, @RolesAllowed, hasRole/hasAuthority calls, inline role equality, role-collection membership) plus Ktor (authenticate {} blocks and install() of auth-adjacent plugins). Includes a ktor-samples corpus run in docs/corpus/kotlin.md (13 structural findings, no false positives).
Without the operator constraint, the binary_expression query matched any operator (==, !=, ===, etc.), causing false positives on user.role != "admin". Pin the field to == and add negative tests for the != case at both the rule-TOML and matcher layer.
d091b12 to
eacb96b
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
rules/kotlin/spring-secured.toml (1)
46-71: ⚡ Quick winAdd a multi-role
@Securedtest to lock in the behavior described in comments.Lines 7-11 describe handling multi-role annotations (e.g.,
@Secured("A", "B")), but current tests only cover single-role inputs. Add one test with multiple role strings so this behavior doesn’t regress silently.Suggested test addition
[[rule.tests]] input = """ class UserController { `@org.springframework.security.access.annotation.Secured`("ROLE_ADMIN") fun deleteUser(id: Long) { } } """ expect_match = true +[[rule.tests]] +input = """ +class UserController { + `@Secured`("ROLE_ADMIN", "ROLE_AUDITOR") + fun deleteUser(id: Long) { } +} +""" +expect_match = true + [[rule.tests]] input = """ class UserController { `@Override` fun deleteUser(id: Long) { } } """ expect_match = false🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@rules/kotlin/spring-secured.toml` around lines 46 - 71, The test suite for the Secured rule lacks a case covering multi-role annotations, so add a new [[rule.tests]] block in rules/kotlin/spring-secured.toml containing an input that uses `@Secured` with multiple role strings (e.g., `@Secured`("ROLE_A", "ROLE_B")) and set expect_match = true to lock in the described multi-role handling; place it alongside the existing [[rule.tests]] entries that use `@Secured` and fully-qualified `@org.springframework`...Secured to ensure the rule continues to match multi-role annotations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@rules/kotlin/spring-secured.toml`:
- Around line 46-71: The test suite for the Secured rule lacks a case covering
multi-role annotations, so add a new [[rule.tests]] block in
rules/kotlin/spring-secured.toml containing an input that uses `@Secured` with
multiple role strings (e.g., `@Secured`("ROLE_A", "ROLE_B")) and set expect_match
= true to lock in the described multi-role handling; place it alongside the
existing [[rule.tests]] entries that use `@Secured` and fully-qualified
`@org.springframework`...Secured to ensure the rule continues to match multi-role
annotations.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 10a8faf0-fa4b-4183-b90d-69d14d22c016
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (19)
AGENTS.mdCargo.tomlREADME.mddocs/DESIGN.mddocs/corpus/README.mddocs/corpus/kotlin.mdrules/kotlin/has-role-call.tomlrules/kotlin/ktor-authenticate-block.tomlrules/kotlin/ktor-install-authentication.tomlrules/kotlin/role-collection-contains.tomlrules/kotlin/role-equals-check.tomlrules/kotlin/roles-allowed.tomlrules/kotlin/spring-preauthorize.tomlrules/kotlin/spring-secured.tomlsrc/deep/candidate.rssrc/rules/embedded.rssrc/scanner/discovery.rssrc/scanner/matcher.rssrc/scanner/parser.rs
✅ Files skipped from review due to trivial changes (5)
- AGENTS.md
- src/deep/candidate.rs
- docs/DESIGN.md
- README.md
- docs/corpus/kotlin.md
🚧 Files skipped from review as they are similar to previous changes (13)
- Cargo.toml
- docs/corpus/README.md
- rules/kotlin/role-collection-contains.toml
- rules/kotlin/ktor-install-authentication.toml
- rules/kotlin/role-equals-check.toml
- rules/kotlin/ktor-authenticate-block.toml
- rules/kotlin/has-role-call.toml
- src/scanner/parser.rs
- src/rules/embedded.rs
- rules/kotlin/roles-allowed.toml
- rules/kotlin/spring-preauthorize.toml
- src/scanner/matcher.rs
- src/scanner/discovery.rs
Summary
Adds Kotlin to the structural scanner — eight rules covering Spring Security and Ktor, the
tree-sitter-kotlin-nggrammar wired through the parser, and.kt/.ktsdiscovery.Changes
tree-sitter-kotlin-ng = 1.1added;Language::Kotlinwired throughget_language,detect_language, anddetect_language_for_deep;.kt+.ktsextensions resolve to Kotlin.rules/kotlin/, 8 rules, allconfidence = "high"):@PreAuthorize,@Secured,@RolesAllowed,hasRole/hasAuthoritycall,user.role == "...",user.roles.contains(...)authenticate("name") { ... }/authenticate { ... }route guards (middleware),install(Authentication)/install(Sessions)plugin registration (middleware)(^|\.)Annotation$regex on a singleuser_typecapture to handle both bare and fully-qualified annotation forms in one rule (Kotlin's tree-sitter flattens dotted annotation paths).src/rules/embedded.rs): all 8 Kotlin rules registered in the embedded set.@Secured("A", "B"); 18 new inline rule-TOML tests. Full suite green: 442 lib tests + 424 inline rule tests pass.docs/corpus/kotlin.md—ktor-samples(commitc89f051e, 204 .kt/.kts files, 12,254 LOC) yields 13 structural findings (7authenticate {}, 6install()) with no false positives. Spring-Kotlin rules need a separate corpus target.README.md,AGENTS.md,docs/DESIGN.mdupdated to reflect Kotlin shipping in v0.2 (was previously listed as planned).Testing
Manual corpus reproduction:
Notes
feat:per CLAUDE.md's versioning table — this rolls into the next 0.2.x patch (not a 0.2.0 cut). Usefeat!:when cutting 0.2.0 deliberately.Closes #84
Summary by CodeRabbit
New Features
Documentation