Skip to content

Commit a2408f8

Browse files
adonovangopherbot
authored andcommitted
internal/astutil/cursor: Cursor.Children: document invariants
Fixes golang/go#71074 Change-Id: I640748cde4272f12696e3125f82b3a84afe9376f Reviewed-on: https://go-review.googlesource.com/c/tools/+/641075 LUCI-TryBot-Result: Go LUCI <[email protected]> Auto-Submit: Alan Donovan <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent ee69ea2 commit a2408f8

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

internal/astutil/cursor/cursor.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ func (c Cursor) Parent() Cursor {
197197
// the last node in the list, or is not part of a list.
198198
//
199199
// NextSibling must not be called on the Root node.
200+
//
201+
// See note at [Cursor.Children].
200202
func (c Cursor) NextSibling() (Cursor, bool) {
201203
if c.index < 0 {
202204
panic("Cursor.NextSibling called on Root node")
@@ -218,6 +220,8 @@ func (c Cursor) NextSibling() (Cursor, bool) {
218220
// the first node in the list, or is not part of a list.
219221
//
220222
// It must not be called on the Root node.
223+
//
224+
// See note at [Cursor.Children].
221225
func (c Cursor) PrevSibling() (Cursor, bool) {
222226
if c.index < 0 {
223227
panic("Cursor.PrevSibling called on Root node")
@@ -266,6 +270,26 @@ func (c Cursor) LastChild() (Cursor, bool) {
266270

267271
// Children returns an iterator over the direct children of the
268272
// current node, if any.
273+
//
274+
// When using Children, NextChild, and PrevChild, bear in mind that a
275+
// Node's children may come from different fields, some of which may
276+
// be lists of nodes without a distinguished intervening container
277+
// such as [ast.BlockStmt].
278+
//
279+
// For example, [ast.CaseClause] has a field List of expressions and a
280+
// field Body of statements, so the children of a CaseClause are a mix
281+
// of expressions and statements. Other nodes that have "uncontained"
282+
// list fields include:
283+
//
284+
// - [ast.ValueSpec] (Names, Values)
285+
// - [ast.CompositeLit] (Type, Elts)
286+
// - [ast.IndexListExpr] (X, Indices)
287+
// - [ast.CallExpr] (Fun, Args)
288+
// - [ast.AssignStmt] (Lhs, Rhs)
289+
//
290+
// So, do not assume that the previous sibling of an ast.Stmt is also
291+
// an ast.Stmt unless you have established that, say, its parent is a
292+
// BlockStmt.
269293
func (c Cursor) Children() iter.Seq[Cursor] {
270294
return func(yield func(Cursor) bool) {
271295
c, ok := c.FirstChild()

0 commit comments

Comments
 (0)