Noir::GoNamedHandler
Named-handler attribution for the Go adapters' line loops.
Those loops credit every accessor line (c.Query("x")) to the most recent
route above it. That is right for inline closures, but a named handler's
body (r.GET("/a", listA) ... func listA(c) {...}) sits below the LAST
route of the file, so all of its accessors landed on that last route and
the route that actually names the handler got nothing.
Usage: build one per file from the extracted routes, claim? each line
first (skip the legacy attribution when it returns true), bind every
endpoint with its route, then each_attribution once the loop is done
(the handler may be declared above or below its route).
Every plain handler argument of a route is resolved — middleware too
(r.GET("/x", Auth, listX) binds both bodies), and a middleware factory
called with no arguments (RateLimit()) resolves to the factory body.
Only unambiguous references are claimed; everything else keeps the legacy
attribution:
- a bare
listAresolves to the onefunc listAin this file; - a selector
h.Listresolves to the one methodListin this file whose receiver type is the typehis declared with here, or, whenh's type is not visible in this file, whose receiver is namedh. A receiver that is an imported package (handlers.List) never resolves to a local method; - given a
Scope, a name not declared in this file is looked up in the other files of its package (same rules), andpkg.Fnin the scanned packagepkgimports. Those bodies are attributed from their own source, since the line loop never walks them; - a function that registers routes itself is never claimed.
A wrapped handler (guard(func(c) { return listA(c) })) binds every
function its text names (guard, listA), and a bound body's own calls
bind one hop further (listA calling parseFilter(c)). Any other body in
the file that registers no route is claimed and credited to nobody: a
helper below the last route is not part of that route.
Constants
Declarations that pin a name's type, scanned once per file (see
declared_types). Assignments are anchored at a statement start, so the
second name of a, b := &X{}, newY() is never typed X.
Group 2 is the type's package qualifier, if any.
name *T as a parameter, receiver, struct field or var.
The text after a definition's parameter list when it is a handler: no
result (func(c *gin.Context), func(w, r)) or an error (func(c echo.Context) error). A wrapper or factory returns the next handler
(echo.HandlerFunc, func(...)), so it never matches.
Library middleware whose request read lives in a dependency the scan
never sees, with that read as the source line the adapters parse:
gin's BasicAuth checks the Authorization header.
An unqualified name in a wrapped handler's text, and an unqualified call in a bound body.
recv.Method( in a body: a call on a receiver.
A route registration with a path literal (net/http's may lead with a
method, "POST /items"): the stand-in for the same-file route-row check
on a body declared in another file.
A function value in a wrapped handler's text: a name or selector that is
neither called nor a composite literal (a.UpdateSubscriber in
pm(hasID(a.UpdateSubscriber), auth.PermX)).
Constructors
Class methods
listA -> {"", "listA"}, h.List -> {"h", "List"}, RateLimit() ->
{"", "RateLimit"}. Anything else (closures, calls with arguments,
wrapped handlers) is not a plain reference, so nil.
Instance methods
True when line (0-based index) is inside the body of a function a
route names; the line is held for each_attribution.
The route's handler resolved to its definition: the last handler
argument, which is the one that answers (everything before it is
middleware), or the first one with handler_first. A wrapped handler
names the function value it hands in. An inline closure there is the handler, named closure at
the line it starts on; a middleware before a closure is never promoted,
since route.GET("/home", CookieTool(), func(c) {...}) is not handled
by CookieTool. A bare name bound to a closure in the registering
function (isLive := func(c *gin.Context) {...}) names that closure.
The definition the route's handler resolves to (see handler_for), for
reading its request params; nil for an inline closure.
Whether the route hands its path to a router a called function builds
(mux.Handle("/v1/", api.NewHandler(store))): that router's own routes
are reported, so the mount is not a route.