mirror of https://github.com/golang/go.git
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
|
|
@ -0,0 +1 @@
|
||||||
|
pkg go/ast, func Preorder(Node) iter.Seq[Node] #66339
|
||||||
|
|
@ -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 }
|
// 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
|
// This example illustrates how to remove a variable declaration
|
||||||
// in a Go program while maintaining correct comment association
|
// in a Go program while maintaining correct comment association
|
||||||
// using an ast.CommentMap.
|
// using an ast.CommentMap.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@
|
||||||
|
|
||||||
package ast
|
package ast
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"iter"
|
||||||
|
)
|
||||||
|
|
||||||
// A Visitor's Visit method is invoked for each node encountered by [Walk].
|
// 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
|
// 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) {
|
func Inspect(node Node, f func(Node) bool) {
|
||||||
Walk(inspector(f), node)
|
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