πΉ Go Fan Report: golang.org/x/tools
Module Overview
golang.org/x/tools is the Go team's static-analysis toolkit. In gh-aw it's the backbone of the custom linter suite β the go/analysis framework, the passes/inspect result, the go/ast/inspector traversal engine, multichecker for the CLI, and analysistest for tests. This is one of the most deeply-integrated dependencies in the repo. π
Current Usage in gh-aw
- Files: ~38 analyzer packages under
pkg/linters/* (+ shared internal/astutil), wired into cmd/linters/main.go via multichecker.Main(...).
- Key APIs Used:
analysis.Analyzer / Pass.ReportRangef, passes/inspect.Analyzer (every analyzer's Requires), go/ast/inspector (Preorder, Root().Preorder, Cursor.Enclosing), multichecker.Main, analysistest.
- Version:
v0.47.0 β the latest release (repo pushed 2026-06-30). No upgrade needed. β
Research Findings
The go/ast/inspector docs now explicitly state: "We recommend using methods of Cursor in preference to Inspector where possible." The Cursor API (added v0.34.0, well below the pinned v0.47.0) is immutable positional navigation over the AST β Enclosing, Parent, Children, Contains, FindByPos, Preorder, Inspect β letting you start a traversal at any node, nest traversals, and navigate in all four directions.
Recent Updates
Cursor + Inspector.Root()/At() (v0.34.0), Valid()/ParentEdgeKind()/ParentEdgeIndex() (v0.42.0), generic All[N]/PreorderSeq iterators (v0.26.0). Active maintenance through v0.47.0.
Best Practices
- Prefer
Cursor methods over the callback-based Inspector.Preorder/Nodes/WithStack.
- Use
Cursor.Enclosing(types...) for ancestor/context checks instead of manual stack tracking.
Improvement Opportunities
π Quick Wins
- Add an
astutil.Root(pass) (inspector.Cursor, error) helper next to the existing astutil.Inspector(pass) so Cursor-style linters share one error path and drop insp.Root() boilerplate.
β¨ Feature Opportunities
- The Cursor-based linters (e.g.
timeafterleak) that re-walk subtrees for containment could use Cursor.Contains / Cursor.FindByPos.
π Best Practice Alignment (primary finding)
The suite is split between two traversal styles:
- Modern Cursor API (
insp.Root().Preorder(...) + cur.Enclosing(...)): 9 linters β ctxbackground, deferinloop, execcommandwithoutcontext, hardcodedfilepath, httpnoctx, panic-in-library-code, regexpcompileinfunction, timeafterleak, timesleepnocontext (exactly the ones needing enclosing-context navigation).
- Legacy callback API (
insp.Preorder(filter, func(n ast.Node){...})): 29 linters β e.g. sortslice, errormessage, httpstatuscode, jsonmarshalignoredeerror, lenstringzero.
- No linter uses the superseded
WithStack (good).
Migrating the 29 legacy linters to for cur := range insp.Root().Preorder(nodeType) { ... } aligns the whole suite with the maintainers' recommendation, drops the []ast.Node filter boilerplate, and makes any future enclosing-context need a one-line cur.Enclosing(...) instead of a rewrite.
π§ General Improvements
- A tiny shared traversal helper would keep all linters on one style and prevent drift between the two.
Recommendations (prioritized)
- Incrementally migrate legacy linters to the Cursor API. Mechanical, low-risk (both share the same inspector), guarded by existing
analysistest coverage. Start with linters most likely to grow context checks.
- Add the
astutil.Root(pass) helper to standardize Cursor acquisition.
- Keep tracking x/tools releases for further
Cursor conveniences β already on latest v0.47.0.
Next Steps
Generated by Go Fan
Module summary saved to: scratchpad/mods/golang-x-tools.md
Generated by πΉ Go Fan Β· 118.9 AIC Β· β 12.7 AIC Β· β 7.4K Β· β·
πΉ Go Fan Report: golang.org/x/tools
Module Overview
golang.org/x/toolsis the Go team's static-analysis toolkit. In gh-aw it's the backbone of the custom linter suite β thego/analysisframework, thepasses/inspectresult, thego/ast/inspectortraversal engine,multicheckerfor the CLI, andanalysistestfor tests. This is one of the most deeply-integrated dependencies in the repo. πCurrent Usage in gh-aw
pkg/linters/*(+ sharedinternal/astutil), wired intocmd/linters/main.goviamultichecker.Main(...).analysis.Analyzer/Pass.ReportRangef,passes/inspect.Analyzer(every analyzer'sRequires),go/ast/inspector(Preorder,Root().Preorder,Cursor.Enclosing),multichecker.Main,analysistest.v0.47.0β the latest release (repo pushed 2026-06-30). No upgrade needed. βResearch Findings
The
go/ast/inspectordocs now explicitly state: "We recommend using methods ofCursorin preference toInspectorwhere possible." TheCursorAPI (added v0.34.0, well below the pinned v0.47.0) is immutable positional navigation over the AST βEnclosing,Parent,Children,Contains,FindByPos,Preorder,Inspectβ letting you start a traversal at any node, nest traversals, and navigate in all four directions.Recent Updates
Cursor+Inspector.Root()/At()(v0.34.0),Valid()/ParentEdgeKind()/ParentEdgeIndex()(v0.42.0), genericAll[N]/PreorderSeqiterators (v0.26.0). Active maintenance through v0.47.0.Best Practices
Cursormethods over the callback-basedInspector.Preorder/Nodes/WithStack.Cursor.Enclosing(types...)for ancestor/context checks instead of manual stack tracking.Improvement Opportunities
π Quick Wins
astutil.Root(pass) (inspector.Cursor, error)helper next to the existingastutil.Inspector(pass)so Cursor-style linters share one error path and dropinsp.Root()boilerplate.β¨ Feature Opportunities
timeafterleak) that re-walk subtrees for containment could useCursor.Contains/Cursor.FindByPos.π Best Practice Alignment (primary finding)
The suite is split between two traversal styles:
insp.Root().Preorder(...)+cur.Enclosing(...)): 9 linters βctxbackground,deferinloop,execcommandwithoutcontext,hardcodedfilepath,httpnoctx,panic-in-library-code,regexpcompileinfunction,timeafterleak,timesleepnocontext(exactly the ones needing enclosing-context navigation).insp.Preorder(filter, func(n ast.Node){...})): 29 linters β e.g.sortslice,errormessage,httpstatuscode,jsonmarshalignoredeerror,lenstringzero.WithStack(good).Migrating the 29 legacy linters to
for cur := range insp.Root().Preorder(nodeType) { ... }aligns the whole suite with the maintainers' recommendation, drops the[]ast.Nodefilter boilerplate, and makes any future enclosing-context need a one-linecur.Enclosing(...)instead of a rewrite.π§ General Improvements
Recommendations (prioritized)
analysistestcoverage. Start with linters most likely to grow context checks.astutil.Root(pass)helper to standardize Cursor acquisition.Cursorconveniences β already on latest v0.47.0.Next Steps
astutil.Root(pass)helper.sortslice,httpstatuscode) to Cursor as a pattern reference.Generated by Go Fan
Module summary saved to: scratchpad/mods/golang-x-tools.md