|
15 | 15 | package cmd |
16 | 16 |
|
17 | 17 | import ( |
18 | | - "fmt" |
19 | 18 | "io/ioutil" |
20 | 19 | "os" |
21 | 20 | "path/filepath" |
22 | 21 | "strings" |
23 | 22 |
|
24 | 23 | "cuelang.org/go/cue/ast" |
25 | | - "cuelang.org/go/cue/ast/astutil" |
26 | 24 | "cuelang.org/go/cue/errors" |
27 | 25 | "cuelang.org/go/cue/format" |
28 | 26 | "cuelang.org/go/cue/load" |
29 | | - "cuelang.org/go/cue/parser" |
30 | 27 | "cuelang.org/go/cue/token" |
31 | | - "cuelang.org/go/internal" |
| 28 | + "cuelang.org/go/tools/fix" |
32 | 29 | "github.com/spf13/cobra" |
33 | 30 | ) |
34 | 31 |
|
@@ -87,7 +84,7 @@ func runFixAll(cmd *Command, args []string) error { |
87 | 84 | } |
88 | 85 | } |
89 | 86 |
|
90 | | - errs := fixAll(instances) |
| 87 | + errs := fix.Instances(instances) |
91 | 88 |
|
92 | 89 | if errs != nil && flagForce.Bool(cmd) { |
93 | 90 | return errs |
@@ -129,238 +126,3 @@ func appendDirs(a []string, base string) []string { |
129 | 126 | }) |
130 | 127 | return a |
131 | 128 | } |
132 | | - |
133 | | -func fix(f *ast.File) *ast.File { |
134 | | - // Isolate bulk optional fields into a single struct. |
135 | | - ast.Walk(f, func(n ast.Node) bool { |
136 | | - var decls []ast.Decl |
137 | | - switch x := n.(type) { |
138 | | - case *ast.StructLit: |
139 | | - decls = x.Elts |
140 | | - case *ast.File: |
141 | | - decls = x.Decls |
142 | | - } |
143 | | - |
144 | | - if len(decls) <= 1 { |
145 | | - return true |
146 | | - } |
147 | | - |
148 | | - for i, d := range decls { |
149 | | - if internal.IsBulkField(d) { |
150 | | - decls[i] = internal.EmbedStruct(ast.NewStruct(d)) |
151 | | - } |
152 | | - } |
153 | | - |
154 | | - return true |
155 | | - }, nil) |
156 | | - |
157 | | - // Rewrite an old-style alias to a let clause. |
158 | | - ast.Walk(f, func(n ast.Node) bool { |
159 | | - var decls []ast.Decl |
160 | | - switch x := n.(type) { |
161 | | - case *ast.StructLit: |
162 | | - decls = x.Elts |
163 | | - case *ast.File: |
164 | | - decls = x.Decls |
165 | | - } |
166 | | - for i, d := range decls { |
167 | | - if a, ok := d.(*ast.Alias); ok { |
168 | | - x := &ast.LetClause{ |
169 | | - Ident: a.Ident, |
170 | | - Equal: a.Equal, |
171 | | - Expr: a.Expr, |
172 | | - } |
173 | | - astutil.CopyMeta(x, a) |
174 | | - decls[i] = x |
175 | | - } |
176 | | - } |
177 | | - return true |
178 | | - }, nil) |
179 | | - |
180 | | - // Rewrite block comments to regular comments. |
181 | | - ast.Walk(f, func(n ast.Node) bool { |
182 | | - switch x := n.(type) { |
183 | | - case *ast.CommentGroup: |
184 | | - comments := []*ast.Comment{} |
185 | | - for _, c := range x.List { |
186 | | - s := c.Text |
187 | | - if !strings.HasPrefix(s, "/*") || !strings.HasSuffix(s, "*/") { |
188 | | - comments = append(comments, c) |
189 | | - continue |
190 | | - } |
191 | | - if x.Position > 0 { |
192 | | - // Moving to the end doesn't work, as it still |
193 | | - // may inject at a false line break position. |
194 | | - x.Position = 0 |
195 | | - x.Doc = true |
196 | | - } |
197 | | - s = strings.TrimSpace(s[2 : len(s)-2]) |
198 | | - for _, s := range strings.Split(s, "\n") { |
199 | | - for i := 0; i < 3; i++ { |
200 | | - if strings.HasPrefix(s, " ") || strings.HasPrefix(s, "*") { |
201 | | - s = s[1:] |
202 | | - } |
203 | | - } |
204 | | - comments = append(comments, &ast.Comment{Text: "// " + s}) |
205 | | - } |
206 | | - } |
207 | | - x.List = comments |
208 | | - return false |
209 | | - } |
210 | | - return true |
211 | | - }, nil) |
212 | | - |
213 | | - // Referred nodes and used identifiers. |
214 | | - referred := map[ast.Node]string{} |
215 | | - used := map[string]bool{} |
216 | | - replacement := map[ast.Node]string{} |
217 | | - |
218 | | - ast.Walk(f, func(n ast.Node) bool { |
219 | | - if i, ok := n.(*ast.Ident); ok { |
220 | | - str, err := ast.ParseIdent(i) |
221 | | - if err != nil { |
222 | | - return false |
223 | | - } |
224 | | - referred[i.Node] = str |
225 | | - used[str] = true |
226 | | - } |
227 | | - return true |
228 | | - }, nil) |
229 | | - |
230 | | - num := 0 |
231 | | - newIdent := func() string { |
232 | | - for num++; ; num++ { |
233 | | - str := fmt.Sprintf("X%d", num) |
234 | | - if !used[str] { |
235 | | - used[str] = true |
236 | | - return str |
237 | | - } |
238 | | - } |
239 | | - } |
240 | | - |
241 | | - // Rewrite TemplateLabel to ListLit. |
242 | | - // Note: there is a chance that the name will clash with the |
243 | | - // scope in which it is defined. We drop the alias if it is not |
244 | | - // used to mitigate this issue. |
245 | | - f = astutil.Apply(f, func(c astutil.Cursor) bool { |
246 | | - n := c.Node() |
247 | | - switch x := n.(type) { |
248 | | - case *ast.TemplateLabel: |
249 | | - var expr ast.Expr = ast.NewIdent("string") |
250 | | - if _, ok := referred[x]; ok { |
251 | | - expr = &ast.Alias{ |
252 | | - Ident: x.Ident, |
253 | | - Expr: ast.NewIdent("_"), |
254 | | - } |
255 | | - } |
256 | | - c.Replace(ast.NewList(expr)) |
257 | | - } |
258 | | - return true |
259 | | - }, nil).(*ast.File) |
260 | | - |
261 | | - // Rewrite quoted identifier fields that are referenced. |
262 | | - f = astutil.Apply(f, func(c astutil.Cursor) bool { |
263 | | - n := c.Node() |
264 | | - switch x := n.(type) { |
265 | | - case *ast.Field: |
266 | | - m, ok := referred[x.Value] |
267 | | - if !ok { |
268 | | - break |
269 | | - } |
270 | | - |
271 | | - if b, ok := x.Label.(*ast.Ident); ok { |
272 | | - str, err := ast.ParseIdent(b) |
273 | | - var expr ast.Expr = b |
274 | | - |
275 | | - switch { |
276 | | - case token.Lookup(str) != token.IDENT: |
277 | | - // quote keywords |
278 | | - expr = ast.NewString(b.Name) |
279 | | - |
280 | | - case err != nil || str != m || str == b.Name: |
281 | | - return true |
282 | | - |
283 | | - case ast.IsValidIdent(str): |
284 | | - x.Label = astutil.CopyMeta(ast.NewIdent(str), x.Label).(ast.Label) |
285 | | - return true |
286 | | - } |
287 | | - |
288 | | - ident := newIdent() |
289 | | - replacement[x.Value] = ident |
290 | | - expr = &ast.Alias{Ident: ast.NewIdent(ident), Expr: expr} |
291 | | - ast.SetRelPos(x.Label, token.NoRelPos) |
292 | | - x.Label = astutil.CopyMeta(expr, x.Label).(ast.Label) |
293 | | - } |
294 | | - } |
295 | | - return true |
296 | | - }, nil).(*ast.File) |
297 | | - |
298 | | - // Replace quoted references with their alias identifier. |
299 | | - astutil.Apply(f, func(c astutil.Cursor) bool { |
300 | | - n := c.Node() |
301 | | - switch x := n.(type) { |
302 | | - case *ast.Ident: |
303 | | - if r, ok := replacement[x.Node]; ok { |
304 | | - c.Replace(astutil.CopyMeta(ast.NewIdent(r), n)) |
305 | | - break |
306 | | - } |
307 | | - str, err := ast.ParseIdent(x) |
308 | | - if err != nil || str == x.Name { |
309 | | - break |
310 | | - } |
311 | | - // Either the identifier is valid, in which can be replaced simply |
312 | | - // as here, or it is a complicated identifier and the original |
313 | | - // destination must have been quoted, in which case it is handled |
314 | | - // above. |
315 | | - if ast.IsValidIdent(str) && token.Lookup(str) == token.IDENT { |
316 | | - c.Replace(astutil.CopyMeta(ast.NewIdent(str), n)) |
317 | | - } |
318 | | - } |
319 | | - return true |
320 | | - }, nil) |
321 | | - |
322 | | - // TODO: we are probably reintroducing slices. Disable for now. |
323 | | - // |
324 | | - // Rewrite slice expression. |
325 | | - // f = astutil.Apply(f, func(c astutil.Cursor) bool { |
326 | | - // n := c.Node() |
327 | | - // getVal := func(n ast.Expr) ast.Expr { |
328 | | - // if n == nil { |
329 | | - // return nil |
330 | | - // } |
331 | | - // if id, ok := n.(*ast.Ident); ok && id.Name == "_" { |
332 | | - // return nil |
333 | | - // } |
334 | | - // return n |
335 | | - // } |
336 | | - // switch x := n.(type) { |
337 | | - // case *ast.SliceExpr: |
338 | | - // ast.SetRelPos(x.X, token.NoRelPos) |
339 | | - |
340 | | - // lo := getVal(x.Low) |
341 | | - // hi := getVal(x.High) |
342 | | - // if lo == nil { // a[:j] |
343 | | - // lo = mustParseExpr("0") |
344 | | - // astutil.CopyMeta(lo, x.Low) |
345 | | - // } |
346 | | - // if hi == nil { // a[i:] |
347 | | - // hi = ast.NewCall(ast.NewIdent("len"), x.X) |
348 | | - // astutil.CopyMeta(lo, x.High) |
349 | | - // } |
350 | | - // if pkg := c.Import("list"); pkg != nil { |
351 | | - // c.Replace(ast.NewCall(ast.NewSel(pkg, "Slice"), x.X, lo, hi)) |
352 | | - // } |
353 | | - // } |
354 | | - // return true |
355 | | - // }, nil).(*ast.File) |
356 | | - |
357 | | - return f |
358 | | -} |
359 | | - |
360 | | -func mustParseExpr(expr string) ast.Expr { |
361 | | - ex, err := parser.ParseExpr("fix", expr) |
362 | | - if err != nil { |
363 | | - panic(err) |
364 | | - } |
365 | | - return ex |
366 | | -} |
0 commit comments