...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package walk
17
18 import (
19 "fmt"
20
21 "cuelang.org/go/internal/core/adt"
22 )
23
24
25
26 func Features(x adt.Expr, f func(label adt.Feature, src adt.Node)) {
27 w := Visitor{
28 Feature: f,
29 }
30 w.Elem(x)
31 }
32
33
34 type Visitor struct {
35
36 Feature func(f adt.Feature, src adt.Node)
37
38
39
40
41 Before func(adt.Node) bool
42 }
43
44 func (w *Visitor) Elem(x adt.Elem) {
45 w.node(x)
46 }
47
48 func (w *Visitor) feature(x adt.Feature, src adt.Node) {
49 if w.Feature != nil {
50 w.Feature(x, src)
51 }
52 }
53
54 func (w *Visitor) node(n adt.Node) {
55 if w.Before != nil && !w.Before(n) {
56 return
57 }
58
59 switch x := n.(type) {
60 case nil:
61
62
63 case adt.Value:
64
65 case *adt.ConjunctGroup:
66 for _, x := range *x {
67 w.Elem(x.Elem())
68 }
69
70 case *adt.ListLit:
71 for _, x := range x.Elems {
72 w.node(x)
73 }
74
75 case *adt.StructLit:
76 for _, x := range x.Decls {
77 w.node(x)
78 }
79
80 case *adt.FieldReference:
81 w.feature(x.Label, x)
82
83 case *adt.ValueReference:
84 w.feature(x.Label, x)
85
86 case *adt.LabelReference:
87
88 case *adt.DynamicReference:
89
90 case *adt.ImportReference:
91 w.feature(x.ImportPath, x)
92 w.feature(x.Label, x)
93
94 case *adt.LetReference:
95 w.feature(x.Label, x)
96
97 case *adt.SelectorExpr:
98 w.node(x.X)
99 w.feature(x.Sel, x)
100
101 case *adt.IndexExpr:
102 w.node(x.X)
103 w.node(x.Index)
104
105 case *adt.SliceExpr:
106 w.node(x.X)
107 w.node(x.Lo)
108 w.node(x.Hi)
109 w.node(x.Stride)
110
111 case *adt.Interpolation:
112 for _, x := range x.Parts {
113 w.node(x)
114 }
115
116 case *adt.BoundExpr:
117 w.node(x.Expr)
118
119 case *adt.UnaryExpr:
120 w.node(x.X)
121
122 case *adt.BinaryExpr:
123 w.node(x.X)
124 w.node(x.Y)
125
126 case *adt.CallExpr:
127 w.node(x.Fun)
128 for _, arg := range x.Args {
129 w.node(arg)
130 }
131
132 case *adt.DisjunctionExpr:
133 for _, d := range x.Values {
134 w.node(d.Val)
135 }
136
137
138
139 case *adt.Ellipsis:
140 if x.Value != nil {
141 w.node(x.Value)
142 }
143
144 case *adt.Field:
145 w.feature(x.Label, x)
146 w.node(x.Value)
147
148 case *adt.LetField:
149 w.feature(x.Label, x)
150 w.node(x.Value)
151
152 case *adt.BulkOptionalField:
153 w.node(x.Filter)
154 w.node(x.Value)
155
156 case *adt.DynamicField:
157 w.node(x.Key)
158 w.node(x.Value)
159
160
161
162 case *adt.Comprehension:
163 for _, c := range x.Clauses {
164 w.node(c)
165 }
166 w.node(adt.ToExpr(x.Value))
167
168 case *adt.ForClause:
169 w.feature(x.Key, x)
170 w.feature(x.Value, x)
171
172 case *adt.IfClause:
173 w.node(x.Condition)
174
175 case *adt.LetClause:
176 w.feature(x.Label, x)
177 w.node(x.Expr)
178
179 case *adt.ValueClause:
180
181 default:
182 panic(fmt.Sprintf("unknown field %T", x))
183 }
184 }
185
View as plain text