module
Noir::TreeSitterKotlinKtorRouteExtractor
Overview
Tree-sitter-backed Ktor DSL route extractor.
Walks the canonical Ktor server idiom:
routing {
get("/x") { ... }
route("/api") {
post("/items") { val item = call.receive < Item > () }
}
authenticate("auth-jwt") {
get("/profile") { ... }
}
}
Recognises:
- Verb DSL calls —
get/post/put/delete/patch/head/optionswith a string-literal path argument and a trailing lambda body. route("/x") { ... }blocks contributing to the path prefix.authenticate("realm") { ... }blocks acting as transparent wrappers (no prefix change). Tagging is handled elsewhere; we just descend so wrapped routes are still discovered.routing { ... }andapplication.routing { ... }entry points.- Type-safe
@Resourcerouting —get<VideoStream> { },resource<Login> { post { } },method(HttpMethod.Get) { handle<T> }— with cross-file parent-path composition. - Inside each verb's lambda body:
call.receive<T>()→bodyparameter typedTasjsoncall.parameters["name"]→nameparameter asquerycall.request.headers["name"]→nameparameter asheader
Not covered yet:
install(plugin) { ... }plugin scoping that affects routing.
Extended Modules
Defined in:
miniparsers/kotlin_ktor_route_extractor_ts.crConstant Summary
-
HTTP_VERB_NAMES =
{"get" => "GET", "post" => "POST", "put" => "PUT", "delete" => "DELETE", "patch" => "PATCH", "head" => "HEAD", "options" => "OPTIONS", "webSocket" => "GET", "webSocketRaw" => "GET", "sse" => "GET"} -
PASSTHROUGH_NAMES =
Set {"routing", "authenticate", "rateLimit", "intercept", "host", "port"} -
Pass-through DSL calls — descend into their lambda body without changing the path prefix.
routingis the entry point;authenticatewraps a sub-tree behind an auth realm; the remaining names cover the common Ktor scoping helpers.installis handled separately (seewalk) because onlyinstall(Routing)contributes routes — every other plugin config block must NOT be walked as routing.
Instance Method Summary
-
#compose_resource_paths(raws : Array(RawResource)) : Hash(String, String)
Resolve each raw resource to its full URL path.
-
#extract_resource_classes(source : String) : Array(RawResource)
Collect every
@Resource("path")-annotated class/object in a file (including nested ones, with their dotted lexical name). - #extract_routes(source : String, string_constants = Hash(String, String).new, resource_paths = Hash(String, String).new, *, include_callees : Bool = false) : Array(Route)
- #extract_string_constants(source : String) : Hash(String, String)
Instance Method Detail
Resolve each raw resource to its full URL path. The parent is the
first primary-constructor property whose type is itself a resource
(root: Root → /api); the child path joins onto it. Returns a
map keyed by BOTH the dotted lexical name (Articles.New) and the
bare simple name (TagsResource) so get<...> references resolve
either way.
Collect every @Resource("path")-annotated class/object in a file
(including nested ones, with their dotted lexical name). The
analyzer gathers these across the whole project before composing
full paths, since a resource's parent is often declared in another
module (Ktor's KMP commonMain resource definitions).