Analyzer::Swift::Vapor
Inherits Analyzer::Swift::SwiftEngine < FileScanEngine < Analyzer < FileHelper < Reference < Object
Constants
The base may be a dotted receiver (app.routes.grouped(...)), an implicit
self (bare grouped(...)), or a single identifier (router.grouped(...)).
Maximum number of lines to look ahead for function parameters
route_definition? runs on every scanned line (route detection, param
lookahead, body-boundary checks). One precompiled Regex.union scan
(PCRE2 JIT) replaces six naive String#includes? char scans; union
auto-escapes each literal so it is provably equivalent to the
OR-of-substrings it replaces.
Patterns for route definitions in Vapor: app.get("path") { ... } app.post("path", "segment") { ... } routes.get("path", ":param") { ... }
extension RoutesBuilder { ... self.get(...) ... } — inside such an
extension self (and bare grouped(...), handled by GROUP_ASSIGN_PATTERN)
is router-like.
A function parameter (or binding) typed as a Vapor router:
func routes(_ app: Application), func boot(routes: RoutesBuilder),
func boot(router: Router) (Vapor 3), let app = Application(...).
Tracking these makes route detection receiver-aware, so that non-router
.get/.delete/... calls — Environment.get("DATABASE_URL"),
model.delete(on: req.db), req.client.get(url) — stop surfacing as
phantom endpoints.
Gate for register_router_params. All three patterns it runs require
one of these three words, so a line without any of them cannot
contribute a receiver and does not need to be matched at all.
That pattern opens with an unanchored ([A-Za-z_]\w*), so PCRE2 tries
it at every offset of the subject and backtracks the greedy \w* on
each one — quadratic in the line length. Up to roughly half a megabyte
the JIT absorbs it; past that the JIT stack overflows, PCRE2 falls back
to the interpreter, and the cost becomes visible all at once: a
600 KB single-line .swift file (generated code, a vendored bundle)
took 75 s in this one scan where 300 KB took milliseconds.
A literal union is a plain memchr-class search with no backtracking, and since the full pattern requires one of these three words the gate cannot change what is found.
Class methods
Instance methods
Extract parameters from function body
Extract path parameters from the route pattern (e.g., :id, :userID)
Parse route path from route arguments Examples: "hello" -> /hello "users", ":id" -> /users/:id "api", "users", ":userID" -> /api/users/:userID
Instance-side view of the same declaration. The per-file rescues live on
this base class, which has no way to name the analyzer that is running
inside them, so a skipped file could not be attributed to a tech.
Deriving it from analyzer_for keeps the name written exactly once.