class
Analyzer::Javascript::RouterMountScanner
- Analyzer::Javascript::RouterMountScanner
- Reference
- Object
Overview
RouterMountScanner handles the two-pass scanning process for Express router mounts. It scans JavaScript/TypeScript files to discover router mount patterns like: app.use('/api', userRouter) router.use('/v1', require('./routes')) and stores the prefix information in CodeLocator for cross-file resolution.
Included Modules
Defined in:
analyzer/analyzers/javascript/express/router_mount_scanner.crConstant Summary
-
HONO_ROUTE_MOUNT_RE =
/\.route\s*\(\s*['"]([^'"]+)['"]\s*,\s*(\w+)\s*\)/ -
Hono
<chain>.route('/prefix', ChildApp)mounts. Registers the prefix on the child's file whenChildAppis an imported router, regardless of (or in the absence of) a named caller. -
JS_TO_TS_EXT =
{".js" => [".ts", ".tsx"], ".jsx" => [".tsx"], ".mjs" => [".mts"], ".cjs" => [".cts"]} -
TypeScript ESM (
moduleResolution: NodeNext) imports a sibling.tssource through a.js-family specifier. Map each JS extension to the TS source extension(s) it can stand in for, soresolve_require_pathcan fall back to the real on-disk file when the literal path is absent. -
MOUNT_ARRAY_RES =
MOUNT_CALL_NAMES.map do |c| {c, /(\w+)\.#{c}\s*\(\s*\[([^\]]+)\]\s*,\s*/m} end.to_h -
MOUNT_BACKTICK_RES =
MOUNT_CALL_NAMES.map do |c| {c, /(\w+)\.#{c}\s*\(\s*`([^`$]+)`\s*,\s*/} end.to_h -
MOUNT_CALL_NAMES =
["use", "route"] of ::String -
Mount-call verbs scanned for literal prefixes (
.use('/p', r)/.route('/p', app)). Compiled once per verb — interpolated regex literals would otherwise be rebuilt (full PCRE2 compile) on every scan_literal_mount_calls invocation. -
MOUNT_IDENT_RES =
MOUNT_CALL_NAMES.map do |c| {c, /(\w+)\.#{c}\s*\(\s*(\w+)\s*,\s*/} end.to_h -
MOUNT_STRING_RES =
MOUNT_CALL_NAMES.map do |c| {c, /(\w+)\.#{c}\s*\(\s*['"]([^'"]+)['"]\s*,\s*/} end.to_h -
SPLIT_COMMA_RULES =
Noir::TopLevelSplit::Rules.new(nest: (Noir::TopLevelSplit::Nest::Paren | Noir::TopLevelSplit::Nest::Bracket) | Noir::TopLevelSplit::Nest::Brace, quotes: "\"'`", escape: Noir::TopLevelSplit::Escape::InQuotes, strip: false, empties: Noir::TopLevelSplit::Empties::DropTrailing, per_kind: true, clamp: true) -
Rules::JSon five of seven axes — same nest kinds, same three quote characters, same per-kind depth counters, same clamp, sameEscape::InQuotes. It diverges onstripandemptiesonly, and only because the hand-rolled body it replaces never stripped and kept its interior empties:Rules::JSstrips and drops every empty part.Both divergences are invisible to the single caller — the loop in
parse_destructured_namesdoesitem.stripand skips the result when it is empty — so this is faithfulness to the replaced body, not a behavior requirement. File-local because no other splitter in the tree wants this combination, and promoting a preset for one caller whose two distinctive axes are unobservable would be misleading.
Constructors
- .new(all_files : Array(String), base_paths : Array(String), base_path : String, logger : NoirLogger)
Instance Method Summary
-
#scan
Main entry point: scan all files for router mount patterns