Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / ast / inspector / typeof.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/ast/inspector/typeof.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/ast/inspector/typeof.go
new file mode 100644 (file)
index 0000000..d61301b
--- /dev/null
@@ -0,0 +1,216 @@
+package inspector
+
+// This file defines func typeOf(ast.Node) uint64.
+//
+// The initial map-based implementation was too slow;
+// see https://go-review.googlesource.com/c/tools/+/135655/1/go/ast/inspector/inspector.go#196
+
+import "go/ast"
+
+const (
+       nArrayType = iota
+       nAssignStmt
+       nBadDecl
+       nBadExpr
+       nBadStmt
+       nBasicLit
+       nBinaryExpr
+       nBlockStmt
+       nBranchStmt
+       nCallExpr
+       nCaseClause
+       nChanType
+       nCommClause
+       nComment
+       nCommentGroup
+       nCompositeLit
+       nDeclStmt
+       nDeferStmt
+       nEllipsis
+       nEmptyStmt
+       nExprStmt
+       nField
+       nFieldList
+       nFile
+       nForStmt
+       nFuncDecl
+       nFuncLit
+       nFuncType
+       nGenDecl
+       nGoStmt
+       nIdent
+       nIfStmt
+       nImportSpec
+       nIncDecStmt
+       nIndexExpr
+       nInterfaceType
+       nKeyValueExpr
+       nLabeledStmt
+       nMapType
+       nPackage
+       nParenExpr
+       nRangeStmt
+       nReturnStmt
+       nSelectStmt
+       nSelectorExpr
+       nSendStmt
+       nSliceExpr
+       nStarExpr
+       nStructType
+       nSwitchStmt
+       nTypeAssertExpr
+       nTypeSpec
+       nTypeSwitchStmt
+       nUnaryExpr
+       nValueSpec
+)
+
+// typeOf returns a distinct single-bit value that represents the type of n.
+//
+// Various implementations were benchmarked with BenchmarkNewInspector:
+//                                                             GOGC=off
+// - type switch                               4.9-5.5ms       2.1ms
+// - binary search over a sorted list of types  5.5-5.9ms      2.5ms
+// - linear scan, frequency-ordered list       5.9-6.1ms       2.7ms
+// - linear scan, unordered list               6.4ms           2.7ms
+// - hash table                                        6.5ms           3.1ms
+// A perfect hash seemed like overkill.
+//
+// The compiler's switch statement is the clear winner
+// as it produces a binary tree in code,
+// with constant conditions and good branch prediction.
+// (Sadly it is the most verbose in source code.)
+// Binary search suffered from poor branch prediction.
+//
+func typeOf(n ast.Node) uint64 {
+       // Fast path: nearly half of all nodes are identifiers.
+       if _, ok := n.(*ast.Ident); ok {
+               return 1 << nIdent
+       }
+
+       // These cases include all nodes encountered by ast.Inspect.
+       switch n.(type) {
+       case *ast.ArrayType:
+               return 1 << nArrayType
+       case *ast.AssignStmt:
+               return 1 << nAssignStmt
+       case *ast.BadDecl:
+               return 1 << nBadDecl
+       case *ast.BadExpr:
+               return 1 << nBadExpr
+       case *ast.BadStmt:
+               return 1 << nBadStmt
+       case *ast.BasicLit:
+               return 1 << nBasicLit
+       case *ast.BinaryExpr:
+               return 1 << nBinaryExpr
+       case *ast.BlockStmt:
+               return 1 << nBlockStmt
+       case *ast.BranchStmt:
+               return 1 << nBranchStmt
+       case *ast.CallExpr:
+               return 1 << nCallExpr
+       case *ast.CaseClause:
+               return 1 << nCaseClause
+       case *ast.ChanType:
+               return 1 << nChanType
+       case *ast.CommClause:
+               return 1 << nCommClause
+       case *ast.Comment:
+               return 1 << nComment
+       case *ast.CommentGroup:
+               return 1 << nCommentGroup
+       case *ast.CompositeLit:
+               return 1 << nCompositeLit
+       case *ast.DeclStmt:
+               return 1 << nDeclStmt
+       case *ast.DeferStmt:
+               return 1 << nDeferStmt
+       case *ast.Ellipsis:
+               return 1 << nEllipsis
+       case *ast.EmptyStmt:
+               return 1 << nEmptyStmt
+       case *ast.ExprStmt:
+               return 1 << nExprStmt
+       case *ast.Field:
+               return 1 << nField
+       case *ast.FieldList:
+               return 1 << nFieldList
+       case *ast.File:
+               return 1 << nFile
+       case *ast.ForStmt:
+               return 1 << nForStmt
+       case *ast.FuncDecl:
+               return 1 << nFuncDecl
+       case *ast.FuncLit:
+               return 1 << nFuncLit
+       case *ast.FuncType:
+               return 1 << nFuncType
+       case *ast.GenDecl:
+               return 1 << nGenDecl
+       case *ast.GoStmt:
+               return 1 << nGoStmt
+       case *ast.Ident:
+               return 1 << nIdent
+       case *ast.IfStmt:
+               return 1 << nIfStmt
+       case *ast.ImportSpec:
+               return 1 << nImportSpec
+       case *ast.IncDecStmt:
+               return 1 << nIncDecStmt
+       case *ast.IndexExpr:
+               return 1 << nIndexExpr
+       case *ast.InterfaceType:
+               return 1 << nInterfaceType
+       case *ast.KeyValueExpr:
+               return 1 << nKeyValueExpr
+       case *ast.LabeledStmt:
+               return 1 << nLabeledStmt
+       case *ast.MapType:
+               return 1 << nMapType
+       case *ast.Package:
+               return 1 << nPackage
+       case *ast.ParenExpr:
+               return 1 << nParenExpr
+       case *ast.RangeStmt:
+               return 1 << nRangeStmt
+       case *ast.ReturnStmt:
+               return 1 << nReturnStmt
+       case *ast.SelectStmt:
+               return 1 << nSelectStmt
+       case *ast.SelectorExpr:
+               return 1 << nSelectorExpr
+       case *ast.SendStmt:
+               return 1 << nSendStmt
+       case *ast.SliceExpr:
+               return 1 << nSliceExpr
+       case *ast.StarExpr:
+               return 1 << nStarExpr
+       case *ast.StructType:
+               return 1 << nStructType
+       case *ast.SwitchStmt:
+               return 1 << nSwitchStmt
+       case *ast.TypeAssertExpr:
+               return 1 << nTypeAssertExpr
+       case *ast.TypeSpec:
+               return 1 << nTypeSpec
+       case *ast.TypeSwitchStmt:
+               return 1 << nTypeSwitchStmt
+       case *ast.UnaryExpr:
+               return 1 << nUnaryExpr
+       case *ast.ValueSpec:
+               return 1 << nValueSpec
+       }
+       return 0
+}
+
+func maskOf(nodes []ast.Node) uint64 {
+       if nodes == nil {
+               return 1<<64 - 1 // match all node types
+       }
+       var mask uint64
+       for _, n := range nodes {
+               mask |= typeOf(n)
+       }
+       return mask
+}