...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package compile
16
17 import (
18 "github.com/cockroachdb/apd/v3"
19 "golang.org/x/text/unicode/norm"
20
21 "cuelang.org/go/cue/ast"
22 "cuelang.org/go/cue/literal"
23 "cuelang.org/go/cue/token"
24 "cuelang.org/go/internal/core/adt"
25 )
26
27
28 func (c *compiler) label(n ast.Node) adt.Feature {
29 index := c.index
30 switch x := n.(type) {
31 case *ast.Ident:
32 if x.Name == "_" {
33 return adt.InvalidLabel
34 }
35 return adt.MakeIdentLabel(c.index, x.Name, c.pkgPath)
36
37 case *ast.BasicLit:
38 switch x.Kind {
39 case token.STRING:
40 const msg = "invalid string label: %v"
41 s, err := literal.Unquote(x.Value)
42 if err != nil {
43 c.errf(n, msg, err)
44 return adt.InvalidLabel
45 }
46
47 i := int64(index.StringToIndex(norm.NFC.String(s)))
48 f, err := adt.MakeLabel(n, i, adt.StringLabel)
49 if err != nil {
50 c.errf(n, msg, err)
51 }
52 return f
53
54 case token.INT:
55 const msg = "invalid int label: %v"
56 if err := literal.ParseNum(x.Value, &c.num); err != nil {
57 c.errf(n, msg, err)
58 return adt.InvalidLabel
59 }
60
61 var d apd.Decimal
62 if err := c.num.Decimal(&d); err != nil {
63 c.errf(n, msg, err)
64 return adt.InvalidLabel
65 }
66
67 i, err := d.Int64()
68 if err != nil {
69 c.errf(n, msg, err)
70 return adt.InvalidLabel
71 }
72
73 f, err := adt.MakeLabel(n, i, adt.IntLabel)
74 if err != nil {
75 c.errf(n, msg, err)
76 return adt.InvalidLabel
77 }
78 return f
79
80 case token.FLOAT:
81 _ = c.errf(n, "float %s cannot be used as label", x.Value)
82 return adt.InvalidLabel
83
84 default:
85 i := index.StringToIndex(x.Kind.String())
86 f, err := adt.MakeLabel(n, i, adt.StringLabel)
87 if err != nil {
88 c.errf(n, "invalid string label: %v", err)
89 }
90 return f
91 }
92
93 default:
94 c.errf(n, "unsupported label node type %T", n)
95 return adt.InvalidLabel
96 }
97 }
98
99
100 type labeler interface {
101 labelString() string
102 }
103
104 type fieldLabel ast.Field
105
106 func (l *fieldLabel) labelString() string {
107 lab := l.Label
108
109 if a, ok := lab.(*ast.Alias); ok {
110 if x, _ := a.Expr.(ast.Label); x != nil {
111 lab = x
112 }
113 }
114
115 switch x := lab.(type) {
116 case *ast.Ident:
117 return x.Name
118
119 case *ast.BasicLit:
120 if x.Kind == token.STRING {
121 s, err := literal.Unquote(x.Value)
122 if err == nil && ast.IsValidIdent(s) {
123 return s
124 }
125 }
126 return x.Value
127
128 case *ast.ListLit:
129 return "[]"
130
131 case *ast.Interpolation:
132 return "?"
133
134 }
135 return "<unknown>"
136 }
137
138 type forScope ast.ForClause
139
140 func (l *forScope) labelString() string {
141
142 return "for[]"
143 }
144
145 type letScope ast.LetClause
146
147 func (l *letScope) labelString() string {
148
149 return "let[]"
150 }
151
View as plain text