.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / mvdan.cc / gofumpt@v0.1.0 / gen.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/mvdan.cc/gofumpt@v0.1.0/gen.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/mvdan.cc/gofumpt@v0.1.0/gen.go
new file mode 100644 (file)
index 0000000..ea5244a
--- /dev/null
@@ -0,0 +1,340 @@
+// Copyright (c) 2019, Daniel Martí <mvdan@mvdan.cc>
+// See LICENSE for licensing information
+
+// +build ignore
+
+package main
+
+import (
+       "bytes"
+       "context"
+       "encoding/json"
+       "fmt"
+       "io/ioutil"
+       "os"
+       "os/exec"
+       "path/filepath"
+       "strings"
+       "time"
+)
+
+func main() {
+       pkgs, err := listPackages(context.TODO(), nil,
+               "cmd/gofmt",
+
+               // These are internal cmd dependencies. Copy them.
+               "cmd/internal/diff",
+
+               "golang.org/x/tools/cmd/goimports",
+
+               // These are internal goimports dependencies. Copy them.
+               "golang.org/x/tools/internal/event",
+               "golang.org/x/tools/internal/event/core",
+               "golang.org/x/tools/internal/event/keys",
+               "golang.org/x/tools/internal/event/label",
+               "golang.org/x/tools/internal/fastwalk",
+               "golang.org/x/tools/internal/gocommand",
+               "golang.org/x/tools/internal/gopathwalk",
+               "golang.org/x/tools/internal/imports",
+               "golang.org/x/tools/internal/module",
+               "golang.org/x/tools/internal/semver",
+               "golang.org/x/tools/internal/telemetry/event",
+       )
+       if err != nil {
+               panic(err)
+       }
+       for _, pkg := range pkgs {
+               switch pkg.ImportPath {
+               case "cmd/gofmt":
+                       copyGofmt(pkg)
+               case "golang.org/x/tools/cmd/goimports":
+                       copyGoimports(pkg)
+               default:
+                       parts := strings.Split(pkg.ImportPath, "/")
+                       if parts[0] == "cmd" {
+                               copyInternal(pkg, filepath.Join(parts[1:]...))
+                       } else {
+                               dir := filepath.Join(append([]string{"gofumports"}, parts[3:]...)...)
+                               copyInternal(pkg, dir)
+                       }
+               }
+       }
+}
+
+type Module struct {
+       Path      string       // module path
+       Version   string       // module version
+       Versions  []string     // available module versions (with -versions)
+       Replace   *Module      // replaced by this module
+       Time      *time.Time   // time version was created
+       Update    *Module      // available update, if any (with -u)
+       Main      bool         // is this the main module?
+       Indirect  bool         // is this module only an indirect dependency of main module?
+       Dir       string       // directory holding files for this module, if any
+       GoMod     string       // path to go.mod file used when loading this module, if any
+       GoVersion string       // go version used in module
+       Error     *ModuleError // error loading module
+}
+
+type ModuleError struct {
+       Err string // the error itself
+}
+
+type Package struct {
+       Dir           string   // directory containing package sources
+       ImportPath    string   // import path of package in dir
+       ImportComment string   // path in import comment on package statement
+       Name          string   // package name
+       Doc           string   // package documentation string
+       Target        string   // install path
+       Shlib         string   // the shared library that contains this package (only set when -linkshared)
+       Goroot        bool     // is this package in the Go root?
+       Standard      bool     // is this package part of the standard Go library?
+       Stale         bool     // would 'go install' do anything for this package?
+       StaleReason   string   // explanation for Stale==true
+       Root          string   // Go root or Go path dir containing this package
+       ConflictDir   string   // this directory shadows Dir in $GOPATH
+       BinaryOnly    bool     // binary-only package (no longer supported)
+       ForTest       string   // package is only for use in named test
+       Export        string   // file containing export data (when using -export)
+       Module        *Module  // info about package's containing module, if any (can be nil)
+       Match         []string // command-line patterns matching this package
+       DepOnly       bool     // package is only a dependency, not explicitly listed
+
+       // Source files
+       GoFiles         []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+       CgoFiles        []string // .go source files that import "C"
+       CompiledGoFiles []string // .go files presented to compiler (when using -compiled)
+       IgnoredGoFiles  []string // .go source files ignored due to build constraints
+       CFiles          []string // .c source files
+       CXXFiles        []string // .cc, .cxx and .cpp source files
+       MFiles          []string // .m source files
+       HFiles          []string // .h, .hh, .hpp and .hxx source files
+       FFiles          []string // .f, .F, .for and .f90 Fortran source files
+       SFiles          []string // .s source files
+       SwigFiles       []string // .swig files
+       SwigCXXFiles    []string // .swigcxx files
+       SysoFiles       []string // .syso object files to add to archive
+       TestGoFiles     []string // _test.go files in package
+       XTestGoFiles    []string // _test.go files outside package
+
+       // Cgo directives
+       CgoCFLAGS    []string // cgo: flags for C compiler
+       CgoCPPFLAGS  []string // cgo: flags for C preprocessor
+       CgoCXXFLAGS  []string // cgo: flags for C++ compiler
+       CgoFFLAGS    []string // cgo: flags for Fortran compiler
+       CgoLDFLAGS   []string // cgo: flags for linker
+       CgoPkgConfig []string // cgo: pkg-config names
+
+       // Dependency information
+       Imports      []string          // import paths used by this package
+       ImportMap    map[string]string // map from source import to ImportPath (identity entries omitted)
+       Deps         []string          // all (recursively) imported dependencies
+       TestImports  []string          // imports from TestGoFiles
+       XTestImports []string          // imports from XTestGoFiles
+
+       // Error information
+       Incomplete bool            // this package or a dependency has an error
+       Error      *PackageError   // error loading package
+       DepsErrors []*PackageError // errors loading dependencies
+}
+
+type PackageError struct {
+       ImportStack []string // shortest path from package named on command line to this one
+       Pos         string   // position of error (if present, file:line:col)
+       Err         string   // the error itself
+}
+
+func getEnv(env []string, name string) string {
+       for _, kv := range env {
+               if i := strings.IndexByte(kv, '='); i > 0 && name == kv[:i] {
+                       return kv[i+1:]
+               }
+       }
+       return ""
+}
+
+// listPackages is a wrapper for 'go list -json -e', which can take arbitrary
+// environment variables and arguments as input. The working directory can be
+// fed by adding $PWD to env; otherwise, it will default to the current
+// directory.
+//
+// Since -e is used, the returned error will only be non-nil if a JSON result
+// could not be obtained. Such examples are if the Go command is not installed,
+// or if invalid flags are used as arguments.
+//
+// Errors encountered when loading packages will be returned for each package,
+// in the form of PackageError. See 'go help list'.
+func listPackages(ctx context.Context, env []string, args ...string) (pkgs []*Package, finalErr error) {
+       goArgs := append([]string{"list", "-json", "-e"}, args...)
+       cmd := exec.CommandContext(ctx, "go", goArgs...)
+       cmd.Env = env
+       cmd.Dir = getEnv(env, "PWD")
+
+       stdout, err := cmd.StdoutPipe()
+       if err != nil {
+               return nil, err
+       }
+       var stderrBuf bytes.Buffer
+       cmd.Stderr = &stderrBuf
+       defer func() {
+               if finalErr != nil && stderrBuf.Len() > 0 {
+                       // TODO: wrap? but the format is backwards, given that
+                       // stderr is likely multi-line
+                       finalErr = fmt.Errorf("%v\n%s", finalErr, stderrBuf.Bytes())
+               }
+       }()
+
+       if err := cmd.Start(); err != nil {
+               return nil, err
+       }
+       dec := json.NewDecoder(stdout)
+       for dec.More() {
+               var pkg Package
+               if err := dec.Decode(&pkg); err != nil {
+                       return nil, err
+               }
+               pkgs = append(pkgs, &pkg)
+       }
+       if err := cmd.Wait(); err != nil {
+               return nil, err
+       }
+       return pkgs, nil
+}
+
+func readFile(path string) string {
+       body, err := ioutil.ReadFile(path)
+       if err != nil {
+               panic(err)
+       }
+       return string(body)
+}
+
+func writeFile(path, body string) {
+       if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
+               panic(err)
+       }
+       if err := ioutil.WriteFile(path, []byte(body), 0o644); err != nil {
+               panic(err)
+       }
+}
+
+func sourceFiles(pkg *Package) (paths []string) {
+       var combined []string
+       for _, list := range [...][]string{
+               pkg.GoFiles,
+               pkg.IgnoredGoFiles,
+       } {
+               for _, name := range list {
+                       if strings.HasSuffix(name, "_test.go") {
+                               // IgnoredGoFiles can contain test files too.
+                               continue
+                       }
+                       combined = append(combined, filepath.Join(pkg.Dir, name))
+               }
+       }
+       return combined
+}
+
+const extraImport = `gformat "mvdan.cc/gofumpt/format"; `
+
+const extraSrcLangVersion = `` +
+       `if *langVersion == "" {
+               out, err := exec.Command("go", "list", "-m", "-f", "{{.GoVersion}}").Output()
+               out = bytes.TrimSpace(out)
+               if err == nil && len(out) > 0 {
+                       *langVersion = string(out)
+               }
+       }`
+
+func copyGofmt(pkg *Package) {
+       const extraVersion = `
+               // Print the gofumpt version if the user asks for it.
+               if *showVersion {
+                       printVersion()
+                       return
+               }
+               `
+       const extraFormat = `
+               // Apply gofumpt's changes before we print the code in gofmt's
+               // format.
+               ` + extraSrcLangVersion + `
+               gformat.File(fileSet, file, gformat.Options{
+                       LangVersion: *langVersion,
+                       ExtraRules:  *extraRules,
+               })
+               `
+       for _, path := range sourceFiles(pkg) {
+               body := readFile(path)
+               body = fixImports(body)
+               name := filepath.Base(path)
+               switch name {
+               case "doc.go":
+                       continue // we have our own
+               case "gofmt.go":
+                       if i := strings.Index(body, "\t\"mvdan.cc/gofumpt"); i > 0 {
+                               body = body[:i] + "\n" + extraImport + "\n" + body[i:]
+                       }
+                       if i := strings.Index(body, "if *cpuprofile !="); i > 0 {
+                               body = body[:i] + "\n" + extraVersion + "\n" + body[i:]
+                       }
+                       if i := strings.Index(body, "res, err := format("); i > 0 {
+                               body = body[:i] + "\n" + extraFormat + "\n" + body[i:]
+                       }
+               }
+               body = strings.Replace(body, "gofmt", "gofumpt", -1)
+               writeFile(name, body)
+       }
+}
+
+func copyGoimports(pkg *Package) {
+       const extraFormat = `
+               // This is the only gofumpt change on goimports's codebase, besides changing
+               // the name in the usage text.
+               ` + extraSrcLangVersion + `
+               res, err = gformat.Source(res, gformat.Options{LangVersion: *langVersion})
+               if err != nil {
+                       return err
+               }
+               `
+       for _, path := range sourceFiles(pkg) {
+               body := readFile(path)
+               body = fixImports(body)
+               name := filepath.Base(path)
+               switch name {
+               case "doc.go":
+                       continue // we have our own
+               case "goimports.go":
+                       if i := strings.Index(body, "\t\"mvdan.cc/gofumpt"); i > 0 {
+                               body = body[:i] + "\n" + extraImport + "\n" + body[i:]
+                       }
+                       if i := strings.Index(body, "if !bytes.Equal"); i > 0 {
+                               body = body[:i] + "\n" + extraFormat + "\n" + body[i:]
+                       }
+               }
+               body = strings.Replace(body, "goimports", "gofumports", -1)
+
+               writeFile(filepath.Join("gofumports", name), body)
+       }
+}
+
+func copyInternal(pkg *Package, dir string) {
+       for _, path := range sourceFiles(pkg) {
+               body := readFile(path)
+               body = fixImports(body)
+               name := filepath.Base(path)
+               writeFile(filepath.Join(dir, name), body)
+       }
+}
+
+func fixImports(body string) string {
+       body = strings.Replace(body,
+               "golang.org/x/tools/internal/",
+               "mvdan.cc/gofumpt/gofumports/internal/",
+               -1)
+       body = strings.Replace(body,
+               "cmd/internal/",
+               "mvdan.cc/gofumpt/internal/",
+               -1)
+       return body
+}