Imports #
"go/ast"
"go/ast"
"iter"
"go/ast"
"math"
"go/ast"
"go/ast"
"iter"
"go/ast"
"math"
const nArrayType = iotaconst nAssignStmtconst nBadDeclconst nBadExprconst nBadStmtconst nBasicLitconst nBinaryExprconst nBlockStmtconst nBranchStmtconst nCallExprconst nCaseClauseconst nChanTypeconst nCommClauseconst nCommentconst nCommentGroupconst nCompositeLitconst nDeclStmtconst nDeferStmtconst nEllipsisconst nEmptyStmtconst nExprStmtconst nFieldconst nFieldListconst nFileconst nForStmtconst nFuncDeclconst nFuncLitconst nFuncTypeconst nGenDeclconst nGoStmtconst nIdentconst nIfStmtconst nImportSpecconst nIncDecStmtconst nIndexExprconst nIndexListExprconst nInterfaceTypeconst nKeyValueExprconst nLabeledStmtconst nMapTypeconst nPackageconst nParenExprconst nRangeStmtconst nReturnStmtconst nSelectStmtconst nSelectorExprconst nSendStmtconst nSliceExprconst nStarExprconst nStructTypeconst nSwitchStmtconst nTypeAssertExprconst nTypeSpecconst nTypeSwitchStmtconst nUnaryExprconst nValueSpecAn Inspector provides methods for inspecting (traversing) the syntax trees of a package.
type Inspector struct {
events []event
}An event represents a push or a pop of an ast.Node during a traversal.
type event struct {
node ast.Node
typ uint64
index int
}All[N] returns an iterator over all the nodes of type N. N must be a pointer-to-struct type that implements ast.Node. Example: for call := range All[*ast.CallExpr](in) { ... }
func All(in *Inspector) *ast.IndexExprNew returns an Inspector for the specified syntax trees.
func New(files []*ast.File) *InspectorNodes visits the nodes of the files supplied to New in depth-first order. It calls f(n, true) for each node n before it visits n's children. If f returns true, Nodes invokes f recursively for each of the non-nil children of the node, followed by a call of f(n, false). The complete traversal sequence is determined by ast.Inspect. The types argument, if non-empty, enables type-based filtering of events. The function f if is called only for nodes whose type matches an element of the types slice.
func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) proceed bool)Preorder visits all the nodes of the files supplied to New in depth-first order. It calls f(n) for each node n before it visits n's children. The complete traversal sequence is determined by ast.Inspect. The types argument, if non-empty, enables type-based filtering of events. The function f is called only for nodes whose type matches an element of the types slice.
func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node))PreorderSeq returns an iterator that visits all the nodes of the files supplied to New in depth-first order. It visits each node n before n's children. The complete traversal sequence is determined by ast.Inspect. The types argument, if non-empty, enables type-based filtering of events: only nodes whose type matches an element of the types slice are included in the sequence.
func (in *Inspector) PreorderSeq(types ...ast.Node) *ast.IndexExprWithStack visits nodes in a similar manner to Nodes, but it supplies each call to f an additional argument, the current traversal stack. The stack's first element is the outermost node, an *ast.File; its last is the innermost, n.
func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) proceed bool)func maskOf(nodes []ast.Node) uint64traverse builds the table of events representing a traversal.
func traverse(files []*ast.File) []eventtypeOf returns a distinct single-bit value that represents the type of n. Various implementations were benchmarked with BenchmarkNewInspector: GOGC=off - type switch 4.9-5.5ms 2.1ms - binary search over a sorted list of types 5.5-5.9ms 2.5ms - linear scan, frequency-ordered list 5.9-6.1ms 2.7ms - linear scan, unordered list 6.4ms 2.7ms - hash table 6.5ms 3.1ms A perfect hash seemed like overkill. The compiler's switch statement is the clear winner as it produces a binary tree in code, with constant conditions and good branch prediction. (Sadly it is the most verbose in source code.) Binary search suffered from poor branch prediction.
func typeOf(n ast.Node) uint64Generated with Arrow