mirror of
https://github.com/golang/go
synced 2024-11-11 17:21:38 -07:00
go/ast: add Preorder go1.23 iterator
This CL adds a new function Preorder that makes it easier to iterate over the nodes of a syntax tree. In particular, break, continue, and return retain their usual continuations. Fixes #66339 Change-Id: I438b3c23780c91ed589871ad3b8822d54e8fabc7 Reviewed-on: https://go-review.googlesource.com/c/go/+/570680 Reviewed-by: Robert Findley <rfindley@google.com> Auto-Submit: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
3c8f925606
commit
7730e5b783
1
api/next/66339.txt
Normal file
1
api/next/66339.txt
Normal file
@ -0,0 +1 @@
|
||||
pkg go/ast, func Preorder(Node) iter.Seq[Node] #66339
|
2
doc/next/6-stdlib/99-minor/go/ast/66339.md
Normal file
2
doc/next/6-stdlib/99-minor/go/ast/66339.md
Normal file
@ -0,0 +1,2 @@
|
||||
The new [Preorder] function returns a convenient iterator over all the
|
||||
nodes of a syntax tree.
|
@ -140,6 +140,41 @@ func main() {
|
||||
// 61 }
|
||||
}
|
||||
|
||||
func ExamplePreorder() {
|
||||
src := `
|
||||
package p
|
||||
|
||||
func f(x, y int) {
|
||||
print(x + y)
|
||||
}
|
||||
`
|
||||
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, "", src, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Print identifiers in order
|
||||
for n := range ast.Preorder(f) {
|
||||
id, ok := n.(*ast.Ident)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
fmt.Println(id.Name)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// p
|
||||
// f
|
||||
// x
|
||||
// y
|
||||
// int
|
||||
// print
|
||||
// x
|
||||
// y
|
||||
}
|
||||
|
||||
// This example illustrates how to remove a variable declaration
|
||||
// in a Go program while maintaining correct comment association
|
||||
// using an ast.CommentMap.
|
||||
|
@ -4,7 +4,10 @@
|
||||
|
||||
package ast
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"iter"
|
||||
)
|
||||
|
||||
// A Visitor's Visit method is invoked for each node encountered by [Walk].
|
||||
// If the result visitor w is not nil, [Walk] visits each of the children
|
||||
@ -368,3 +371,20 @@ func (f inspector) Visit(node Node) Visitor {
|
||||
func Inspect(node Node, f func(Node) bool) {
|
||||
Walk(inspector(f), node)
|
||||
}
|
||||
|
||||
// Preorder returns an iterator over all the nodes of the syntax tree
|
||||
// beneath (and including) the specified root, in depth-first
|
||||
// preorder.
|
||||
//
|
||||
// For greater control over the traversal of each subtree, use [Inspect].
|
||||
func Preorder(root Node) iter.Seq[Node] {
|
||||
return func(yield func(Node) bool) {
|
||||
ok := true
|
||||
Inspect(root, func(n Node) bool {
|
||||
if n != nil && !yield(n) {
|
||||
ok = false
|
||||
}
|
||||
return ok
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user