Source file
src/go/ast/walk.go
Documentation: go/ast
1
2
3
4
5 package ast
6
7
8
9
10 type Visitor interface {
11 Visit(node Node) (w Visitor)
12 }
13
14
15
16 func walkIdentList(v Visitor, list []*Ident) {
17 for _, x := range list {
18 Walk(v, x)
19 }
20 }
21
22 func walkExprList(v Visitor, list []Expr) {
23 for _, x := range list {
24 Walk(v, x)
25 }
26 }
27
28 func walkStmtList(v Visitor, list []Stmt) {
29 for _, x := range list {
30 Walk(v, x)
31 }
32 }
33
34 func walkDeclList(v Visitor, list []Decl) {
35 for _, x := range list {
36 Walk(v, x)
37 }
38 }
39
40
41
42
43
44
45
46
47
48
49 func Walk(v Visitor, node Node) {
50 if v = v.Visit(node); v == nil {
51 return
52 }
53
54
55
56
57 switch n := node.(type) {
58
59 case *Comment:
60
61
62 case *CommentGroup:
63 for _, c := range n.List {
64 Walk(v, c)
65 }
66
67 case *Field:
68 if n.Doc != nil {
69 Walk(v, n.Doc)
70 }
71 walkIdentList(v, n.Names)
72 if n.Type != nil {
73 Walk(v, n.Type)
74 }
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 walkFuncTypeParams(v, n)
165 if n.Params != nil {
166 Walk(v, n.Params)
167 }
168 if n.Results != nil {
169 Walk(v, n.Results)
170 }
171
172 case *InterfaceType:
173 Walk(v, n.Methods)
174
175 case *MapType:
176 Walk(v, n.Key)
177 Walk(v, n.Value)
178
179 case *ChanType:
180 Walk(v, n.Value)
181
182
183 case *BadStmt:
184
185
186 case *DeclStmt:
187 Walk(v, n.Decl)
188
189 case *EmptyStmt:
190
191
192 case *LabeledStmt:
193 Walk(v, n.Label)
194 Walk(v, n.Stmt)
195
196 case *ExprStmt:
197 Walk(v, n.X)
198
199 case *SendStmt:
200 Walk(v, n.Chan)
201 Walk(v, n.Value)
202
203 case *IncDecStmt:
204 Walk(v, n.X)
205
206 case *AssignStmt:
207 walkExprList(v, n.Lhs)
208 walkExprList(v, n.Rhs)
209
210 case *GoStmt:
211 Walk(v, n.Call)
212
213 case *DeferStmt:
214 Walk(v, n.Call)
215
216 case *ReturnStmt:
217 walkExprList(v, n.Results)
218
219 case *BranchStmt:
220 if n.Label != nil {
221 Walk(v, n.Label)
222 }
223
224 case *BlockStmt:
225 walkStmtList(v, n.List)
226
227 case *IfStmt:
228 if n.Init != nil {
229 Walk(v, n.Init)
230 }
231 Walk(v, n.Cond)
232 Walk(v, n.Body)
233 if n.Else != nil {
234 Walk(v, n.Else)
235 }
236
237 case *CaseClause:
238 walkExprList(v, n.List)
239 walkStmtList(v, n.Body)
240
241 case *SwitchStmt:
242 if n.Init != nil {
243 Walk(v, n.Init)
244 }
245 if n.Tag != nil {
246 Walk(v, n.Tag)
247 }
248 Walk(v, n.Body)
249
250 case *TypeSwitchStmt:
251 if n.Init != nil {
252 Walk(v, n.Init)
253 }
254 Walk(v, n.Assign)
255 Walk(v, n.Body)
256
257 case *CommClause:
258 if n.Comm != nil {
259 Walk(v, n.Comm)
260 }
261 walkStmtList(v, n.Body)
262
263 case *SelectStmt:
264 Walk(v, n.Body)
265
266 case *ForStmt:
267 if n.Init != nil {
268 Walk(v, n.Init)
269 }
270 if n.Cond != nil {
271 Walk(v, n.Cond)
272 }
273 if n.Post != nil {
274 Walk(v, n.Post)
275 }
276 Walk(v, n.Body)
277
278 case *RangeStmt:
279 if n.Key != nil {
280 Walk(v, n.Key)
281 }
282 if n.Value != nil {
283 Walk(v, n.Value)
284 }
285 Walk(v, n.X)
286 Walk(v, n.Body)
287
288
289 case *ImportSpec:
290 if n.Doc != nil {
291 Walk(v, n.Doc)
292 }
293 if n.Name != nil {
294 Walk(v, n.Name)
295 }
296 Walk(v, n.Path)
297 if n.Comment != nil {
298 Walk(v, n.Comment)
299 }
300
301 case *ValueSpec:
302 if n.Doc != nil {
303 Walk(v, n.Doc)
304 }
305 walkIdentList(v, n.Names)
306 if n.Type != nil {
307 Walk(v, n.Type)
308 }
309 walkExprList(v, n.Values)
310 if n.Comment != nil {
311 Walk(v, n.Comment)
312 }
313
314 case *TypeSpec:
315 if n.Doc != nil {
316 Walk(v, n.Doc)
317 }
318 Walk(v, n.Name)
319 walkTypeSpecParams(v, n)
320 Walk(v, n.Type)
321 if n.Comment != nil {
322 Walk(v, n.Comment)
323 }
324
325 case *BadDecl:
326
327
328 case *GenDecl:
329 if n.Doc != nil {
330 Walk(v, n.Doc)
331 }
332 for _, s := range n.Specs {
333 Walk(v, s)
334 }
335
336 case *FuncDecl:
337 if n.Doc != nil {
338 Walk(v, n.Doc)
339 }
340 if n.Recv != nil {
341 Walk(v, n.Recv)
342 }
343 Walk(v, n.Name)
344 Walk(v, n.Type)
345 if n.Body != nil {
346 Walk(v, n.Body)
347 }
348
349
350 case *File:
351 if n.Doc != nil {
352 Walk(v, n.Doc)
353 }
354 Walk(v, n.Name)
355 walkDeclList(v, n.Decls)
356
357
358
359
360 case *Package:
361 for _, f := range n.Files {
362 Walk(v, f)
363 }
364
365 default:
366 walkOtherNodes(v, n)
367 }
368
369 v.Visit(nil)
370 }
371
372 type inspector func(Node) bool
373
374 func (f inspector) Visit(node Node) Visitor {
375 if f(node) {
376 return f
377 }
378 return nil
379 }
380
381
382
383
384
385
386 func Inspect(node Node, f func(Node) bool) {
387 Walk(inspector(f), node)
388 }
389
View as plain text