...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package format
16
17 import (
18 "strconv"
19
20 "cuelang.org/go/cue/ast"
21 "cuelang.org/go/cue/ast/astutil"
22 "cuelang.org/go/internal"
23 )
24
25
26
27
28
29 type labelSimplifier struct {
30 parent *labelSimplifier
31 scope map[string]bool
32 }
33
34 func (s *labelSimplifier) processDecls(decls []ast.Decl) {
35 sc := labelSimplifier{parent: s, scope: map[string]bool{}}
36 for _, d := range decls {
37 switch x := d.(type) {
38 case *ast.Field:
39 ast.Walk(x.Label, sc.markStrings, nil)
40 }
41 }
42
43 for _, d := range decls {
44 switch x := d.(type) {
45 case *ast.Field:
46 ast.Walk(x.Value, sc.markReferences, nil)
47 default:
48 ast.Walk(x, sc.markReferences, nil)
49 }
50 }
51
52 for _, d := range decls {
53 switch x := d.(type) {
54 case *ast.Field:
55 x.Label = astutil.Apply(x.Label, sc.replace, nil).(ast.Label)
56 }
57 }
58 }
59
60 func (s *labelSimplifier) markReferences(n ast.Node) bool {
61
62 switch x := n.(type) {
63 case *ast.File:
64 s.processDecls(x.Decls)
65 return false
66
67 case *ast.StructLit:
68 s.processDecls(x.Elts)
69 return false
70
71 case *ast.SelectorExpr:
72 ast.Walk(x.X, s.markReferences, nil)
73 return false
74
75 case *ast.Ident:
76 for c := s; c != nil; c = c.parent {
77 if _, ok := c.scope[x.Name]; ok {
78 c.scope[x.Name] = false
79 break
80 }
81 }
82 }
83 return true
84 }
85
86 func (s *labelSimplifier) markStrings(n ast.Node) bool {
87 switch x := n.(type) {
88 case *ast.BasicLit:
89 str, err := strconv.Unquote(x.Value)
90 if err != nil || !ast.IsValidIdent(str) || internal.IsDefOrHidden(str) {
91 return false
92 }
93 s.scope[str] = true
94
95 case *ast.Ident:
96 s.scope[x.Name] = true
97
98 case *ast.ListLit, *ast.Interpolation:
99 return false
100 }
101 return true
102 }
103
104 func (s *labelSimplifier) replace(c astutil.Cursor) bool {
105 switch x := c.Node().(type) {
106 case *ast.BasicLit:
107 str, err := strconv.Unquote(x.Value)
108 if err == nil && s.scope[str] && !internal.IsDefOrHidden(str) {
109 c.Replace(ast.NewIdent(str))
110 }
111 }
112 return true
113 }
114
View as plain text