module

Noir::TreeSitterMicronautExtractor

Tree-sitter-backed Micronaut route + parameter extractor.

Walks @Controller-annotated classes and emits one route per method-level verb annotation. Recognises:

  • Class-level @Controller("/x") — joined onto each method's path with a single / separator.
  • Class-level @ServerWebSocket("/x") — surfaced as GET with protocol = "ws".
  • Verb annotations: @Get, @Post, @Put, @Delete, @Patch, @Head, @Options, @Query from io.micronaut.http.annotation, plus @CustomHttpMethod(method = "...") for non-standard verbs.
  • Path supplied positionally (@Get("/x")) or via the value / uri / uris keyword. Array forms (uris = {"/a", "/b"}) fan out into one route per path.
  • @Consumes(MediaType.APPLICATION_*) at class or method level — method-level wins. Same form/json detection shape as the Spring + JAX-RS extractors.
  • Parameter annotations:
    • @PathVariable (skipped — URL carries it)
    • @QueryValue("name") — query
    • @Header("X-Foo") — header
    • @CookieValue("name") — cookie
    • @Part("name") — multipart form
    • @RequestBean — query bean fields
    • @Body — explicit request body
  • Un-annotated, non-primitive parameters — treated as the request body (Micronaut's implicit convention) and expanded against the caller-supplied DTO index.

Out of scope for this first cut: meta-annotations, @Filter, @Produces (response type, not input), @RequestAttribute.

Constants

FORM_FILE_PARAM_TYPES = Set {"completedfileupload", "streamingfileupload", "completedpart", "partdata"}
HTTP_VERB_ANNOTATIONS = {"Get" => "GET", "Post" => "POST", "Put" => "PUT", "Delete" => "DELETE", "Patch" => "PATCH", "Head" => "HEAD", "Options" => "OPTIONS", "Query" => "QUERY"}
INJECTED_PARAM_TYPES = Set {"authentication", "httprequest", "httpheaders", "pageable", "principal", "x509authentication", "httpparameters", "cookies", "basicauth"}
PARAM_ANNOTATION_FORMAT = {"QueryValue" => "query", "Header" => "header", "CookieValue" => "cookie", "Part" => "form"}
PRIMITIVE_TYPES = Set {"boolean", "byte", "char", "short", "int", "long", "float", "double", "void", "string", "object", "integer", "character"}
REACTIVE_BODY_WRAPPER_TYPES = Set {"mono", "single", "maybe", "flowable", "observable", "flux", "publisher", "completablefuture", "optional"}

Single-argument reactive/async/optional wrappers that Micronaut unwraps transparently when binding @Body (and implicit-body) parameters — e.g. @Body Mono<Book> book carries the same wire-level fields as @Body Book book. Resolving through these lets DTO expansion see the real element type instead of the wrapper's bare name.

Instance methods

extract_controller_interface_implementations(source : String) : Array(ControllerInterfaceImplementation)
Source
extract_controller_interface_implementations_from(root : LibTreeSitter::TSNode, source : String) : Array(ControllerInterfaceImplementation)
Source
extract_interface_routes(source : String, dto_index : Hash(String, Array(TreeSitterJavaParameterExtractor::FieldInfo)) = {} of String => Array(TreeSitterJavaParameterExtractor::FieldInfo), *, include_callees : Bool = false) : Hash(String, Array(Route))
Source
extract_interface_routes_from(root : LibTreeSitter::TSNode, source : String, dto_index : Hash(String, Array(TreeSitterJavaParameterExtractor::FieldInfo)) = {} of String => Array(TreeSitterJavaParameterExtractor::FieldInfo), *, include_callees : Bool = false) : Hash(String, Array(Route))
Source
extract_routes(source : String, dto_index : Hash(String, Array(TreeSitterJavaParameterExtractor::FieldInfo)) = {} of String => Array(TreeSitterJavaParameterExtractor::FieldInfo), *, include_callees : Bool = false) : Array(Route)
Source

Nested types