Source file src/pkg/go/ast/walk.go
1
2
3
4
5 package ast
6
7 import "fmt"
8
9
10
11
12 type Visitor interface {
13 Visit(node Node) (w Visitor)
14 }
15
16
17
18 func walkIdentList(v Visitor, list []*Ident) {
19 for _, x := range list {
20 Walk(v, x)
21 }
22 }
23
24 func walkExprList(v Visitor, list []Expr) {
25 for _, x := range list {
26 Walk(v, x)
27 }
28 }
29
30 func walkStmtList(v Visitor, list []Stmt) {
31 for _, x := range list {
32 Walk(v, x)
33 }
34 }
35
36 func walkDeclList(v Visitor, list []Decl) {
37 for _, x := range list {
38 Walk(v, x)
39 }
40 }
41
42
43
44
45
46
47
48
49
50
51 func Walk(v Visitor, node Node) {
52 if v = v.Visit(node); v == nil {
53 return
54 }
55
56
57
58
59 switch n := node.(type) {
60
61 case *Comment:
62
63
64 case *CommentGroup:
65 for _, c := range n.List {
66 Walk(v, c)
67 }
68
69 case *Field:
70 if n.Doc != nil {
71 Walk(v, n.Doc)
72 }
73 walkIdentList(v, n.Names)
74 Walk(v, n.Type)
75 if n.Tag != nil {
76 Walk(v, n.Tag)
77 }
78 if n.Comment != nil {
79 Walk(v, n.Comment)
80 }
81
82 case *FieldList:
83 for _, f := range n.List {
84 Walk(v, f)
85 }
86
87
88 case *BadExpr, *Ident, *BasicLit:
89
90
91 case *Ellipsis:
92 if n.Elt != nil {
93 Walk(v, n.Elt)
94 }
95
96 case *FuncLit:
97 Walk(v, n.Type)
98 Walk(v, n.Body)
99
100 case *CompositeLit:
101 if n.Type != nil {
102 Walk(v, n.Type)
103 }
104 walkExprList(v, n.Elts)
105
106 case *ParenExpr:
107 Walk(v, n.X)
108
109 case *SelectorExpr:
110 Walk(v, n.X)
111 Walk(v, n.Sel)
112
113 case *IndexExpr:
114 Walk(v, n.X)
115 Walk(v, n.Index)
116
117 case *SliceExpr:
118 Walk(v, n.X)
119 if n.Low != nil {
120 Walk(v, n.Low)
121 }
122 if n.High != nil {
123 Walk(v, n.High)
124 }
125 if n.Max != nil {
126 Walk(v, n.Max)
127 }
128
129 case *TypeAssertExpr:
130 Walk(v, n.X)
131 if n.Type != nil {
132 Walk(v, n.Type)
133 }
134
135 case *CallExpr:
136 Walk(v, n.Fun)
137 walkExprList(v, n.Args)
138
139 case *StarExpr:
140 Walk(v, n.X)
141
142 case *UnaryExpr:
143 Walk(v, n.X)
144
145 case *BinaryExpr:
146 Walk(v, n.X)
147 Walk(v, n.Y)
148
149 case *KeyValueExpr:
150 Walk(v, n.Key)
151 Walk(v, n.Value)
152
153
154 case *ArrayType:
155 if n.Len != nil {
156 Walk(v, n.Len)
157 }
158 Walk(v, n.Elt)
159
160 case *StructType:
161 Walk(v, n.Fields)
162
163 case *FuncType:
164 if n.Params != nil {
165 Walk(v, n.Params)
166 }
167 if n.Results != nil {
168 Walk(v, n.Results)
169 }
170
171 case *InterfaceType:
172 Walk(v, n.Methods)
173
174 case *MapType:
175 Walk(v, n.Key)
176 Walk(v, n.Value)
177
178 case *ChanType:
179 Walk(v, n.Value)
180
181
182 case *BadStmt:
183
184
185 case *DeclStmt:
186 Walk(v, n.Decl)
187
188 case *EmptyStmt:
189
190
191 case *LabeledStmt:
192 Walk(v, n.Label)
193 Walk(v, n.Stmt)
194
195 case *ExprStmt:
196 Walk(v, n.X)
197
198 case *SendStmt:
199 Walk(v, n.Chan)
200 Walk(v, n.Value)
201
202 case *IncDecStmt:
203 Walk(v, n.X)
204
205 case *AssignStmt:
206 walkExprList(v, n.Lhs)
207 walkExprList(v, n.Rhs)
208
209 case *GoStmt:
210 Walk(v, n.Call)
211
212 case *DeferStmt:
213 Walk(v, n.Call)
214
215 case *ReturnStmt:
216 walkExprList(v, n.Results)
217
218 case *BranchStmt:
219 if n.Label != nil {
220 Walk(v, n.Label)
221 }
222
223 case *BlockStmt:
224 walkStmtList(v, n.List)
225
226 case *IfStmt:
227 if n.Init != nil {
228 Walk(v, n.Init)
229 }
230 Walk(v, n.Cond)
231 Walk(v, n.Body)
232 if n.Else != nil {
233 Walk(v, n.Else)
234 }
235
236 case *CaseClause:
237 walkExprList(v, n.List)
238 walkStmtList(v, n.Body)
239
240 case *SwitchStmt:
241 if n.Init != nil {
242 Walk(v, n.Init)
243 }
244 if n.Tag != nil {
245 Walk(v, n.Tag)
246 }
247 Walk(v, n.Body)
248
249 case *TypeSwitchStmt:
250 if n.Init != nil {
251 Walk(v, n.Init)
252 }
253 Walk(v, n.Assign)
254 Walk(v, n.Body)
255
256 case *CommClause:
257 if n.Comm != nil {
258 Walk(v, n.Comm)
259 }
260 walkStmtList(v, n.Body)
261
262 case *SelectStmt:
263 Walk(v, n.Body)
264
265 case *ForStmt:
266 if n.Init != nil {
267 Walk(v, n.Init)
268 }
269 if n.Cond != nil {
270 Walk(v, n.Cond)
271 }
272 if n.Post != nil {
273 Walk(v, n.Post)
274 }
275 Walk(v, n.Body)
276
277 case *RangeStmt:
278 if n.Key != nil {
279 Walk(v, n.Key)
280 }
281 if n.Value != nil {
282 Walk(v, n.Value)
283 }
284 Walk(v, n.X)
285 Walk(v, n.Body)
286
287
288 case *ImportSpec:
289 if n.Doc != nil {
290 Walk(v, n.Doc)
291 }
292 if n.Name != nil {
293 Walk(v, n.Name)
294 }
295 Walk(v, n.Path)
296 if n.Comment != nil {
297 Walk(v, n.Comment)
298 }
299
300 case *ValueSpec:
301 if n.Doc != nil {
302 Walk(v, n.Doc)
303 }
304 walkIdentList(v, n.Names)
305 if n.Type != nil {
306 Walk(v, n.Type)
307 }
308 walkExprList(v, n.Values)
309 if n.Comment != nil {
310 Walk(v, n.Comment)
311 }
312
313 case *TypeSpec:
314 if n.Doc != nil {
315 Walk(v, n.Doc)
316 }
317 Walk(v, n.Name)
318 Walk(v, n.Type)
319 if n.Comment != nil {
320 Walk(v, n.Comment)
321 }
322
323 case *BadDecl:
324
325
326 case *GenDecl:
327 if n.Doc != nil {
328 Walk(v, n.Doc)
329 }
330 for _, s := range n.Specs {
331 Walk(v, s)
332 }
333
334 case *FuncDecl:
335 if n.Doc != nil {
336 Walk(v, n.Doc)
337 }
338 if n.Recv != nil {
339 Walk(v, n.Recv)
340 }
341 Walk(v, n.Name)
342 Walk(v, n.Type)
343 if n.Body != nil {
344 Walk(v, n.Body)
345 }
346
347
348 case *File:
349 if n.Doc != nil {
350 Walk(v, n.Doc)
351 }
352 Walk(v, n.Name)
353 walkDeclList(v, n.Decls)
354
355
356
357
358 case *Package:
359 for _, f := range n.Files {
360 Walk(v, f)
361 }
362
363 default:
364 panic(fmt.Sprintf("ast.Walk: unexpected node type %T", n))
365 }
366
367 v.Visit(nil)
368 }
369
370 type inspector func(Node) bool
371
372 func (f inspector) Visit(node Node) Visitor {
373 if f(node) {
374 return f
375 }
376 return nil
377 }
378
379
380
381
382
383
384 func Inspect(node Node, f func(Node) bool) {
385 Walk(inspector(f), node)
386 }
387
View as plain text