module
Analyzer::Dart::Helper
Overview
Shared helpers for the Dart framework analyzers (Dart Frog, Shelf, Serverpod). Kept framework-agnostic so each analyzer can opt in without duplicating path/string conventions.
Extended Modules
Defined in:
analyzer/analyzers/dart/dart_helper.crConstant Summary
-
HANDLER_REFERENCE_REGEX =
/\A[A-Za-z_]\w*(?:\.[A-Za-z_]\w*)*\z/ -
Matches a bare handler reference (
_createUser,auth.handler) passed as a route's handler argument. -
SPLIT_ARGS_RULES =
Noir::TopLevelSplit::Rules.new(nest: ((Noir::TopLevelSplit::Nest::Paren | Noir::TopLevelSplit::Nest::Bracket) | Noir::TopLevelSplit::Nest::Brace) | Noir::TopLevelSplit::Nest::Angle, quotes: "\"'", escape: Noir::TopLevelSplit::Escape::InQuotes, strip: false, empties: Noir::TopLevelSplit::Empties::Keep, per_kind: true, clamp: true) -
Each bracket kind (
(),{},[],<>) gets its own counter so a generic argument (Map<String, int>) and a collection literal ([a, b]) both keep their inner commas, and string literals are skipped so a comma inside'a,b'never splits. Nothing is stripped and every part is kept, the trailing one included, so a single-argument call yields a one-element array.File-local rather than a
Rulespreset: it is the only splitter in the tree that counts<>and also keeps every part unstripped, so a central name would have exactly one user.
Instance Method Summary
-
#build_endpoint(url : String, verb : String, path : String, line : Int32, callees : Array(Noir::DartCalleeExtractor::Entry)) : Endpoint
Build an endpoint from an already-normalized URL, promoting every
{name}capture in it to a path param and attaching the callees. -
#extract_string_literal(text : String) : String | Nil
Pull the contents of a leading single/double-quoted string literal from an argument expression, honouring backslash escapes.
-
#find_matching_paren(text : String, open_idx : Int32) : Int32 | Nil
Index of the
)closing the(atopen_idx, or nil when the expression never balances. -
#first_top_level_comma(text : String, start : Int32, limit : Int32) : Int32 | Nil
Char index of the first comma at paren/brace/bracket depth zero between
startandlimit, or nil when the call has a single argument. -
#handler_callees(handler_arg : String, content : String, handler_start : Int32, path : String, line : Int32) : Array(Noir::DartCalleeExtractor::Entry)
Callees for a route's handler argument, where
handler_startis the CHAR index at which the handler expression begins (typically the char just past the first top-level comma). -
#split_top_level_args(text : String) : Array(String)
Split a call's argument list on top-level commas.
-
#strip_comments(text : String) : String
Replace
//line and/* */block comments with spaces, leaving string literals and overall byte offsets intact so downstream regex/offset logic still lines up with the original source. -
#test_path?(path : String, base_path : String | Nil = nil) : Bool
Standard Dart test-file conventions.
- #test_path?(path : String, base_paths : Array(String)) : Bool
Instance Method Detail
Build an endpoint from an already-normalized URL, promoting every
{name} capture in it to a path param and attaching the callees.
Analyzers whose endpoints carry extra state (Dart Frog's websocket
flag, dart:io HttpServer's inherited params) keep their own.
Pull the contents of a leading single/double-quoted string literal from an argument expression, honouring backslash escapes. Returns nil when the expression doesn't start with a string literal.
Index of the ) closing the ( at open_idx, or nil when the
expression never balances. String literals are skipped so a paren
inside 'a)b' doesn't close the call, and backslash escapes inside
them are honoured.
Both the argument and the result stay in CHAR space, consistent with
Regex::MatchData#begin, Analyzer#line_number_for_index and the
char_index_to_byte_index conversions the analyzers use for callee
extraction.
Char index of the first comma at paren/brace/bracket depth zero
between start and limit, or nil when the call has a single
argument.
Callees for a route's handler argument, where handler_start is the
CHAR index at which the handler expression begins (typically the
char just past the first top-level comma).
A plain function reference (_createUser, auth.handler) can't be
resolved cross-file yet, so the reference itself is recorded as the
callee.
extract_body_after scans by BYTE offset, hence the char-to-byte
conversion. It skips past the leading (req, res) lambda params to
the =>/{ body, so a trailing middleware: argument after the
body is naturally excluded.
Shelf keeps its own variant: it derives the handler start from the call's closing paren instead of a comma index, so the two are not interchangeable.
Split a call's argument list on top-level commas.
Note: Serverpod#split_top_level_commas is deliberately NOT this
method — it tracks only </( on one shared counter and is not
string-aware, matching the narrower shapes it parses. It goes through
the same shared splitter with its own Rules, so the difference is
now two constants to compare rather than two loops to diff.
Replace // line and /* */ block comments with spaces, leaving
string literals and overall byte offsets intact so downstream
regex/offset logic still lines up with the original source.
Standard Dart test-file conventions. The Dart tooling discovers
tests under a project-root test/ directory and via the
*_test.dart suffix; neither ever serves real traffic. Dart Frog
in particular mirrors the route tree under test/routes/, so a
naive /routes/ match would surface every mock handler as a live
endpoint. Centralized so every Dart analyzer can opt in via
next if Helper.test_path?(path, base_paths).
/test/,test/— Dart'sdart testdiscovery root and the Dart Frogtest/routes/mirror tree*_test.dart— the canonical Dart unit-test suffix