Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / go / ast / inspector / typeof.go
1 package inspector
2
3 // This file defines func typeOf(ast.Node) uint64.
4 //
5 // The initial map-based implementation was too slow;
6 // see https://go-review.googlesource.com/c/tools/+/135655/1/go/ast/inspector/inspector.go#196
7
8 import "go/ast"
9
10 const (
11         nArrayType = iota
12         nAssignStmt
13         nBadDecl
14         nBadExpr
15         nBadStmt
16         nBasicLit
17         nBinaryExpr
18         nBlockStmt
19         nBranchStmt
20         nCallExpr
21         nCaseClause
22         nChanType
23         nCommClause
24         nComment
25         nCommentGroup
26         nCompositeLit
27         nDeclStmt
28         nDeferStmt
29         nEllipsis
30         nEmptyStmt
31         nExprStmt
32         nField
33         nFieldList
34         nFile
35         nForStmt
36         nFuncDecl
37         nFuncLit
38         nFuncType
39         nGenDecl
40         nGoStmt
41         nIdent
42         nIfStmt
43         nImportSpec
44         nIncDecStmt
45         nIndexExpr
46         nInterfaceType
47         nKeyValueExpr
48         nLabeledStmt
49         nMapType
50         nPackage
51         nParenExpr
52         nRangeStmt
53         nReturnStmt
54         nSelectStmt
55         nSelectorExpr
56         nSendStmt
57         nSliceExpr
58         nStarExpr
59         nStructType
60         nSwitchStmt
61         nTypeAssertExpr
62         nTypeSpec
63         nTypeSwitchStmt
64         nUnaryExpr
65         nValueSpec
66 )
67
68 // typeOf returns a distinct single-bit value that represents the type of n.
69 //
70 // Various implementations were benchmarked with BenchmarkNewInspector:
71 //                                                              GOGC=off
72 // - type switch                                4.9-5.5ms       2.1ms
73 // - binary search over a sorted list of types  5.5-5.9ms       2.5ms
74 // - linear scan, frequency-ordered list        5.9-6.1ms       2.7ms
75 // - linear scan, unordered list                6.4ms           2.7ms
76 // - hash table                                 6.5ms           3.1ms
77 // A perfect hash seemed like overkill.
78 //
79 // The compiler's switch statement is the clear winner
80 // as it produces a binary tree in code,
81 // with constant conditions and good branch prediction.
82 // (Sadly it is the most verbose in source code.)
83 // Binary search suffered from poor branch prediction.
84 //
85 func typeOf(n ast.Node) uint64 {
86         // Fast path: nearly half of all nodes are identifiers.
87         if _, ok := n.(*ast.Ident); ok {
88                 return 1 << nIdent
89         }
90
91         // These cases include all nodes encountered by ast.Inspect.
92         switch n.(type) {
93         case *ast.ArrayType:
94                 return 1 << nArrayType
95         case *ast.AssignStmt:
96                 return 1 << nAssignStmt
97         case *ast.BadDecl:
98                 return 1 << nBadDecl
99         case *ast.BadExpr:
100                 return 1 << nBadExpr
101         case *ast.BadStmt:
102                 return 1 << nBadStmt
103         case *ast.BasicLit:
104                 return 1 << nBasicLit
105         case *ast.BinaryExpr:
106                 return 1 << nBinaryExpr
107         case *ast.BlockStmt:
108                 return 1 << nBlockStmt
109         case *ast.BranchStmt:
110                 return 1 << nBranchStmt
111         case *ast.CallExpr:
112                 return 1 << nCallExpr
113         case *ast.CaseClause:
114                 return 1 << nCaseClause
115         case *ast.ChanType:
116                 return 1 << nChanType
117         case *ast.CommClause:
118                 return 1 << nCommClause
119         case *ast.Comment:
120                 return 1 << nComment
121         case *ast.CommentGroup:
122                 return 1 << nCommentGroup
123         case *ast.CompositeLit:
124                 return 1 << nCompositeLit
125         case *ast.DeclStmt:
126                 return 1 << nDeclStmt
127         case *ast.DeferStmt:
128                 return 1 << nDeferStmt
129         case *ast.Ellipsis:
130                 return 1 << nEllipsis
131         case *ast.EmptyStmt:
132                 return 1 << nEmptyStmt
133         case *ast.ExprStmt:
134                 return 1 << nExprStmt
135         case *ast.Field:
136                 return 1 << nField
137         case *ast.FieldList:
138                 return 1 << nFieldList
139         case *ast.File:
140                 return 1 << nFile
141         case *ast.ForStmt:
142                 return 1 << nForStmt
143         case *ast.FuncDecl:
144                 return 1 << nFuncDecl
145         case *ast.FuncLit:
146                 return 1 << nFuncLit
147         case *ast.FuncType:
148                 return 1 << nFuncType
149         case *ast.GenDecl:
150                 return 1 << nGenDecl
151         case *ast.GoStmt:
152                 return 1 << nGoStmt
153         case *ast.Ident:
154                 return 1 << nIdent
155         case *ast.IfStmt:
156                 return 1 << nIfStmt
157         case *ast.ImportSpec:
158                 return 1 << nImportSpec
159         case *ast.IncDecStmt:
160                 return 1 << nIncDecStmt
161         case *ast.IndexExpr:
162                 return 1 << nIndexExpr
163         case *ast.InterfaceType:
164                 return 1 << nInterfaceType
165         case *ast.KeyValueExpr:
166                 return 1 << nKeyValueExpr
167         case *ast.LabeledStmt:
168                 return 1 << nLabeledStmt
169         case *ast.MapType:
170                 return 1 << nMapType
171         case *ast.Package:
172                 return 1 << nPackage
173         case *ast.ParenExpr:
174                 return 1 << nParenExpr
175         case *ast.RangeStmt:
176                 return 1 << nRangeStmt
177         case *ast.ReturnStmt:
178                 return 1 << nReturnStmt
179         case *ast.SelectStmt:
180                 return 1 << nSelectStmt
181         case *ast.SelectorExpr:
182                 return 1 << nSelectorExpr
183         case *ast.SendStmt:
184                 return 1 << nSendStmt
185         case *ast.SliceExpr:
186                 return 1 << nSliceExpr
187         case *ast.StarExpr:
188                 return 1 << nStarExpr
189         case *ast.StructType:
190                 return 1 << nStructType
191         case *ast.SwitchStmt:
192                 return 1 << nSwitchStmt
193         case *ast.TypeAssertExpr:
194                 return 1 << nTypeAssertExpr
195         case *ast.TypeSpec:
196                 return 1 << nTypeSpec
197         case *ast.TypeSwitchStmt:
198                 return 1 << nTypeSwitchStmt
199         case *ast.UnaryExpr:
200                 return 1 << nUnaryExpr
201         case *ast.ValueSpec:
202                 return 1 << nValueSpec
203         }
204         return 0
205 }
206
207 func maskOf(nodes []ast.Node) uint64 {
208         if nodes == nil {
209                 return 1<<64 - 1 // match all node types
210         }
211         var mask uint64
212         for _, n := range nodes {
213                 mask |= typeOf(n)
214         }
215         return mask
216 }