some deletions
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / analysis / passes / ctrlflow / ctrlflow.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/analysis/passes/ctrlflow/ctrlflow.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/analysis/passes/ctrlflow/ctrlflow.go
deleted file mode 100644 (file)
index 51600ff..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package ctrlflow is an analysis that provides a syntactic
-// control-flow graph (CFG) for the body of a function.
-// It records whether a function cannot return.
-// By itself, it does not report any diagnostics.
-package ctrlflow
-
-import (
-       "go/ast"
-       "go/types"
-       "log"
-       "reflect"
-
-       "golang.org/x/tools/go/analysis"
-       "golang.org/x/tools/go/analysis/passes/inspect"
-       "golang.org/x/tools/go/ast/inspector"
-       "golang.org/x/tools/go/cfg"
-       "golang.org/x/tools/go/types/typeutil"
-)
-
-var Analyzer = &analysis.Analyzer{
-       Name:       "ctrlflow",
-       Doc:        "build a control-flow graph",
-       Run:        run,
-       ResultType: reflect.TypeOf(new(CFGs)),
-       FactTypes:  []analysis.Fact{new(noReturn)},
-       Requires:   []*analysis.Analyzer{inspect.Analyzer},
-}
-
-// noReturn is a fact indicating that a function does not return.
-type noReturn struct{}
-
-func (*noReturn) AFact() {}
-
-func (*noReturn) String() string { return "noReturn" }
-
-// A CFGs holds the control-flow graphs
-// for all the functions of the current package.
-type CFGs struct {
-       defs      map[*ast.Ident]types.Object // from Pass.TypesInfo.Defs
-       funcDecls map[*types.Func]*declInfo
-       funcLits  map[*ast.FuncLit]*litInfo
-       pass      *analysis.Pass // transient; nil after construction
-}
-
-// CFGs has two maps: funcDecls for named functions and funcLits for
-// unnamed ones. Unlike funcLits, the funcDecls map is not keyed by its
-// syntax node, *ast.FuncDecl, because callMayReturn needs to do a
-// look-up by *types.Func, and you can get from an *ast.FuncDecl to a
-// *types.Func but not the other way.
-
-type declInfo struct {
-       decl     *ast.FuncDecl
-       cfg      *cfg.CFG // iff decl.Body != nil
-       started  bool     // to break cycles
-       noReturn bool
-}
-
-type litInfo struct {
-       cfg      *cfg.CFG
-       noReturn bool
-}
-
-// FuncDecl returns the control-flow graph for a named function.
-// It returns nil if decl.Body==nil.
-func (c *CFGs) FuncDecl(decl *ast.FuncDecl) *cfg.CFG {
-       if decl.Body == nil {
-               return nil
-       }
-       fn := c.defs[decl.Name].(*types.Func)
-       return c.funcDecls[fn].cfg
-}
-
-// FuncLit returns the control-flow graph for a literal function.
-func (c *CFGs) FuncLit(lit *ast.FuncLit) *cfg.CFG {
-       return c.funcLits[lit].cfg
-}
-
-func run(pass *analysis.Pass) (interface{}, error) {
-       inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
-
-       // Because CFG construction consumes and produces noReturn
-       // facts, CFGs for exported FuncDecls must be built before 'run'
-       // returns; we cannot construct them lazily.
-       // (We could build CFGs for FuncLits lazily,
-       // but the benefit is marginal.)
-
-       // Pass 1. Map types.Funcs to ast.FuncDecls in this package.
-       funcDecls := make(map[*types.Func]*declInfo) // functions and methods
-       funcLits := make(map[*ast.FuncLit]*litInfo)
-
-       var decls []*types.Func // keys(funcDecls), in order
-       var lits []*ast.FuncLit // keys(funcLits), in order
-
-       nodeFilter := []ast.Node{
-               (*ast.FuncDecl)(nil),
-               (*ast.FuncLit)(nil),
-       }
-       inspect.Preorder(nodeFilter, func(n ast.Node) {
-               switch n := n.(type) {
-               case *ast.FuncDecl:
-                       // Type information may be incomplete.
-                       if fn, ok := pass.TypesInfo.Defs[n.Name].(*types.Func); ok {
-                               funcDecls[fn] = &declInfo{decl: n}
-                               decls = append(decls, fn)
-                       }
-               case *ast.FuncLit:
-                       funcLits[n] = new(litInfo)
-                       lits = append(lits, n)
-               }
-       })
-
-       c := &CFGs{
-               defs:      pass.TypesInfo.Defs,
-               funcDecls: funcDecls,
-               funcLits:  funcLits,
-               pass:      pass,
-       }
-
-       // Pass 2. Build CFGs.
-
-       // Build CFGs for named functions.
-       // Cycles in the static call graph are broken
-       // arbitrarily but deterministically.
-       // We create noReturn facts as discovered.
-       for _, fn := range decls {
-               c.buildDecl(fn, funcDecls[fn])
-       }
-
-       // Build CFGs for literal functions.
-       // These aren't relevant to facts (since they aren't named)
-       // but are required for the CFGs.FuncLit API.
-       for _, lit := range lits {
-               li := funcLits[lit]
-               if li.cfg == nil {
-                       li.cfg = cfg.New(lit.Body, c.callMayReturn)
-                       if !hasReachableReturn(li.cfg) {
-                               li.noReturn = true
-                       }
-               }
-       }
-
-       // All CFGs are now built.
-       c.pass = nil
-
-       return c, nil
-}
-
-// di.cfg may be nil on return.
-func (c *CFGs) buildDecl(fn *types.Func, di *declInfo) {
-       // buildDecl may call itself recursively for the same function,
-       // because cfg.New is passed the callMayReturn method, which
-       // builds the CFG of the callee, leading to recursion.
-       // The buildDecl call tree thus resembles the static call graph.
-       // We mark each node when we start working on it to break cycles.
-
-       if !di.started { // break cycle
-               di.started = true
-
-               if isIntrinsicNoReturn(fn) {
-                       di.noReturn = true
-               }
-               if di.decl.Body != nil {
-                       di.cfg = cfg.New(di.decl.Body, c.callMayReturn)
-                       if !hasReachableReturn(di.cfg) {
-                               di.noReturn = true
-                       }
-               }
-               if di.noReturn {
-                       c.pass.ExportObjectFact(fn, new(noReturn))
-               }
-
-               // debugging
-               if false {
-                       log.Printf("CFG for %s:\n%s (noreturn=%t)\n", fn, di.cfg.Format(c.pass.Fset), di.noReturn)
-               }
-       }
-}
-
-// callMayReturn reports whether the called function may return.
-// It is passed to the CFG builder.
-func (c *CFGs) callMayReturn(call *ast.CallExpr) (r bool) {
-       if id, ok := call.Fun.(*ast.Ident); ok && c.pass.TypesInfo.Uses[id] == panicBuiltin {
-               return false // panic never returns
-       }
-
-       // Is this a static call?
-       fn := typeutil.StaticCallee(c.pass.TypesInfo, call)
-       if fn == nil {
-               return true // callee not statically known; be conservative
-       }
-
-       // Function or method declared in this package?
-       if di, ok := c.funcDecls[fn]; ok {
-               c.buildDecl(fn, di)
-               return !di.noReturn
-       }
-
-       // Not declared in this package.
-       // Is there a fact from another package?
-       return !c.pass.ImportObjectFact(fn, new(noReturn))
-}
-
-var panicBuiltin = types.Universe.Lookup("panic").(*types.Builtin)
-
-func hasReachableReturn(g *cfg.CFG) bool {
-       for _, b := range g.Blocks {
-               if b.Live && b.Return() != nil {
-                       return true
-               }
-       }
-       return false
-}
-
-// isIntrinsicNoReturn reports whether a function intrinsically never
-// returns because it stops execution of the calling thread.
-// It is the base case in the recursion.
-func isIntrinsicNoReturn(fn *types.Func) bool {
-       // Add functions here as the need arises, but don't allocate memory.
-       path, name := fn.Pkg().Path(), fn.Name()
-       return path == "syscall" && (name == "Exit" || name == "ExitProcess" || name == "ExitThread") ||
-               path == "runtime" && name == "Goexit"
-}