module
Noir::TreeSitterPythonRouteExtractor
Overview
Tree-sitter-backed port of PythonRouteExtractor.
Unlike the regex extractor (which is line-oriented and relies on the caller to loop over lines), this one parses the whole source once and walks the resulting AST. That buys us:
- decorators split across multiple lines
- paths / methods containing commas, brackets, or nested quotes
- precise
def/classline discovery without a forward-scanning heuristic
Behaviour mirrors the regex extractor closely enough that the same
analyzer adapters could switch to it with minimal changes; parity is
verified in spec/unit_test/miniparser/python_route_extractor_ts_spec.cr.
Extended Modules
Defined in:
miniparsers/python_route_extractor_ts.crConstant Summary
-
HTTP_METHODS =
["get", "post", "put", "patch", "delete", "head", "options", "trace"] of ::String
Instance Method Summary
-
#extract_blueprints(source : String, module_names : Array(String)) : Array(BlueprintDecl)
Parses
sourceand returns everyBlueprint(...)assignment that matches one ofmodule_namesor a bareBlueprint. -
#extract_decorations(source : String, router_names : Array(String) | Nil = nil, extra_attributes : Hash(String, String) | Nil = nil) : Array(Decoration)
Parses
sourceand returns every route decoration found.
Instance Method Detail
Parses source and returns every Blueprint(...) assignment that
matches one of module_names or a bare Blueprint.
module_names is the list of module prefixes allowed before
.Blueprint (e.g. ["flask"]). A bare Blueprint call is always
accepted, matching the regex extractor.
Uses a tree-sitter query to find the two Blueprint assignment
shapes (bare and module-qualified). The url_prefix keyword is
still extracted procedurally because a Blueprint may be declared
without one and the query language can't express "this keyword,
if present" cleanly.
Parses source and returns every route decoration found.
router_names optionally restricts which variable names count as
routers; nil accepts any identifier (matching the regex extractor,
which doesn't gate on the name).
extra_attributes optionally widens the set of decorator attribute
names that count as a route. Each entry maps an attribute name
(e.g. "websocket") to the HTTP method the synthesised endpoint
should carry (Quart's @app.websocket is emitted as GET so the
downstream pipeline keeps treating it as an HTTP-shaped endpoint;
the caller flips protocol = "ws" based on attribute_name).