package inspector

Import Path
	golang.org/x/tools/go/ast/inspector (on go.dev)

Dependency Relation
	imports 7 packages, and imported by one package

Involved Source Files cursor.go Package inspector provides helper functions for traversal over the syntax trees of a package, including node filtering by type, and materialization of the traversal stack. During construction, the inspector does a complete traversal and builds a list of push/pop events and their node type. Subsequent method calls that request a traversal scan this list, rather than walk the AST, and perform type filtering using efficient bit sets. This representation is sometimes called a "balanced parenthesis tree." Experiments suggest the inspector's traversals are about 2.5x faster than [ast.Inspect], but it may take around 5 traversals for this benefit to amortize the inspector's construction cost. If efficiency is the primary concern, do not use Inspector for one-off traversals. The [Cursor] type provides a more flexible API for efficient navigation of syntax trees in all four "cardinal directions". For example, traversals may be nested, so you can find each node of type A and then search within it for nodes of type B. Or you can traverse from a node to its immediate neighbors: its parent, its previous and next sibling, or its first and last child. We recommend using methods of Cursor in preference to Inspector where possible. iter.go typeof.go walk.go
Package-Level Type Names (total 5, in which 2 are exported)
/* sort exporteds by: | */
A Cursor represents an [ast.Node]. It is immutable. Two Cursors compare equal if they represent the same node. The zero value of Cursor is not valid. Call [Inspector.Root] to obtain a cursor for the virtual root node of the traversal. This is the sole valid cursor for which [Cursor.Node] returns nil. Use the following methods to navigate efficiently around the tree: - for ancestors, use [Cursor.Parent] and [Cursor.Enclosing]; - for children, use [Cursor.Child], [Cursor.Children], [Cursor.FirstChild], and [Cursor.LastChild]; - for siblings, use [Cursor.PrevSibling] and [Cursor.NextSibling]; - for descendants, use [Cursor.FindByPos], [Cursor.FindNode], [Cursor.Inspect], and [Cursor.Preorder]. Use the [Cursor.ChildAt] and [Cursor.ParentEdge] methods for information about the edges in a tree: which field (and slice element) of the parent node holds the child. Child returns the cursor for n, which must be a direct child of c's Node. Child must not be called on the Root node (whose [Cursor.Node] returns nil). ChildAt returns the cursor for the child of the current node identified by its edge and index. The index must be -1 if the edge.Kind is not a slice. The indicated child node must exist. ChildAt must not be called on the Root node (whose [Cursor.Node] returns nil). Invariant: c.Parent().ChildAt(c.ParentEdge()) == c. Children returns an iterator over the direct children of the current node, if any. When using Children, NextChild, and PrevChild, bear in mind that a Node's children may come from different fields, some of which may be lists of nodes without a distinguished intervening container such as [ast.BlockStmt]. For example, [ast.CaseClause] has a field List of expressions and a field Body of statements, so the children of a CaseClause are a mix of expressions and statements. Other nodes that have "uncontained" list fields include: - [ast.ValueSpec] (Names, Values) - [ast.CompositeLit] (Type, Elts) - [ast.IndexListExpr] (X, Indices) - [ast.CallExpr] (Fun, Args) - [ast.AssignStmt] (Lhs, Rhs) So, do not assume that the previous sibling of an ast.Stmt is also an ast.Stmt, or if it is, that they are executed sequentially, unless you have established that, say, its parent is a BlockStmt or its [Cursor.ParentEdge] is [edge.BlockStmt_List]. For example, given "for S1; ; S2 {}", the predecessor of S2 is S1, even though they are not executed in sequence. Contains reports whether c contains or is equal to c2. Both Cursors must belong to the same [Inspector]; neither may be its Root node. Enclosing returns an iterator over the nodes enclosing the current current node, starting with the Cursor itself. Enclosing must not be called on the Root node (whose [Cursor.Node] returns nil). The types argument, if non-empty, enables type-based filtering of events: the sequence includes only enclosing nodes whose type matches an element of the types slice. FindByPos returns the cursor for the innermost node n in the tree rooted at c such that n.Pos() <= start && end <= n.End(). (For an *ast.File, it uses the bounds n.FileStart-n.FileEnd.) An empty range (start == end) between two adjacent nodes is considered to belong to the first node. It returns zero if none is found. Precondition: start <= end. See also [astutil.PathEnclosingInterval], which tolerates adjoining whitespace. FindNode returns the cursor for node n if it belongs to the subtree rooted at c. It returns zero if n is not found. FirstChild returns the first direct child of the current node, or zero if it has no children. Index returns the index of this cursor position within the package. Clients should not assume anything about the numeric Index value except that it increases monotonically throughout the traversal. It is provided for use with [Inspector.At]. Index must not be called on the Root node. Inspect visits the nodes of the subtree represented by c in depth-first order. It calls f(n) for each node n before it visits n's children. If f returns true, Inspect invokes f recursively for each of the non-nil children of the node. Each node is represented by a Cursor that allows access to the Node, but may also be used to start a new traversal, or to obtain the stack of nodes enclosing the cursor. 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. Inspector returns the cursor's Inspector. It returns nil if the Cursor is not valid. LastChild returns the last direct child of the current node, or zero if it has no children. NextSibling returns the cursor for the next sibling node in the same list (for example, of files, decls, specs, statements, fields, or expressions) as the current node. It returns (zero, false) if the node is the last node in the list, or is not part of a list. NextSibling must not be called on the Root node. See note at [Cursor.Children]. Node returns the node at the current cursor position, or nil for the cursor returned by [Inspector.Root]. Parent returns the parent of the current node. Parent must not be called on the Root node (whose [Cursor.Node] returns nil). ParentEdge returns the identity of the field in the parent node that holds this cursor's node, and if it is a list, the index within it. For example, f(x, y) is a CallExpr whose three children are Idents. f has edge kind [edge.CallExpr_Fun] and index -1. x and y have kind [edge.CallExpr_Args] and indices 0 and 1, respectively. If called on a child of the Root node, it returns ([edge.Invalid], -1). ParentEdge must not be called on the Root node (whose [Cursor.Node] returns nil). ParentEdgeIndex returns the index component of the result of [Cursor.ParentEdge]. ParentEdgeKind returns the kind component of the result of [Cursor.ParentEdge]. Preorder returns an iterator over the nodes of the subtree represented by c in depth-first order. Each node in the sequence is represented by a Cursor that allows access to the Node, but may also be used to start a new traversal, or to obtain the stack of nodes enclosing the cursor. The 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. If you need control over descent into subtrees, or need both pre- and post-order notifications, use [Cursor.Inspect] PrevSibling returns the cursor for the previous sibling node in the same list (for example, of files, decls, specs, statements, fields, or expressions) as the current node. It returns zero if the node is the first node in the list, or is not part of a list. It must not be called on the Root node. See note at [Cursor.Children]. String returns information about the cursor's node, if any. Valid reports whether the cursor is valid. The zero value of cursor is invalid. Unless otherwise documented, it is not safe to call any other method on an invalid cursor. Cursor : expvar.Var Cursor : fmt.Stringer func Cursor.Child(n ast.Node) Cursor func Cursor.ChildAt(k edge.Kind, idx int) Cursor func Cursor.FindByPos(start, end token.Pos) (Cursor, bool) func Cursor.FindNode(n ast.Node) (Cursor, bool) func Cursor.FirstChild() (Cursor, bool) func Cursor.LastChild() (Cursor, bool) func Cursor.NextSibling() (Cursor, bool) func Cursor.Parent() Cursor func Cursor.PrevSibling() (Cursor, bool) func (*Inspector).At(index int32) Cursor func (*Inspector).Root() Cursor func Cursor.Contains(c2 Cursor) bool func golang.org/x/tools/internal/typesinternal.EnclosingScope(info *types.Info, cur Cursor) *types.Scope
An Inspector provides methods for inspecting (traversing) the syntax trees of a package. At returns the cursor at the specified index in the traversal, which must have been obtained from [Cursor.Index] on a Cursor belonging to the same Inspector (see [Cursor.Inspector]). Nodes 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. The [Cursor.Inspect] method provides a richer alternative interface. Example: in.Root().Inspect(types, func(c Cursor) bool { ... return true } 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. The [Cursor.Preorder] method provides a richer alternative interface. Example: for c := range in.Root().Preorder(types) { ... } 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: only nodes whose type matches an element of the types slice are included in the sequence. Example: for call := range in.PreorderSeq((*ast.CallExpr)(nil)) { ... } The [All] function is more convenient if there is exactly one node type: for call := range All[*ast.CallExpr](in) { ... } See also the newer and more flexible [Cursor] API, which lets you start the traversal at an arbitrary node, and reports each matching node by its Cursor, enabling easier navigation. The above example would be written thus: for curCall := range in.Root().Preorder((*ast.CallExpr)(nil)) { call := curCall.Node().(*ast.CallExpr) ... } Root returns a valid cursor for the virtual root node, whose children are the files provided to [New]. Its [Cursor.Node] method return nil. WithStack 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. The [Cursor.Inspect] method provides a richer alternative interface. Example: in.Root().Inspect(types, func(c Cursor) bool { stack := slices.Collect(c.Enclosing()) ... return true }) func New(files []*ast.File) *Inspector func Cursor.Inspector() *Inspector func All[N, S](in *Inspector) iter.Seq[N]
Package-Level Functions (total 9, in which 2 are exported)
Type Parameters: N: interface{*S; ast.Node} S: any 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) { ... } See also the newer and more flexible [Cursor] API, which lets you start the traversal at an arbitrary node, and reports each matching node by its Cursor, enabling easier navigation. The above example would be written thus: for curCall := range in.Root().Preorder((*ast.CallExpr)(nil)) { call := curCall.Node().(*ast.CallExpr) ... }
New returns an Inspector for the specified syntax trees.