feat(go): index GoFrame g.Meta routes and bind them to controller methods (#747) (#957)

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:
Colby Mchenry
2026-06-22 18:16:11 -05:00
committed by GitHub
co-authored by Claude Opus 4.8
parent 6459ead6aa
commit a89315645d
9 changed files with 531 additions and 0 deletions
+3
View File
@@ -19,6 +19,7 @@ import { railsResolver } from './ruby';
import { springResolver } from './java';
import { playResolver } from './play';
import { goResolver } from './go';
import { goframeResolver } from './goframe';
import { rustResolver } from './rust';
import { aspnetResolver } from './csharp';
import { swiftUIResolver, uikitResolver, vaporResolver } from './swift';
@@ -52,6 +53,7 @@ const FRAMEWORK_RESOLVERS: FrameworkResolver[] = [
playResolver,
// Go
goResolver,
goframeResolver,
// Rust
rustResolver,
// C#
@@ -136,6 +138,7 @@ export { railsResolver } from './ruby';
export { springResolver } from './java';
export { playResolver } from './play';
export { goResolver } from './go';
export { goframeResolver } from './goframe';
export { rustResolver } from './rust';
export { aspnetResolver } from './csharp';
export { swiftUIResolver, uikitResolver, vaporResolver } from './swift';