some deletions
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / refactor / rename / rename.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/refactor/rename/rename.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/refactor/rename/rename.go
deleted file mode 100644 (file)
index 3651c62..0000000
+++ /dev/null
@@ -1,603 +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 rename contains the implementation of the 'gorename' command
-// whose main function is in golang.org/x/tools/cmd/gorename.
-// See the Usage constant for the command documentation.
-package rename // import "golang.org/x/tools/refactor/rename"
-
-import (
-       "bytes"
-       "errors"
-       "fmt"
-       "go/ast"
-       "go/build"
-       "go/format"
-       "go/parser"
-       "go/token"
-       "go/types"
-       "io"
-       "io/ioutil"
-       "log"
-       "os"
-       "os/exec"
-       "path"
-       "regexp"
-       "sort"
-       "strconv"
-       "strings"
-
-       "golang.org/x/tools/go/loader"
-       "golang.org/x/tools/go/types/typeutil"
-       "golang.org/x/tools/refactor/importgraph"
-       "golang.org/x/tools/refactor/satisfy"
-)
-
-const Usage = `gorename: precise type-safe renaming of identifiers in Go source code.
-
-Usage:
-
- gorename (-from <spec> | -offset <file>:#<byte-offset>) -to <name> [-force]
-
-You must specify the object (named entity) to rename using the -offset
-or -from flag.  Exactly one must be specified.
-
-Flags:
-
--offset    specifies the filename and byte offset of an identifier to rename.
-           This form is intended for use by text editors.
-
--from      specifies the object to rename using a query notation;
-           This form is intended for interactive use at the command line.
-           A legal -from query has one of the following forms:
-
-  "encoding/json".Decoder.Decode        method of package-level named type
-  (*"encoding/json".Decoder).Decode     ditto, alternative syntax
-  "encoding/json".Decoder.buf           field of package-level named struct type
-  "encoding/json".HTMLEscape            package member (const, func, var, type)
-  "encoding/json".Decoder.Decode::x     local object x within a method
-  "encoding/json".HTMLEscape::x         local object x within a function
-  "encoding/json"::x                    object x anywhere within a package
-  json.go::x                            object x within file json.go
-
-           Double-quotes must be escaped when writing a shell command.
-           Quotes may be omitted for single-segment import paths such as "fmt".
-
-           For methods, the parens and '*' on the receiver type are both
-           optional.
-
-           It is an error if one of the ::x queries matches multiple
-           objects.
-
--to        the new name.
-
--force     causes the renaming to proceed even if conflicts were reported.
-           The resulting program may be ill-formed, or experience a change
-           in behaviour.
-
-           WARNING: this flag may even cause the renaming tool to crash.
-           (In due course this bug will be fixed by moving certain
-           analyses into the type-checker.)
-
--d         display diffs instead of rewriting files
-
--v         enables verbose logging.
-
-gorename automatically computes the set of packages that might be
-affected.  For a local renaming, this is just the package specified by
--from or -offset, but for a potentially exported name, gorename scans
-the workspace ($GOROOT and $GOPATH).
-
-gorename rejects renamings of concrete methods that would change the
-assignability relation between types and interfaces. If the interface
-change was intentional, initiate the renaming at the interface method.
-
-gorename rejects any renaming that would create a conflict at the point
-of declaration, or a reference conflict (ambiguity or shadowing), or
-anything else that could cause the resulting program not to compile.
-
-
-Examples:
-
-$ gorename -offset file.go:#123 -to foo
-
-  Rename the object whose identifier is at byte offset 123 within file file.go.
-
-$ gorename -from '"bytes".Buffer.Len' -to Size
-
-  Rename the "Len" method of the *bytes.Buffer type to "Size".
-`
-
-// ---- TODO ----
-
-// Correctness:
-// - handle dot imports correctly
-// - document limitations (reflection, 'implements' algorithm).
-// - sketch a proof of exhaustiveness.
-
-// Features:
-// - support running on packages specified as *.go files on the command line
-// - support running on programs containing errors (loader.Config.AllowErrors)
-// - allow users to specify a scope other than "global" (to avoid being
-//   stuck by neglected packages in $GOPATH that don't build).
-// - support renaming the package clause (no object)
-// - support renaming an import path (no ident or object)
-//   (requires filesystem + SCM updates).
-// - detect and reject edits to autogenerated files (cgo, protobufs)
-//   and optionally $GOROOT packages.
-// - report all conflicts, or at least all qualitatively distinct ones.
-//   Sometimes we stop to avoid redundancy, but
-//   it may give a disproportionate sense of safety in -force mode.
-// - support renaming all instances of a pattern, e.g.
-//   all receiver vars of a given type,
-//   all local variables of a given type,
-//   all PkgNames for a given package.
-// - emit JSON output for other editors and tools.
-
-var (
-       // Force enables patching of the source files even if conflicts were reported.
-       // The resulting program may be ill-formed.
-       // It may even cause gorename to crash.  TODO(adonovan): fix that.
-       Force bool
-
-       // Diff causes the tool to display diffs instead of rewriting files.
-       Diff bool
-
-       // DiffCmd specifies the diff command used by the -d feature.
-       // (The command must accept a -u flag and two filename arguments.)
-       DiffCmd = "diff"
-
-       // ConflictError is returned by Main when it aborts the renaming due to conflicts.
-       // (It is distinguished because the interesting errors are the conflicts themselves.)
-       ConflictError = errors.New("renaming aborted due to conflicts")
-
-       // Verbose enables extra logging.
-       Verbose bool
-)
-
-var stdout io.Writer = os.Stdout
-
-type renamer struct {
-       iprog              *loader.Program
-       objsToUpdate       map[types.Object]bool
-       hadConflicts       bool
-       from, to           string
-       satisfyConstraints map[satisfy.Constraint]bool
-       packages           map[*types.Package]*loader.PackageInfo // subset of iprog.AllPackages to inspect
-       msets              typeutil.MethodSetCache
-       changeMethods      bool
-}
-
-var reportError = func(posn token.Position, message string) {
-       fmt.Fprintf(os.Stderr, "%s: %s\n", posn, message)
-}
-
-// importName renames imports of fromPath within the package specified by info.
-// If fromName is not empty, importName renames only imports as fromName.
-// If the renaming would lead to a conflict, the file is left unchanged.
-func importName(iprog *loader.Program, info *loader.PackageInfo, fromPath, fromName, to string) error {
-       if fromName == to {
-               return nil // no-op (e.g. rename x/foo to y/foo)
-       }
-       for _, f := range info.Files {
-               var from types.Object
-               for _, imp := range f.Imports {
-                       importPath, _ := strconv.Unquote(imp.Path.Value)
-                       importName := path.Base(importPath)
-                       if imp.Name != nil {
-                               importName = imp.Name.Name
-                       }
-                       if importPath == fromPath && (fromName == "" || importName == fromName) {
-                               from = info.Implicits[imp]
-                               break
-                       }
-               }
-               if from == nil {
-                       continue
-               }
-               r := renamer{
-                       iprog:        iprog,
-                       objsToUpdate: make(map[types.Object]bool),
-                       to:           to,
-                       packages:     map[*types.Package]*loader.PackageInfo{info.Pkg: info},
-               }
-               r.check(from)
-               if r.hadConflicts {
-                       reportError(iprog.Fset.Position(f.Imports[0].Pos()),
-                               "skipping update of this file")
-                       continue // ignore errors; leave the existing name
-               }
-               if err := r.update(); err != nil {
-                       return err
-               }
-       }
-       return nil
-}
-
-func Main(ctxt *build.Context, offsetFlag, fromFlag, to string) error {
-       // -- Parse the -from or -offset specifier ----------------------------
-
-       if (offsetFlag == "") == (fromFlag == "") {
-               return fmt.Errorf("exactly one of the -from and -offset flags must be specified")
-       }
-
-       if !isValidIdentifier(to) {
-               return fmt.Errorf("-to %q: not a valid identifier", to)
-       }
-
-       if Diff {
-               defer func(saved func(string, []byte) error) { writeFile = saved }(writeFile)
-               writeFile = diff
-       }
-
-       var spec *spec
-       var err error
-       if fromFlag != "" {
-               spec, err = parseFromFlag(ctxt, fromFlag)
-       } else {
-               spec, err = parseOffsetFlag(ctxt, offsetFlag)
-       }
-       if err != nil {
-               return err
-       }
-
-       if spec.fromName == to {
-               return fmt.Errorf("the old and new names are the same: %s", to)
-       }
-
-       // -- Load the program consisting of the initial package  -------------
-
-       iprog, err := loadProgram(ctxt, map[string]bool{spec.pkg: true})
-       if err != nil {
-               return err
-       }
-
-       fromObjects, err := findFromObjects(iprog, spec)
-       if err != nil {
-               return err
-       }
-
-       // -- Load a larger program, for global renamings ---------------------
-
-       if requiresGlobalRename(fromObjects, to) {
-               // For a local refactoring, we needn't load more
-               // packages, but if the renaming affects the package's
-               // API, we we must load all packages that depend on the
-               // package defining the object, plus their tests.
-
-               if Verbose {
-                       log.Print("Potentially global renaming; scanning workspace...")
-               }
-
-               // Scan the workspace and build the import graph.
-               _, rev, errors := importgraph.Build(ctxt)
-               if len(errors) > 0 {
-                       // With a large GOPATH tree, errors are inevitable.
-                       // Report them but proceed.
-                       fmt.Fprintf(os.Stderr, "While scanning Go workspace:\n")
-                       for path, err := range errors {
-                               fmt.Fprintf(os.Stderr, "Package %q: %s.\n", path, err)
-                       }
-               }
-
-               // Enumerate the set of potentially affected packages.
-               affectedPackages := make(map[string]bool)
-               for _, obj := range fromObjects {
-                       // External test packages are never imported,
-                       // so they will never appear in the graph.
-                       for path := range rev.Search(obj.Pkg().Path()) {
-                               affectedPackages[path] = true
-                       }
-               }
-
-               // TODO(adonovan): allow the user to specify the scope,
-               // or -ignore patterns?  Computing the scope when we
-               // don't (yet) support inputs containing errors can make
-               // the tool rather brittle.
-
-               // Re-load the larger program.
-               iprog, err = loadProgram(ctxt, affectedPackages)
-               if err != nil {
-                       return err
-               }
-
-               fromObjects, err = findFromObjects(iprog, spec)
-               if err != nil {
-                       return err
-               }
-       }
-
-       // -- Do the renaming -------------------------------------------------
-
-       r := renamer{
-               iprog:        iprog,
-               objsToUpdate: make(map[types.Object]bool),
-               from:         spec.fromName,
-               to:           to,
-               packages:     make(map[*types.Package]*loader.PackageInfo),
-       }
-
-       // A renaming initiated at an interface method indicates the
-       // intention to rename abstract and concrete methods as needed
-       // to preserve assignability.
-       for _, obj := range fromObjects {
-               if obj, ok := obj.(*types.Func); ok {
-                       recv := obj.Type().(*types.Signature).Recv()
-                       if recv != nil && isInterface(recv.Type().Underlying()) {
-                               r.changeMethods = true
-                               break
-                       }
-               }
-       }
-
-       // Only the initially imported packages (iprog.Imported) and
-       // their external tests (iprog.Created) should be inspected or
-       // modified, as only they have type-checked functions bodies.
-       // The rest are just dependencies, needed only for package-level
-       // type information.
-       for _, info := range iprog.Imported {
-               r.packages[info.Pkg] = info
-       }
-       for _, info := range iprog.Created { // (tests)
-               r.packages[info.Pkg] = info
-       }
-
-       for _, from := range fromObjects {
-               r.check(from)
-       }
-       if r.hadConflicts && !Force {
-               return ConflictError
-       }
-       return r.update()
-}
-
-// loadProgram loads the specified set of packages (plus their tests)
-// and all their dependencies, from source, through the specified build
-// context.  Only packages in pkgs will have their functions bodies typechecked.
-func loadProgram(ctxt *build.Context, pkgs map[string]bool) (*loader.Program, error) {
-       conf := loader.Config{
-               Build:      ctxt,
-               ParserMode: parser.ParseComments,
-
-               // TODO(adonovan): enable this.  Requires making a lot of code more robust!
-               AllowErrors: false,
-       }
-       // Optimization: don't type-check the bodies of functions in our
-       // dependencies, since we only need exported package members.
-       conf.TypeCheckFuncBodies = func(p string) bool {
-               return pkgs[p] || pkgs[strings.TrimSuffix(p, "_test")]
-       }
-
-       if Verbose {
-               var list []string
-               for pkg := range pkgs {
-                       list = append(list, pkg)
-               }
-               sort.Strings(list)
-               for _, pkg := range list {
-                       log.Printf("Loading package: %s", pkg)
-               }
-       }
-
-       for pkg := range pkgs {
-               conf.ImportWithTests(pkg)
-       }
-
-       // Ideally we would just return conf.Load() here, but go/types
-       // reports certain "soft" errors that gc does not (Go issue 14596).
-       // As a workaround, we set AllowErrors=true and then duplicate
-       // the loader's error checking but allow soft errors.
-       // It would be nice if the loader API permitted "AllowErrors: soft".
-       conf.AllowErrors = true
-       prog, err := conf.Load()
-       if err != nil {
-               return nil, err
-       }
-
-       var errpkgs []string
-       // Report hard errors in indirectly imported packages.
-       for _, info := range prog.AllPackages {
-               if containsHardErrors(info.Errors) {
-                       errpkgs = append(errpkgs, info.Pkg.Path())
-               }
-       }
-       if errpkgs != nil {
-               var more string
-               if len(errpkgs) > 3 {
-                       more = fmt.Sprintf(" and %d more", len(errpkgs)-3)
-                       errpkgs = errpkgs[:3]
-               }
-               return nil, fmt.Errorf("couldn't load packages due to errors: %s%s",
-                       strings.Join(errpkgs, ", "), more)
-       }
-       return prog, nil
-}
-
-func containsHardErrors(errors []error) bool {
-       for _, err := range errors {
-               if err, ok := err.(types.Error); ok && err.Soft {
-                       continue
-               }
-               return true
-       }
-       return false
-}
-
-// requiresGlobalRename reports whether this renaming could potentially
-// affect other packages in the Go workspace.
-func requiresGlobalRename(fromObjects []types.Object, to string) bool {
-       var tfm bool
-       for _, from := range fromObjects {
-               if from.Exported() {
-                       return true
-               }
-               switch objectKind(from) {
-               case "type", "field", "method":
-                       tfm = true
-               }
-       }
-       if ast.IsExported(to) && tfm {
-               // A global renaming may be necessary even if we're
-               // exporting a previous unexported name, since if it's
-               // the name of a type, field or method, this could
-               // change selections in other packages.
-               // (We include "type" in this list because a type
-               // used as an embedded struct field entails a field
-               // renaming.)
-               return true
-       }
-       return false
-}
-
-// update updates the input files.
-func (r *renamer) update() error {
-       // We use token.File, not filename, since a file may appear to
-       // belong to multiple packages and be parsed more than once.
-       // token.File captures this distinction; filename does not.
-
-       var nidents int
-       var filesToUpdate = make(map[*token.File]bool)
-       docRegexp := regexp.MustCompile(`\b` + r.from + `\b`)
-       for _, info := range r.packages {
-               // Mutate the ASTs and note the filenames.
-               for id, obj := range info.Defs {
-                       if r.objsToUpdate[obj] {
-                               nidents++
-                               id.Name = r.to
-                               filesToUpdate[r.iprog.Fset.File(id.Pos())] = true
-                               // Perform the rename in doc comments too.
-                               if doc := r.docComment(id); doc != nil {
-                                       for _, comment := range doc.List {
-                                               comment.Text = docRegexp.ReplaceAllString(comment.Text, r.to)
-                                       }
-                               }
-                       }
-               }
-
-               for id, obj := range info.Uses {
-                       if r.objsToUpdate[obj] {
-                               nidents++
-                               id.Name = r.to
-                               filesToUpdate[r.iprog.Fset.File(id.Pos())] = true
-                       }
-               }
-       }
-
-       // Renaming not supported if cgo files are affected.
-       var generatedFileNames []string
-       for _, info := range r.packages {
-               for _, f := range info.Files {
-                       tokenFile := r.iprog.Fset.File(f.Pos())
-                       if filesToUpdate[tokenFile] && generated(f, tokenFile) {
-                               generatedFileNames = append(generatedFileNames, tokenFile.Name())
-                       }
-               }
-       }
-       if !Force && len(generatedFileNames) > 0 {
-               return fmt.Errorf("refusing to modify generated file%s containing DO NOT EDIT marker: %v", plural(len(generatedFileNames)), generatedFileNames)
-       }
-
-       // Write affected files.
-       var nerrs, npkgs int
-       for _, info := range r.packages {
-               first := true
-               for _, f := range info.Files {
-                       tokenFile := r.iprog.Fset.File(f.Pos())
-                       if filesToUpdate[tokenFile] {
-                               if first {
-                                       npkgs++
-                                       first = false
-                                       if Verbose {
-                                               log.Printf("Updating package %s", info.Pkg.Path())
-                                       }
-                               }
-
-                               filename := tokenFile.Name()
-                               var buf bytes.Buffer
-                               if err := format.Node(&buf, r.iprog.Fset, f); err != nil {
-                                       log.Printf("failed to pretty-print syntax tree: %v", err)
-                                       nerrs++
-                                       continue
-                               }
-                               if err := writeFile(filename, buf.Bytes()); err != nil {
-                                       log.Print(err)
-                                       nerrs++
-                               }
-                       }
-               }
-       }
-       if !Diff {
-               fmt.Printf("Renamed %d occurrence%s in %d file%s in %d package%s.\n",
-                       nidents, plural(nidents),
-                       len(filesToUpdate), plural(len(filesToUpdate)),
-                       npkgs, plural(npkgs))
-       }
-       if nerrs > 0 {
-               return fmt.Errorf("failed to rewrite %d file%s", nerrs, plural(nerrs))
-       }
-       return nil
-}
-
-// docComment returns the doc for an identifier.
-func (r *renamer) docComment(id *ast.Ident) *ast.CommentGroup {
-       _, nodes, _ := r.iprog.PathEnclosingInterval(id.Pos(), id.End())
-       for _, node := range nodes {
-               switch decl := node.(type) {
-               case *ast.FuncDecl:
-                       return decl.Doc
-               case *ast.Field:
-                       return decl.Doc
-               case *ast.GenDecl:
-                       return decl.Doc
-               // For {Type,Value}Spec, if the doc on the spec is absent,
-               // search for the enclosing GenDecl
-               case *ast.TypeSpec:
-                       if decl.Doc != nil {
-                               return decl.Doc
-                       }
-               case *ast.ValueSpec:
-                       if decl.Doc != nil {
-                               return decl.Doc
-                       }
-               case *ast.Ident:
-               default:
-                       return nil
-               }
-       }
-       return nil
-}
-
-func plural(n int) string {
-       if n != 1 {
-               return "s"
-       }
-       return ""
-}
-
-// writeFile is a seam for testing and for the -d flag.
-var writeFile = reallyWriteFile
-
-func reallyWriteFile(filename string, content []byte) error {
-       return ioutil.WriteFile(filename, content, 0644)
-}
-
-func diff(filename string, content []byte) error {
-       renamed := fmt.Sprintf("%s.%d.renamed", filename, os.Getpid())
-       if err := ioutil.WriteFile(renamed, content, 0644); err != nil {
-               return err
-       }
-       defer os.Remove(renamed)
-
-       diff, err := exec.Command(DiffCmd, "-u", filename, renamed).CombinedOutput()
-       if len(diff) > 0 {
-               // diff exits with a non-zero status when the files don't match.
-               // Ignore that failure as long as we get output.
-               stdout.Write(diff)
-               return nil
-       }
-       if err != nil {
-               return fmt.Errorf("computing diff: %v", err)
-       }
-       return nil
-}