some deletions
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / cmd / guru / whicherrs.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/cmd/guru/whicherrs.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/cmd/guru/whicherrs.go
deleted file mode 100644 (file)
index 3a81bf5..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-// Copyright 2014 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 main
-
-import (
-       "fmt"
-       "go/ast"
-       "go/token"
-       "go/types"
-       "sort"
-
-       "golang.org/x/tools/cmd/guru/serial"
-       "golang.org/x/tools/go/ast/astutil"
-       "golang.org/x/tools/go/loader"
-       "golang.org/x/tools/go/pointer"
-       "golang.org/x/tools/go/ssa"
-       "golang.org/x/tools/go/ssa/ssautil"
-)
-
-var builtinErrorType = types.Universe.Lookup("error").Type()
-
-// whicherrs takes an position to an error and tries to find all types, constants
-// and global value which a given error can point to and which can be checked from the
-// scope where the error lives.
-// In short, it returns a list of things that can be checked against in order to handle
-// an error properly.
-//
-// TODO(dmorsing): figure out if fields in errors like *os.PathError.Err
-// can be queried recursively somehow.
-func whicherrs(q *Query) error {
-       lconf := loader.Config{Build: q.Build}
-
-       if err := setPTAScope(&lconf, q.Scope); err != nil {
-               return err
-       }
-
-       // Load/parse/type-check the program.
-       lprog, err := loadWithSoftErrors(&lconf)
-       if err != nil {
-               return err
-       }
-
-       qpos, err := parseQueryPos(lprog, q.Pos, true) // needs exact pos
-       if err != nil {
-               return err
-       }
-
-       prog := ssautil.CreateProgram(lprog, ssa.GlobalDebug)
-
-       ptaConfig, err := setupPTA(prog, lprog, q.PTALog, q.Reflection)
-       if err != nil {
-               return err
-       }
-
-       path, action := findInterestingNode(qpos.info, qpos.path)
-       if action != actionExpr {
-               return fmt.Errorf("whicherrs wants an expression; got %s",
-                       astutil.NodeDescription(qpos.path[0]))
-       }
-       var expr ast.Expr
-       var obj types.Object
-       switch n := path[0].(type) {
-       case *ast.ValueSpec:
-               // ambiguous ValueSpec containing multiple names
-               return fmt.Errorf("multiple value specification")
-       case *ast.Ident:
-               obj = qpos.info.ObjectOf(n)
-               expr = n
-       case ast.Expr:
-               expr = n
-       default:
-               return fmt.Errorf("unexpected AST for expr: %T", n)
-       }
-
-       typ := qpos.info.TypeOf(expr)
-       if !types.Identical(typ, builtinErrorType) {
-               return fmt.Errorf("selection is not an expression of type 'error'")
-       }
-       // Determine the ssa.Value for the expression.
-       var value ssa.Value
-       if obj != nil {
-               // def/ref of func/var object
-               value, _, err = ssaValueForIdent(prog, qpos.info, obj, path)
-       } else {
-               value, _, err = ssaValueForExpr(prog, qpos.info, path)
-       }
-       if err != nil {
-               return err // e.g. trivially dead code
-       }
-
-       // Defer SSA construction till after errors are reported.
-       prog.Build()
-
-       globals := findVisibleErrs(prog, qpos)
-       constants := findVisibleConsts(prog, qpos)
-
-       res := &whicherrsResult{
-               qpos:   qpos,
-               errpos: expr.Pos(),
-       }
-
-       // TODO(adonovan): the following code is heavily duplicated
-       // w.r.t.  "pointsto".  Refactor?
-
-       // Find the instruction which initialized the
-       // global error. If more than one instruction has stored to the global
-       // remove the global from the set of values that we want to query.
-       allFuncs := ssautil.AllFunctions(prog)
-       for fn := range allFuncs {
-               for _, b := range fn.Blocks {
-                       for _, instr := range b.Instrs {
-                               store, ok := instr.(*ssa.Store)
-                               if !ok {
-                                       continue
-                               }
-                               gval, ok := store.Addr.(*ssa.Global)
-                               if !ok {
-                                       continue
-                               }
-                               gbl, ok := globals[gval]
-                               if !ok {
-                                       continue
-                               }
-                               // we already found a store to this global
-                               // The normal error define is just one store in the init
-                               // so we just remove this global from the set we want to query
-                               if gbl != nil {
-                                       delete(globals, gval)
-                               }
-                               globals[gval] = store.Val
-                       }
-               }
-       }
-
-       ptaConfig.AddQuery(value)
-       for _, v := range globals {
-               ptaConfig.AddQuery(v)
-       }
-
-       ptares := ptrAnalysis(ptaConfig)
-       valueptr := ptares.Queries[value]
-       if valueptr == (pointer.Pointer{}) {
-               return fmt.Errorf("pointer analysis did not find expression (dead code?)")
-       }
-       for g, v := range globals {
-               ptr, ok := ptares.Queries[v]
-               if !ok {
-                       continue
-               }
-               if !ptr.MayAlias(valueptr) {
-                       continue
-               }
-               res.globals = append(res.globals, g)
-       }
-       pts := valueptr.PointsTo()
-       dedup := make(map[*ssa.NamedConst]bool)
-       for _, label := range pts.Labels() {
-               // These values are either MakeInterfaces or reflect
-               // generated interfaces. For the purposes of this
-               // analysis, we don't care about reflect generated ones
-               makeiface, ok := label.Value().(*ssa.MakeInterface)
-               if !ok {
-                       continue
-               }
-               constval, ok := makeiface.X.(*ssa.Const)
-               if !ok {
-                       continue
-               }
-               c := constants[*constval]
-               if c != nil && !dedup[c] {
-                       dedup[c] = true
-                       res.consts = append(res.consts, c)
-               }
-       }
-       concs := pts.DynamicTypes()
-       concs.Iterate(func(conc types.Type, _ interface{}) {
-               // go/types is a bit annoying here.
-               // We want to find all the types that we can
-               // typeswitch or assert to. This means finding out
-               // if the type pointed to can be seen by us.
-               //
-               // For the purposes of this analysis, we care only about
-               // TypeNames of Named or pointer-to-Named types.
-               // We ignore other types (e.g. structs) that implement error.
-               var name *types.TypeName
-               switch t := conc.(type) {
-               case *types.Pointer:
-                       named, ok := t.Elem().(*types.Named)
-                       if !ok {
-                               return
-                       }
-                       name = named.Obj()
-               case *types.Named:
-                       name = t.Obj()
-               default:
-                       return
-               }
-               if !isAccessibleFrom(name, qpos.info.Pkg) {
-                       return
-               }
-               res.types = append(res.types, &errorType{conc, name})
-       })
-       sort.Sort(membersByPosAndString(res.globals))
-       sort.Sort(membersByPosAndString(res.consts))
-       sort.Sort(sorterrorType(res.types))
-
-       q.Output(lprog.Fset, res)
-       return nil
-}
-
-// findVisibleErrs returns a mapping from each package-level variable of type "error" to nil.
-func findVisibleErrs(prog *ssa.Program, qpos *queryPos) map[*ssa.Global]ssa.Value {
-       globals := make(map[*ssa.Global]ssa.Value)
-       for _, pkg := range prog.AllPackages() {
-               for _, mem := range pkg.Members {
-                       gbl, ok := mem.(*ssa.Global)
-                       if !ok {
-                               continue
-                       }
-                       gbltype := gbl.Type()
-                       // globals are always pointers
-                       if !types.Identical(deref(gbltype), builtinErrorType) {
-                               continue
-                       }
-                       if !isAccessibleFrom(gbl.Object(), qpos.info.Pkg) {
-                               continue
-                       }
-                       globals[gbl] = nil
-               }
-       }
-       return globals
-}
-
-// findVisibleConsts returns a mapping from each package-level constant assignable to type "error", to nil.
-func findVisibleConsts(prog *ssa.Program, qpos *queryPos) map[ssa.Const]*ssa.NamedConst {
-       constants := make(map[ssa.Const]*ssa.NamedConst)
-       for _, pkg := range prog.AllPackages() {
-               for _, mem := range pkg.Members {
-                       obj, ok := mem.(*ssa.NamedConst)
-                       if !ok {
-                               continue
-                       }
-                       consttype := obj.Type()
-                       if !types.AssignableTo(consttype, builtinErrorType) {
-                               continue
-                       }
-                       if !isAccessibleFrom(obj.Object(), qpos.info.Pkg) {
-                               continue
-                       }
-                       constants[*obj.Value] = obj
-               }
-       }
-
-       return constants
-}
-
-type membersByPosAndString []ssa.Member
-
-func (a membersByPosAndString) Len() int { return len(a) }
-func (a membersByPosAndString) Less(i, j int) bool {
-       cmp := a[i].Pos() - a[j].Pos()
-       return cmp < 0 || cmp == 0 && a[i].String() < a[j].String()
-}
-func (a membersByPosAndString) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
-type sorterrorType []*errorType
-
-func (a sorterrorType) Len() int { return len(a) }
-func (a sorterrorType) Less(i, j int) bool {
-       cmp := a[i].obj.Pos() - a[j].obj.Pos()
-       return cmp < 0 || cmp == 0 && a[i].typ.String() < a[j].typ.String()
-}
-func (a sorterrorType) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
-type errorType struct {
-       typ types.Type      // concrete type N or *N that implements error
-       obj *types.TypeName // the named type N
-}
-
-type whicherrsResult struct {
-       qpos    *queryPos
-       errpos  token.Pos
-       globals []ssa.Member
-       consts  []ssa.Member
-       types   []*errorType
-}
-
-func (r *whicherrsResult) PrintPlain(printf printfFunc) {
-       if len(r.globals) > 0 {
-               printf(r.qpos, "this error may point to these globals:")
-               for _, g := range r.globals {
-                       printf(g.Pos(), "\t%s", g.RelString(r.qpos.info.Pkg))
-               }
-       }
-       if len(r.consts) > 0 {
-               printf(r.qpos, "this error may contain these constants:")
-               for _, c := range r.consts {
-                       printf(c.Pos(), "\t%s", c.RelString(r.qpos.info.Pkg))
-               }
-       }
-       if len(r.types) > 0 {
-               printf(r.qpos, "this error may contain these dynamic types:")
-               for _, t := range r.types {
-                       printf(t.obj.Pos(), "\t%s", r.qpos.typeString(t.typ))
-               }
-       }
-}
-
-func (r *whicherrsResult) JSON(fset *token.FileSet) []byte {
-       we := &serial.WhichErrs{}
-       we.ErrPos = fset.Position(r.errpos).String()
-       for _, g := range r.globals {
-               we.Globals = append(we.Globals, fset.Position(g.Pos()).String())
-       }
-       for _, c := range r.consts {
-               we.Constants = append(we.Constants, fset.Position(c.Pos()).String())
-       }
-       for _, t := range r.types {
-               var et serial.WhichErrsType
-               et.Type = r.qpos.typeString(t.typ)
-               et.Position = fset.Position(t.obj.Pos()).String()
-               we.Types = append(we.Types, et)
-       }
-       return toJSON(we)
-}