1
2
3
4
5
6
7 package syntax
8
9
10 func StartPos(n Node) Pos {
11
12 for m := n; ; {
13 switch n := m.(type) {
14 case nil:
15 panic("nil node")
16
17
18 case *File:
19
20 return MakePos(n.Pos().Base(), 1, 1)
21
22
23
24
25
26
27
28
29
30
31
32
33 case *CompositeLit:
34 if n.Type != nil {
35 m = n.Type
36 continue
37 }
38 return n.Pos()
39 case *KeyValueExpr:
40 m = n.Key
41
42
43 case *SelectorExpr:
44 m = n.X
45 case *IndexExpr:
46 m = n.X
47
48 case *AssertExpr:
49 m = n.X
50 case *TypeSwitchGuard:
51 if n.Lhs != nil {
52 m = n.Lhs
53 continue
54 }
55 m = n.X
56 case *Operation:
57 if n.Y != nil {
58 m = n.X
59 continue
60 }
61 return n.Pos()
62 case *CallExpr:
63 m = n.Fun
64 case *ListExpr:
65 if len(n.ElemList) > 0 {
66 m = n.ElemList[0]
67 continue
68 }
69 return n.Pos()
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 case *SendStmt:
87 m = n.Chan
88
89 case *AssignStmt:
90 m = n.Lhs
91
92
93
94
95
96
97
98
99
100 case *RangeClause:
101 if n.Lhs != nil {
102 m = n.Lhs
103 continue
104 }
105 m = n.X
106
107
108
109 default:
110 return n.Pos()
111 }
112 }
113 }
114
115
116
117
118
119
120
121
122
123
124 func EndPos(n Node) Pos {
125 for m := n; ; {
126 switch n := m.(type) {
127 case nil:
128 panic("nil node")
129
130
131 case *File:
132 return n.EOF
133
134
135 case *ImportDecl:
136 m = n.Path
137 case *ConstDecl:
138 if n.Values != nil {
139 m = n.Values
140 continue
141 }
142 if n.Type != nil {
143 m = n.Type
144 continue
145 }
146 if l := len(n.NameList); l > 0 {
147 m = n.NameList[l-1]
148 continue
149 }
150 return n.Pos()
151 case *TypeDecl:
152 m = n.Type
153 case *VarDecl:
154 if n.Values != nil {
155 m = n.Values
156 continue
157 }
158 if n.Type != nil {
159 m = n.Type
160 continue
161 }
162 if l := len(n.NameList); l > 0 {
163 m = n.NameList[l-1]
164 continue
165 }
166 return n.Pos()
167 case *FuncDecl:
168 if n.Body != nil {
169 m = n.Body
170 continue
171 }
172 m = n.Type
173
174
175 case *BadExpr:
176 return n.Pos()
177 case *Name:
178 p := n.Pos()
179 return MakePos(p.Base(), p.Line(), p.Col()+uint(len(n.Value)))
180 case *BasicLit:
181 p := n.Pos()
182 return MakePos(p.Base(), p.Line(), p.Col()+uint(len(n.Value)))
183 case *CompositeLit:
184 return n.Rbrace
185 case *KeyValueExpr:
186 m = n.Value
187 case *FuncLit:
188 m = n.Body
189 case *ParenExpr:
190 m = n.X
191 case *SelectorExpr:
192 m = n.Sel
193 case *IndexExpr:
194 m = n.Index
195 case *SliceExpr:
196 for i := len(n.Index) - 1; i >= 0; i-- {
197 if x := n.Index[i]; x != nil {
198 m = x
199 continue
200 }
201 }
202 m = n.X
203 case *AssertExpr:
204 m = n.Type
205 case *TypeSwitchGuard:
206 m = n.X
207 case *Operation:
208 if n.Y != nil {
209 m = n.Y
210 continue
211 }
212 m = n.X
213 case *CallExpr:
214 if l := lastExpr(n.ArgList); l != nil {
215 m = l
216 continue
217 }
218 m = n.Fun
219 case *ListExpr:
220 if l := lastExpr(n.ElemList); l != nil {
221 m = l
222 continue
223 }
224 return n.Pos()
225
226
227 case *ArrayType:
228 m = n.Elem
229 case *SliceType:
230 m = n.Elem
231 case *DotsType:
232 m = n.Elem
233 case *StructType:
234 if l := lastField(n.FieldList); l != nil {
235 m = l
236 continue
237 }
238 return n.Pos()
239
240 case *Field:
241 if n.Type != nil {
242 m = n.Type
243 continue
244 }
245 m = n.Name
246 case *InterfaceType:
247 if l := lastField(n.MethodList); l != nil {
248 m = l
249 continue
250 }
251 return n.Pos()
252 case *FuncType:
253 if l := lastField(n.ResultList); l != nil {
254 m = l
255 continue
256 }
257 if l := lastField(n.ParamList); l != nil {
258 m = l
259 continue
260 }
261 return n.Pos()
262 case *MapType:
263 m = n.Value
264 case *ChanType:
265 m = n.Elem
266
267
268 case *EmptyStmt:
269 return n.Pos()
270 case *LabeledStmt:
271 m = n.Stmt
272 case *BlockStmt:
273 return n.Rbrace
274 case *ExprStmt:
275 m = n.X
276 case *SendStmt:
277 m = n.Value
278 case *DeclStmt:
279 if l := lastDecl(n.DeclList); l != nil {
280 m = l
281 continue
282 }
283 return n.Pos()
284 case *AssignStmt:
285 m = n.Rhs
286 if m == nil {
287 p := EndPos(n.Lhs)
288 return MakePos(p.Base(), p.Line(), p.Col()+2)
289 }
290 case *BranchStmt:
291 if n.Label != nil {
292 m = n.Label
293 continue
294 }
295 return n.Pos()
296 case *CallStmt:
297 m = n.Call
298 case *ReturnStmt:
299 if n.Results != nil {
300 m = n.Results
301 continue
302 }
303 return n.Pos()
304 case *IfStmt:
305 if n.Else != nil {
306 m = n.Else
307 continue
308 }
309 m = n.Then
310 case *ForStmt:
311 m = n.Body
312 case *SwitchStmt:
313 return n.Rbrace
314 case *SelectStmt:
315 return n.Rbrace
316
317
318 case *RangeClause:
319 m = n.X
320 case *CaseClause:
321 if l := lastStmt(n.Body); l != nil {
322 m = l
323 continue
324 }
325 return n.Colon
326 case *CommClause:
327 if l := lastStmt(n.Body); l != nil {
328 m = l
329 continue
330 }
331 return n.Colon
332
333 default:
334 return n.Pos()
335 }
336 }
337 }
338
339 func lastDecl(list []Decl) Decl {
340 if l := len(list); l > 0 {
341 return list[l-1]
342 }
343 return nil
344 }
345
346 func lastExpr(list []Expr) Expr {
347 if l := len(list); l > 0 {
348 return list[l-1]
349 }
350 return nil
351 }
352
353 func lastStmt(list []Stmt) Stmt {
354 if l := len(list); l > 0 {
355 return list[l-1]
356 }
357 return nil
358 }
359
360 func lastField(list []*Field) *Field {
361 if l := len(list); l > 0 {
362 return list[l-1]
363 }
364 return nil
365 }
366
View as plain text