Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/river/ast/walk.go
4096 views
1
package ast
2
3
import "fmt"
4
5
// A Visitor has its Visit method invoked for each node encountered by Walk. If
6
// the resulting visitor w is not nil, Walk visits each of the children of node
7
// with the visitor w, followed by a call of w.Visit(nil).
8
type Visitor interface {
9
Visit(node Node) (w Visitor)
10
}
11
12
// Walk traverses an AST in depth-first order: it starts by calling
13
// v.Visit(node); node must not be nil. If the visitor w returned by
14
// v.Visit(node) is not nil, Walk is invoked recursively with visitor w for
15
// each of the non-nil children of node, followed by a call of w.Visit(nil).
16
func Walk(v Visitor, node Node) {
17
if v = v.Visit(node); v == nil {
18
return
19
}
20
21
// Walk children. The order of the cases matches the declared order of nodes
22
// in ast.go.
23
switch n := node.(type) {
24
case *File:
25
Walk(v, n.Body)
26
case Body:
27
for _, s := range n {
28
Walk(v, s)
29
}
30
case *AttributeStmt:
31
Walk(v, n.Name)
32
Walk(v, n.Value)
33
case *BlockStmt:
34
Walk(v, n.Body)
35
case *Ident:
36
// Nothing to do
37
case *IdentifierExpr:
38
Walk(v, n.Ident)
39
case *LiteralExpr:
40
// Nothing to do
41
case *ArrayExpr:
42
for _, e := range n.Elements {
43
Walk(v, e)
44
}
45
case *ObjectExpr:
46
for _, f := range n.Fields {
47
Walk(v, f.Name)
48
Walk(v, f.Value)
49
}
50
case *AccessExpr:
51
Walk(v, n.Value)
52
Walk(v, n.Name)
53
case *IndexExpr:
54
Walk(v, n.Value)
55
Walk(v, n.Index)
56
case *CallExpr:
57
Walk(v, n.Value)
58
for _, a := range n.Args {
59
Walk(v, a)
60
}
61
case *UnaryExpr:
62
Walk(v, n.Value)
63
case *BinaryExpr:
64
Walk(v, n.Left)
65
Walk(v, n.Right)
66
case *ParenExpr:
67
Walk(v, n.Inner)
68
default:
69
panic(fmt.Sprintf("river/ast: unexpected node type %T", n))
70
}
71
72
v.Visit(nil)
73
}
74
75