cue/ast/astutil: improve LabelName logic
Change-Id: I256569a137ebab1ad4a9fec730f4237641b2cc9a
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/4382
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/ast/astutil/resolve.go b/cue/ast/astutil/resolve.go
index 4282a3e..6f923fb 100644
--- a/cue/ast/astutil/resolve.go
+++ b/cue/ast/astutil/resolve.go
@@ -68,6 +68,8 @@
label := x.Label
if a, ok := x.Label.(*ast.Alias); ok {
+ // TODO(legacy): use name := a.Ident.Name once quoted
+ // identifiers are no longer supported.
if name, _, _ := ast.LabelName(a.Ident); name != "" {
s.insert(name, x)
}
diff --git a/cue/ast/ident.go b/cue/ast/ident.go
index b0a18d9..bbd4aea 100644
--- a/cue/ast/ident.go
+++ b/cue/ast/ident.go
@@ -128,46 +128,55 @@
// X=foo "foo" true nil
//
func LabelName(l Label) (name string, isIdent bool, err error) {
- a, ok := l.(*Alias)
- if ok {
- if l, ok = a.Expr.(Label); !ok {
- goto expressionLabel
- }
+ if a, ok := l.(*Alias); ok {
+ l, _ = a.Expr.(Label)
}
switch n := l.(type) {
case *ListLit:
- // An expression, but not one can evaluated.
+ // An expression, but not one that can evaluated.
return "", false, errors.Newf(l.Pos(),
"cannot reference fields with square brackets labels outside the field value")
case *Ident:
- str, err := ParseIdent(n)
+ // TODO(legacy): use name = n.Name
+ name, err = ParseIdent(n)
if err != nil {
return "", false, err
}
- return str, true, nil
+ isIdent = true
+ // TODO(legacy): remove this return once quoted identifiers are removed.
+ return name, isIdent, err
case *BasicLit:
switch n.Kind {
case token.STRING:
// Use strconv to only allow double-quoted, single-line strings.
- str, err := strconv.Unquote(n.Value)
+ name, err = strconv.Unquote(n.Value)
if err != nil {
err = errors.Newf(l.Pos(), "invalid")
}
- return str, false, err
case token.NULL, token.TRUE, token.FALSE:
- return n.Value, true, nil
+ name = n.Value
+ isIdent = true
- // TODO: allow numbers to be fields?
+ default:
+ // TODO: allow numbers to be fields
+ // This includes interpolation and template labels.
+ return "", false, errors.Wrapf(ErrIsExpression, l.Pos(),
+ "cannot use numbers as fields")
}
- }
-expressionLabel:
- // This includes interpolation and template labels.
- return "", false, errors.Wrapf(ErrIsExpression, l.Pos(),
- "label is an expression")
+ default:
+ // This includes interpolation and template labels.
+ return "", false, errors.Wrapf(ErrIsExpression, l.Pos(),
+ "label is an expression")
+ }
+ if !IsValidIdent(name) {
+ isIdent = false
+ }
+ return name, isIdent, err
+
}
// ErrIsExpression reports whether a label is an expression.