.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.0 / cmd / eg / eg.go
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // The eg command performs example-based refactoring.
6 // For documentation, run the command, or see Help in
7 // golang.org/x/tools/refactor/eg.
8 package main // import "golang.org/x/tools/cmd/eg"
9
10 import (
11         "flag"
12         "fmt"
13         "go/build"
14         "go/format"
15         "go/parser"
16         "go/token"
17         exec "golang.org/x/sys/execabs"
18         "os"
19         "strings"
20
21         "golang.org/x/tools/go/buildutil"
22         "golang.org/x/tools/go/loader"
23         "golang.org/x/tools/refactor/eg"
24 )
25
26 var (
27         beforeeditFlag = flag.String("beforeedit", "", "A command to exec before each file is edited (e.g. chmod, checkout).  Whitespace delimits argument words.  The string '{}' is replaced by the file name.")
28         helpFlag       = flag.Bool("help", false, "show detailed help message")
29         templateFlag   = flag.String("t", "", "template.go file specifying the refactoring")
30         transitiveFlag = flag.Bool("transitive", false, "apply refactoring to all dependencies too")
31         writeFlag      = flag.Bool("w", false, "rewrite input files in place (by default, the results are printed to standard output)")
32         verboseFlag    = flag.Bool("v", false, "show verbose matcher diagnostics")
33 )
34
35 func init() {
36         flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
37 }
38
39 const usage = `eg: an example-based refactoring tool.
40
41 Usage: eg -t template.go [-w] [-transitive] <args>...
42
43 -help            show detailed help message
44 -t template.go   specifies the template file (use -help to see explanation)
45 -w               causes files to be re-written in place.
46 -transitive      causes all dependencies to be refactored too.
47 -v               show verbose matcher diagnostics
48 -beforeedit cmd  a command to exec before each file is modified.
49                  "{}" represents the name of the file.
50 ` + loader.FromArgsUsage
51
52 func main() {
53         if err := doMain(); err != nil {
54                 fmt.Fprintf(os.Stderr, "eg: %s\n", err)
55                 os.Exit(1)
56         }
57 }
58
59 func doMain() error {
60         flag.Parse()
61         args := flag.Args()
62
63         if *helpFlag {
64                 fmt.Fprint(os.Stderr, eg.Help)
65                 os.Exit(2)
66         }
67
68         if len(args) == 0 {
69                 fmt.Fprint(os.Stderr, usage)
70                 os.Exit(1)
71         }
72
73         if *templateFlag == "" {
74                 return fmt.Errorf("no -t template.go file specified")
75         }
76
77         conf := loader.Config{
78                 Fset:       token.NewFileSet(),
79                 ParserMode: parser.ParseComments,
80         }
81
82         // The first Created package is the template.
83         conf.CreateFromFilenames("template", *templateFlag)
84
85         if _, err := conf.FromArgs(args, true); err != nil {
86                 return err
87         }
88
89         // Load, parse and type-check the whole program.
90         iprog, err := conf.Load()
91         if err != nil {
92                 return err
93         }
94
95         // Analyze the template.
96         template := iprog.Created[0]
97         xform, err := eg.NewTransformer(iprog.Fset, template.Pkg, template.Files[0], &template.Info, *verboseFlag)
98         if err != nil {
99                 return err
100         }
101
102         // Apply it to the input packages.
103         var pkgs []*loader.PackageInfo
104         if *transitiveFlag {
105                 for _, info := range iprog.AllPackages {
106                         pkgs = append(pkgs, info)
107                 }
108         } else {
109                 pkgs = iprog.InitialPackages()
110         }
111         var hadErrors bool
112         for _, pkg := range pkgs {
113                 if pkg == template {
114                         continue
115                 }
116                 for _, file := range pkg.Files {
117                         n := xform.Transform(&pkg.Info, pkg.Pkg, file)
118                         if n == 0 {
119                                 continue
120                         }
121                         filename := iprog.Fset.File(file.Pos()).Name()
122                         fmt.Fprintf(os.Stderr, "=== %s (%d matches)\n", filename, n)
123                         if *writeFlag {
124                                 // Run the before-edit command (e.g. "chmod +w",  "checkout") if any.
125                                 if *beforeeditFlag != "" {
126                                         args := strings.Fields(*beforeeditFlag)
127                                         // Replace "{}" with the filename, like find(1).
128                                         for i := range args {
129                                                 if i > 0 {
130                                                         args[i] = strings.Replace(args[i], "{}", filename, -1)
131                                                 }
132                                         }
133                                         cmd := exec.Command(args[0], args[1:]...)
134                                         cmd.Stdout = os.Stdout
135                                         cmd.Stderr = os.Stderr
136                                         if err := cmd.Run(); err != nil {
137                                                 fmt.Fprintf(os.Stderr, "Warning: edit hook %q failed (%s)\n",
138                                                         args, err)
139                                         }
140                                 }
141                                 if err := eg.WriteAST(iprog.Fset, filename, file); err != nil {
142                                         fmt.Fprintf(os.Stderr, "eg: %s\n", err)
143                                         hadErrors = true
144                                 }
145                         } else {
146                                 format.Node(os.Stdout, iprog.Fset, file)
147                         }
148                 }
149         }
150         if hadErrors {
151                 os.Exit(1)
152         }
153         return nil
154 }