Noir::KotlinCalleeExtractor
Tree-sitter-backed Kotlin 1-hop callee extractor. Parallels
Noir::JavaCalleeExtractor for JVM analyzers — both Spring (Kotlin)
and Ktor route through this module. Kotlin's call_expression
wraps either a simple_identifier (bare call), a
navigation_expression (a.b.c selector chain, optionally rooted on
this/super), or an inner call_expression (the foo(...) { }
trailing-lambda shape). 1-hop extraction reduces to:
- For Spring Kotlin: find the (class_name, method_name)
function_declarationin the already-parsed root and walk itsfunction_body. - For Ktor: walk the verb DSL call's lambda
statementsnode. - For each
call_expression, reconstruct a textual callee:foo()→fooservice.save(x)→service.savethis.foo()→this.foosuper.foo()→super.fooFoo.bar()(static) →Foo.bargetFoo().bar()→ "" (chained on a call — outer dropped as noise, innergetFoostill emitted via the recursive walk)
Cross-file definition resolution (e.g. userService.save →
UserServiceImpl.save in another file) is intentionally out of
scope for this first cut. Callee#path therefore points at the
call site, matching the honest scope on every other analyzer.
Constants
Routing DSL verbs + scoping helpers. When skip_routing is on
(Ktor handler body), a call_expression whose root name is in
this set is treated as a NESTED ROUTE — we skip both emitting it
and descending into its trailing lambda so the nested route's
callees don't leak into the parent route's list.
Instance methods
Ktor / http4k entry: given a handler body node, return every
1-hop callee inside it. skip_routing controls whether Ktor's
routing DSL (route { ... }, sibling verb calls, etc.) is
treated as a NESTED ROUTE boundary — Ktor needs this on so a
nested route's callees don't leak into the parent; http4k uses
an entirely different routing idiom ("/x" bind GET to h) and
turns the skip off so a real handler call named get isn't
silently dropped.
Spring Kotlin entry: find the (class_name, method_name)
function_declaration in root and return every 1-hop
call_expression callee inside its body as
{name, file_path, file_line_1_based}. Empty array when the
function can't be located or its body is missing.