module
Noir::TreeSitterKotlinRouteExtractor
Overview
Tree-sitter-backed Kotlin route extractor.
Scope for this first cut: Spring-style annotation routing —
class-level @RequestMapping-family annotations composing with
method-level mapping annotations. Mirrors TreeSitterJavaRouteExtractor
but for Kotlin's distinct AST shape (annotations live in
modifiers, functions use function_declaration, primary
constructors carry DTO fields, etc.).
Covered:
@GetMapping,@PostMapping,@PutMapping,@DeleteMapping,@PatchMapping— each fixes the HTTP verb@RequestMapping— generic; verb frommethod = RequestMethod.X(single or array form), or GET when absent- Class-level mapping annotations contribute a prefix joined
onto the per-method path with exactly one
/separator - Path supplied positionally (
@GetMapping("/x")) or viavalue = "/x"/path = "/x"keyword arguments, including string arrays (value = ["/a", "/b"]) - Multi-line annotations — the grammar eats whitespace for us
Not covered yet (follow-ups):
- Ktor's DSL
routing { get("/x") { ... } }. That's a different authoring style and lives in a separate walker. - Meta-annotations (custom annotations composing
@RequestMapping).
Extended Modules
Defined in:
miniparsers/kotlin_route_extractor_ts.crConstant Summary
-
ANNOTATION_VERBS =
{"GetMapping" => "GET", "PostMapping" => "POST", "PutMapping" => "PUT", "DeleteMapping" => "DELETE", "PatchMapping" => "PATCH", "RequestMapping" => nil} -
Spring mapping annotation names → HTTP verb.
nilmeans look at the annotation'smethod =argument. Same table as the Java extractor for consistency.
Instance Method Summary
-
#expand_constant_interpolations(constants : Hash(String, String)) : Hash(String, String)
Resolve Kotlin string-template interpolations inside collected constant values, e.g.
- #extract_controller_interface_implementations_from(root : LibTreeSitter::TSNode, source : String, string_constants = Hash(String, String).new, local_string_constants : Hash(String, String) | Nil = nil) : Array(ControllerInterfaceImplementation)
- #extract_graphql_routes_from(root : LibTreeSitter::TSNode, source : String, string_constants = Hash(String, String).new, local_string_constants : Hash(String, String) | Nil = nil) : Array(GraphqlRoute)
- #extract_interface_routes_from(root : LibTreeSitter::TSNode, source : String, string_constants = Hash(String, String).new, local_string_constants : Hash(String, String) | Nil = nil) : Hash(String, Array(Route))
- #extract_routes(source : String, string_constants = Hash(String, String).new) : Array(Route)
-
#extract_routes_from(root : LibTreeSitter::TSNode, source : String, string_constants = Hash(String, String).new, local_string_constants : Hash(String, String) | Nil = nil) : Array(Route)
_from(root, source)— accept a pre-parsed root so the Kotlin Spring analyzer can amortise the parse across multiple extractions on the same file. - #extract_stomp_application_prefixes(source : String, string_constants = Hash(String, String).new, local_string_constants : Hash(String, String) | Nil = nil) : Array(String)
- #extract_stomp_routes_from(root : LibTreeSitter::TSNode, source : String, string_constants = Hash(String, String).new, local_string_constants : Hash(String, String) | Nil = nil, application_prefixes = [""]) : Array(Route)
- #extract_string_constants(source : String) : Hash(String, String)
Instance Method Detail
Resolve Kotlin string-template interpolations inside collected
constant values, e.g. const val STATIC_URL = "$PUBLIC_URL/static"
with PUBLIC_URL = "/public" becomes /public/static. The regex
capture in #extract_string_constants stores the raw $PUBLIC_URL
text, so without this a path built from such a constant keeps the
literal $VAR (or, as an inline annotation literal, mis-parses it
as a {VAR} path placeholder). Unresolved references (e.g. Spring
${config.property} placeholders) are left untouched. Bounded
iterations resolve transitive chains.
_from(root, source) — accept a pre-parsed root so the Kotlin
Spring analyzer can amortise the parse across multiple
extractions on the same file. Tree lifetime is the caller's
responsibility.