GoFrame's standard router binds routes reflectively (group.Bind(ctrl)): the path and method live in a g.Meta struct tag on a request type, and the controller method that serves it is matched by that request type at runtime — so there was no path string and no edge from a route to its handler, and "where is this route handled / where are routes bound to controllers?" could only be answered lexically (issue #720's report). - frameworks/goframe.ts: detect gogf/gf in go.mod, extract each path-bearing g.Meta into a route node (requires path:, so response mime:-only tags are skipped), encoding the package-qualified request type for the join. - goframe-synthesizer.ts: join each route -> the controller method whose signature takes that request type — NOT by name (DeptSearchReq is served by List) — keyed pkg.Type to disambiguate the many identical bare names a large app defines one-per-module, with an addon-root tiebreak for cloned demo addons. Edge kind calls, provenance heuristic, synthesizedBy goframe-route, surfaced as a dynamic-dispatch hop in codegraph_explore. Validated on real repos: gf-demo-user 7/7, gfast 65/68 (3 genuinely handler-less), hotgo 242/247 (98%) — 100% precision (0 non-controller handlers, 0 core/addon cross-binding), node count stable. Agent A/B (gfast, sonnet/high, 2 runs/arm): with codegraph 1 explore call / 0 Read / ~20s vs without 7.5 Read avg + grep-hunting for the non-existent literal route string / ~42s; same correct answer. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6459ead6aa
commit
a89315645d
@@ -1651,6 +1651,14 @@ export class ToolHandler {
|
||||
registeredAt,
|
||||
};
|
||||
}
|
||||
if (m?.synthesizedBy === 'goframe-route') {
|
||||
const route = m.route ? `\`${String(m.route)}\`` : 'a route';
|
||||
return {
|
||||
label: `GoFrame route ${route} — reflective Bind → controller method (dynamic dispatch)`,
|
||||
compact: `dynamic: GoFrame route ${m.route ? String(m.route) : ''}${at}`,
|
||||
registeredAt,
|
||||
};
|
||||
}
|
||||
// Generic fallback for any other synthesizer (redux-thunk, gin-middleware-chain,
|
||||
// flutter-build, …): a synthesized hop must never read as a bare static `calls`.
|
||||
// It's a dynamic-dispatch bridge — label it as one and keep its wiring site.
|
||||
|
||||
Reference in New Issue
Block a user