Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / ast / astutil / rewrite_test.go
1 // Copyright 2017 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 package astutil_test
6
7 import (
8         "bytes"
9         "go/ast"
10         "go/format"
11         "go/parser"
12         "go/token"
13         "testing"
14
15         "golang.org/x/tools/go/ast/astutil"
16 )
17
18 var rewriteTests = [...]struct {
19         name       string
20         orig, want string
21         pre, post  astutil.ApplyFunc
22 }{
23         {name: "nop", orig: "package p\n", want: "package p\n"},
24
25         {name: "replace",
26                 orig: `package p
27
28 var x int
29 `,
30                 want: `package p
31
32 var t T
33 `,
34                 post: func(c *astutil.Cursor) bool {
35                         if _, ok := c.Node().(*ast.ValueSpec); ok {
36                                 c.Replace(valspec("t", "T"))
37                                 return false
38                         }
39                         return true
40                 },
41         },
42
43         {name: "set doc strings",
44                 orig: `package p
45
46 const z = 0
47
48 type T struct{}
49
50 var x int
51 `,
52                 want: `package p
53 // a foo is a foo
54 const z = 0
55 // a foo is a foo
56 type T struct{}
57 // a foo is a foo
58 var x int
59 `,
60                 post: func(c *astutil.Cursor) bool {
61                         if _, ok := c.Parent().(*ast.GenDecl); ok && c.Name() == "Doc" && c.Node() == nil {
62                                 c.Replace(&ast.CommentGroup{List: []*ast.Comment{{Text: "// a foo is a foo"}}})
63                         }
64                         return true
65                 },
66         },
67
68         {name: "insert names",
69                 orig: `package p
70
71 const a = 1
72 `,
73                 want: `package p
74
75 const a, b, c = 1, 2, 3
76 `,
77                 pre: func(c *astutil.Cursor) bool {
78                         if _, ok := c.Parent().(*ast.ValueSpec); ok {
79                                 switch c.Name() {
80                                 case "Names":
81                                         c.InsertAfter(ast.NewIdent("c"))
82                                         c.InsertAfter(ast.NewIdent("b"))
83                                 case "Values":
84                                         c.InsertAfter(&ast.BasicLit{Kind: token.INT, Value: "3"})
85                                         c.InsertAfter(&ast.BasicLit{Kind: token.INT, Value: "2"})
86                                 }
87                         }
88                         return true
89                 },
90         },
91
92         {name: "insert",
93                 orig: `package p
94
95 var (
96         x int
97         y int
98 )
99 `,
100                 want: `package p
101
102 var before1 int
103 var before2 int
104
105 var (
106         x int
107         y int
108 )
109 var after2 int
110 var after1 int
111 `,
112                 pre: func(c *astutil.Cursor) bool {
113                         if _, ok := c.Node().(*ast.GenDecl); ok {
114                                 c.InsertBefore(vardecl("before1", "int"))
115                                 c.InsertAfter(vardecl("after1", "int"))
116                                 c.InsertAfter(vardecl("after2", "int"))
117                                 c.InsertBefore(vardecl("before2", "int"))
118                         }
119                         return true
120                 },
121         },
122
123         {name: "delete",
124                 orig: `package p
125
126 var x int
127 var y int
128 var z int
129 `,
130                 want: `package p
131
132 var y int
133 var z int
134 `,
135                 pre: func(c *astutil.Cursor) bool {
136                         n := c.Node()
137                         if d, ok := n.(*ast.GenDecl); ok && d.Specs[0].(*ast.ValueSpec).Names[0].Name == "x" {
138                                 c.Delete()
139                         }
140                         return true
141                 },
142         },
143
144         {name: "insertafter-delete",
145                 orig: `package p
146
147 var x int
148 var y int
149 var z int
150 `,
151                 want: `package p
152
153 var x1 int
154
155 var y int
156 var z int
157 `,
158                 pre: func(c *astutil.Cursor) bool {
159                         n := c.Node()
160                         if d, ok := n.(*ast.GenDecl); ok && d.Specs[0].(*ast.ValueSpec).Names[0].Name == "x" {
161                                 c.InsertAfter(vardecl("x1", "int"))
162                                 c.Delete()
163                         }
164                         return true
165                 },
166         },
167
168         {name: "delete-insertafter",
169                 orig: `package p
170
171 var x int
172 var y int
173 var z int
174 `,
175                 want: `package p
176
177 var y int
178 var x1 int
179 var z int
180 `,
181                 pre: func(c *astutil.Cursor) bool {
182                         n := c.Node()
183                         if d, ok := n.(*ast.GenDecl); ok && d.Specs[0].(*ast.ValueSpec).Names[0].Name == "x" {
184                                 c.Delete()
185                                 // The cursor is now effectively atop the 'var y int' node.
186                                 c.InsertAfter(vardecl("x1", "int"))
187                         }
188                         return true
189                 },
190         },
191 }
192
193 func valspec(name, typ string) *ast.ValueSpec {
194         return &ast.ValueSpec{Names: []*ast.Ident{ast.NewIdent(name)},
195                 Type: ast.NewIdent(typ),
196         }
197 }
198
199 func vardecl(name, typ string) *ast.GenDecl {
200         return &ast.GenDecl{
201                 Tok:   token.VAR,
202                 Specs: []ast.Spec{valspec(name, typ)},
203         }
204 }
205
206 func TestRewrite(t *testing.T) {
207         t.Run("*", func(t *testing.T) {
208                 for _, test := range rewriteTests {
209                         test := test
210                         t.Run(test.name, func(t *testing.T) {
211                                 t.Parallel()
212                                 fset := token.NewFileSet()
213                                 f, err := parser.ParseFile(fset, test.name, test.orig, parser.ParseComments)
214                                 if err != nil {
215                                         t.Fatal(err)
216                                 }
217                                 n := astutil.Apply(f, test.pre, test.post)
218                                 var buf bytes.Buffer
219                                 if err := format.Node(&buf, fset, n); err != nil {
220                                         t.Fatal(err)
221                                 }
222                                 got := buf.String()
223                                 if got != test.want {
224                                         t.Errorf("got:\n\n%s\nwant:\n\n%s\n", got, test.want)
225                                 }
226                         })
227                 }
228         })
229 }
230
231 var sink ast.Node
232
233 func BenchmarkRewrite(b *testing.B) {
234         for _, test := range rewriteTests {
235                 b.Run(test.name, func(b *testing.B) {
236                         for i := 0; i < b.N; i++ {
237                                 b.StopTimer()
238                                 fset := token.NewFileSet()
239                                 f, err := parser.ParseFile(fset, test.name, test.orig, parser.ParseComments)
240                                 if err != nil {
241                                         b.Fatal(err)
242                                 }
243                                 b.StartTimer()
244                                 sink = astutil.Apply(f, test.pre, test.post)
245                         }
246                 })
247         }
248 }