1
2
3
4
5
6
7 package edge
8
9 import (
10 "fmt"
11 "go/ast"
12 "reflect"
13 )
14
15
16 type Kind uint8
17
18
19 func (k Kind) String() string {
20 if k == Invalid {
21 return "<invalid>"
22 }
23 info := fieldInfos[k]
24 return fmt.Sprintf("%v.%s", info.nodeType.Elem().Name(), info.name)
25 }
26
27
28 func (k Kind) NodeType() reflect.Type { return fieldInfos[k].nodeType }
29
30
31 func (k Kind) FieldName() string { return fieldInfos[k].name }
32
33
34 func (k Kind) FieldType() reflect.Type { return fieldInfos[k].fieldType }
35
36
37
38
39 func (k Kind) Get(n ast.Node, idx int) ast.Node {
40 if k.NodeType() != reflect.TypeOf(n) {
41 panic(fmt.Sprintf("%v.Get(%T): invalid node type", k, n))
42 }
43 v := reflect.ValueOf(n).Elem().Field(fieldInfos[k].index)
44 if idx != -1 {
45 v = v.Index(idx)
46 } else {
47
48 }
49 return v.Interface().(ast.Node)
50 }
51
52 const (
53 Invalid Kind = iota
54
55
56
57
58
59
60 ArrayType_Elt
61 ArrayType_Len
62 AssignStmt_Lhs
63 AssignStmt_Rhs
64 BinaryExpr_X
65 BinaryExpr_Y
66 BlockStmt_List
67 BranchStmt_Label
68 CallExpr_Args
69 CallExpr_Fun
70 CaseClause_Body
71 CaseClause_List
72 ChanType_Value
73 CommClause_Body
74 CommClause_Comm
75 CommentGroup_List
76 CompositeLit_Elts
77 CompositeLit_Type
78 DeclStmt_Decl
79 DeferStmt_Call
80 Ellipsis_Elt
81 ExprStmt_X
82 FieldList_List
83 Field_Comment
84 Field_Doc
85 Field_Names
86 Field_Tag
87 Field_Type
88 File_Decls
89 File_Doc
90 File_Name
91 ForStmt_Body
92 ForStmt_Cond
93 ForStmt_Init
94 ForStmt_Post
95 FuncDecl_Body
96 FuncDecl_Doc
97 FuncDecl_Name
98 FuncDecl_Recv
99 FuncDecl_Type
100 FuncLit_Body
101 FuncLit_Type
102 FuncType_Params
103 FuncType_Results
104 FuncType_TypeParams
105 GenDecl_Doc
106 GenDecl_Specs
107 GoStmt_Call
108 IfStmt_Body
109 IfStmt_Cond
110 IfStmt_Else
111 IfStmt_Init
112 ImportSpec_Comment
113 ImportSpec_Doc
114 ImportSpec_Name
115 ImportSpec_Path
116 IncDecStmt_X
117 IndexExpr_Index
118 IndexExpr_X
119 IndexListExpr_Indices
120 IndexListExpr_X
121 InterfaceType_Methods
122 KeyValueExpr_Key
123 KeyValueExpr_Value
124 LabeledStmt_Label
125 LabeledStmt_Stmt
126 MapType_Key
127 MapType_Value
128 ParenExpr_X
129 RangeStmt_Body
130 RangeStmt_Key
131 RangeStmt_Value
132 RangeStmt_X
133 ReturnStmt_Results
134 SelectStmt_Body
135 SelectorExpr_Sel
136 SelectorExpr_X
137 SendStmt_Chan
138 SendStmt_Value
139 SliceExpr_High
140 SliceExpr_Low
141 SliceExpr_Max
142 SliceExpr_X
143 StarExpr_X
144 StructType_Fields
145 SwitchStmt_Body
146 SwitchStmt_Init
147 SwitchStmt_Tag
148 TypeAssertExpr_Type
149 TypeAssertExpr_X
150 TypeSpec_Comment
151 TypeSpec_Doc
152 TypeSpec_Name
153 TypeSpec_Type
154 TypeSpec_TypeParams
155 TypeSwitchStmt_Assign
156 TypeSwitchStmt_Body
157 TypeSwitchStmt_Init
158 UnaryExpr_X
159 ValueSpec_Comment
160 ValueSpec_Doc
161 ValueSpec_Names
162 ValueSpec_Type
163 ValueSpec_Values
164
165 maxKind
166 )
167
168
169
170
171 var _ = [1 << 7]struct{}{}[maxKind]
172
173 type fieldInfo struct {
174 nodeType reflect.Type
175 name string
176 index int
177 fieldType reflect.Type
178 }
179
180 func info[N ast.Node](fieldName string) fieldInfo {
181 nodePtrType := reflect.TypeFor[N]()
182 f, ok := nodePtrType.Elem().FieldByName(fieldName)
183 if !ok {
184 panic(fieldName)
185 }
186 return fieldInfo{nodePtrType, fieldName, f.Index[0], f.Type}
187 }
188
189 var fieldInfos = [...]fieldInfo{
190 Invalid: {},
191 ArrayType_Elt: info[*ast.ArrayType]("Elt"),
192 ArrayType_Len: info[*ast.ArrayType]("Len"),
193 AssignStmt_Lhs: info[*ast.AssignStmt]("Lhs"),
194 AssignStmt_Rhs: info[*ast.AssignStmt]("Rhs"),
195 BinaryExpr_X: info[*ast.BinaryExpr]("X"),
196 BinaryExpr_Y: info[*ast.BinaryExpr]("Y"),
197 BlockStmt_List: info[*ast.BlockStmt]("List"),
198 BranchStmt_Label: info[*ast.BranchStmt]("Label"),
199 CallExpr_Args: info[*ast.CallExpr]("Args"),
200 CallExpr_Fun: info[*ast.CallExpr]("Fun"),
201 CaseClause_Body: info[*ast.CaseClause]("Body"),
202 CaseClause_List: info[*ast.CaseClause]("List"),
203 ChanType_Value: info[*ast.ChanType]("Value"),
204 CommClause_Body: info[*ast.CommClause]("Body"),
205 CommClause_Comm: info[*ast.CommClause]("Comm"),
206 CommentGroup_List: info[*ast.CommentGroup]("List"),
207 CompositeLit_Elts: info[*ast.CompositeLit]("Elts"),
208 CompositeLit_Type: info[*ast.CompositeLit]("Type"),
209 DeclStmt_Decl: info[*ast.DeclStmt]("Decl"),
210 DeferStmt_Call: info[*ast.DeferStmt]("Call"),
211 Ellipsis_Elt: info[*ast.Ellipsis]("Elt"),
212 ExprStmt_X: info[*ast.ExprStmt]("X"),
213 FieldList_List: info[*ast.FieldList]("List"),
214 Field_Comment: info[*ast.Field]("Comment"),
215 Field_Doc: info[*ast.Field]("Doc"),
216 Field_Names: info[*ast.Field]("Names"),
217 Field_Tag: info[*ast.Field]("Tag"),
218 Field_Type: info[*ast.Field]("Type"),
219 File_Decls: info[*ast.File]("Decls"),
220 File_Doc: info[*ast.File]("Doc"),
221 File_Name: info[*ast.File]("Name"),
222 ForStmt_Body: info[*ast.ForStmt]("Body"),
223 ForStmt_Cond: info[*ast.ForStmt]("Cond"),
224 ForStmt_Init: info[*ast.ForStmt]("Init"),
225 ForStmt_Post: info[*ast.ForStmt]("Post"),
226 FuncDecl_Body: info[*ast.FuncDecl]("Body"),
227 FuncDecl_Doc: info[*ast.FuncDecl]("Doc"),
228 FuncDecl_Name: info[*ast.FuncDecl]("Name"),
229 FuncDecl_Recv: info[*ast.FuncDecl]("Recv"),
230 FuncDecl_Type: info[*ast.FuncDecl]("Type"),
231 FuncLit_Body: info[*ast.FuncLit]("Body"),
232 FuncLit_Type: info[*ast.FuncLit]("Type"),
233 FuncType_Params: info[*ast.FuncType]("Params"),
234 FuncType_Results: info[*ast.FuncType]("Results"),
235 FuncType_TypeParams: info[*ast.FuncType]("TypeParams"),
236 GenDecl_Doc: info[*ast.GenDecl]("Doc"),
237 GenDecl_Specs: info[*ast.GenDecl]("Specs"),
238 GoStmt_Call: info[*ast.GoStmt]("Call"),
239 IfStmt_Body: info[*ast.IfStmt]("Body"),
240 IfStmt_Cond: info[*ast.IfStmt]("Cond"),
241 IfStmt_Else: info[*ast.IfStmt]("Else"),
242 IfStmt_Init: info[*ast.IfStmt]("Init"),
243 ImportSpec_Comment: info[*ast.ImportSpec]("Comment"),
244 ImportSpec_Doc: info[*ast.ImportSpec]("Doc"),
245 ImportSpec_Name: info[*ast.ImportSpec]("Name"),
246 ImportSpec_Path: info[*ast.ImportSpec]("Path"),
247 IncDecStmt_X: info[*ast.IncDecStmt]("X"),
248 IndexExpr_Index: info[*ast.IndexExpr]("Index"),
249 IndexExpr_X: info[*ast.IndexExpr]("X"),
250 IndexListExpr_Indices: info[*ast.IndexListExpr]("Indices"),
251 IndexListExpr_X: info[*ast.IndexListExpr]("X"),
252 InterfaceType_Methods: info[*ast.InterfaceType]("Methods"),
253 KeyValueExpr_Key: info[*ast.KeyValueExpr]("Key"),
254 KeyValueExpr_Value: info[*ast.KeyValueExpr]("Value"),
255 LabeledStmt_Label: info[*ast.LabeledStmt]("Label"),
256 LabeledStmt_Stmt: info[*ast.LabeledStmt]("Stmt"),
257 MapType_Key: info[*ast.MapType]("Key"),
258 MapType_Value: info[*ast.MapType]("Value"),
259 ParenExpr_X: info[*ast.ParenExpr]("X"),
260 RangeStmt_Body: info[*ast.RangeStmt]("Body"),
261 RangeStmt_Key: info[*ast.RangeStmt]("Key"),
262 RangeStmt_Value: info[*ast.RangeStmt]("Value"),
263 RangeStmt_X: info[*ast.RangeStmt]("X"),
264 ReturnStmt_Results: info[*ast.ReturnStmt]("Results"),
265 SelectStmt_Body: info[*ast.SelectStmt]("Body"),
266 SelectorExpr_Sel: info[*ast.SelectorExpr]("Sel"),
267 SelectorExpr_X: info[*ast.SelectorExpr]("X"),
268 SendStmt_Chan: info[*ast.SendStmt]("Chan"),
269 SendStmt_Value: info[*ast.SendStmt]("Value"),
270 SliceExpr_High: info[*ast.SliceExpr]("High"),
271 SliceExpr_Low: info[*ast.SliceExpr]("Low"),
272 SliceExpr_Max: info[*ast.SliceExpr]("Max"),
273 SliceExpr_X: info[*ast.SliceExpr]("X"),
274 StarExpr_X: info[*ast.StarExpr]("X"),
275 StructType_Fields: info[*ast.StructType]("Fields"),
276 SwitchStmt_Body: info[*ast.SwitchStmt]("Body"),
277 SwitchStmt_Init: info[*ast.SwitchStmt]("Init"),
278 SwitchStmt_Tag: info[*ast.SwitchStmt]("Tag"),
279 TypeAssertExpr_Type: info[*ast.TypeAssertExpr]("Type"),
280 TypeAssertExpr_X: info[*ast.TypeAssertExpr]("X"),
281 TypeSpec_Comment: info[*ast.TypeSpec]("Comment"),
282 TypeSpec_Doc: info[*ast.TypeSpec]("Doc"),
283 TypeSpec_Name: info[*ast.TypeSpec]("Name"),
284 TypeSpec_Type: info[*ast.TypeSpec]("Type"),
285 TypeSpec_TypeParams: info[*ast.TypeSpec]("TypeParams"),
286 TypeSwitchStmt_Assign: info[*ast.TypeSwitchStmt]("Assign"),
287 TypeSwitchStmt_Body: info[*ast.TypeSwitchStmt]("Body"),
288 TypeSwitchStmt_Init: info[*ast.TypeSwitchStmt]("Init"),
289 UnaryExpr_X: info[*ast.UnaryExpr]("X"),
290 ValueSpec_Comment: info[*ast.ValueSpec]("Comment"),
291 ValueSpec_Doc: info[*ast.ValueSpec]("Doc"),
292 ValueSpec_Names: info[*ast.ValueSpec]("Names"),
293 ValueSpec_Type: info[*ast.ValueSpec]("Type"),
294 ValueSpec_Values: info[*ast.ValueSpec]("Values"),
295 }
296
View as plain text