Skip to content

Commit

Permalink
cue/ast: remove ParseIdent and support for quoted identifiers
Browse files Browse the repository at this point in the history
Quoted identifiers haven't been supported or used for years.
https://cuelang.org/cl/531206 dropped support for them entirely,
but missed the APIs in the cue/ast package itself.

Remove the deprecated ParseIdent API, just like the earlier CL
removed any APIs only useful for quoted identifiers,
and teach LabelName to return an error on quoted identifiers.
All other behavior should be left intact.

While here, we also simplify the LabelName logic a bit.

Signed-off-by: Daniel Martí <[email protected]>
Change-Id: I106163d4701e9eaf5796d5ac94975321259784a7
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1185684
TryBot-Result: CUEcueckoo <[email protected]>
Unity-Result: CUE porcuepine <[email protected]>
Reviewed-by: Paul Jolly <[email protected]>
  • Loading branch information
mvdan committed Mar 21, 2024
1 parent 35acbf4 commit f8ec1f4
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 84 deletions.
72 changes: 5 additions & 67 deletions cue/ast/ident.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,61 +70,6 @@ func IsValidIdent(ident string) bool {
return true
}

// ParseIdent unquotes a possibly quoted identifier and validates
// if the result is valid.
//
// Deprecated: quoted identifiers are deprecated. Use aliases.
func ParseIdent(n *Ident) (string, error) {
return parseIdent(n.NamePos, n.Name)
}

func parseIdent(pos token.Pos, ident string) (string, error) {
if ident == "" {
return "", errors.Newf(pos, "empty identifier")
}
quoted := false
if ident[0] == '`' {
u, err := strconv.Unquote(ident)
if err != nil {
return "", errors.Newf(pos, "invalid quoted identifier")
}
ident = u
quoted = true
}

p := 0
if strings.HasPrefix(ident, "_") {
p++
if len(ident) == 1 {
return ident, nil
}
}
if strings.HasPrefix(ident[p:], "#") {
p++
// if len(ident) == p {
// return "", errors.Newf(pos, "invalid identifier '_#'")
// }
}

if p == 0 || ident[p-1] == '#' {
if r, _ := utf8.DecodeRuneInString(ident[p:]); isDigit(r) {
return "", errors.Newf(pos, "invalid character '%s' in identifier", string(r))
}
}

for _, r := range ident[p:] {
if isLetter(r) || isDigit(r) || r == '_' || r == '$' {
continue
}
if r == '-' && quoted {
continue
}
return "", errors.Newf(pos, "invalid character '%s' in identifier", string(r))
}

return ident, nil
}

// LabelName reports the name of a label, whether it is an identifier
// (it binds a value to a scope), and whether it is valid.
// Keywords that are allowed in label positions are interpreted accordingly.
Expand All @@ -150,14 +95,11 @@ func LabelName(l Label) (name string, isIdent bool, err error) {
"cannot reference fields with square brackets labels outside the field value")

case *Ident:
// TODO(legacy): use name = n.Name
name, err = ParseIdent(n)
if err != nil {
return "", false, err
name = n.Name
if !IsValidIdent(name) {
return "", false, errors.Newf(l.Pos(), "invalid identifier")
}
isIdent = true
// TODO(legacy): remove this return once quoted identifiers are removed.
return name, isIdent, err
return name, true, err

case *BasicLit:
switch n.Kind {
Expand All @@ -178,17 +120,13 @@ func LabelName(l Label) (name string, isIdent bool, err error) {
return "", false, errors.Wrapf(ErrIsExpression, l.Pos(),
"cannot use numbers as fields")
}
return name, isIdent, err

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.
Expand Down
19 changes: 2 additions & 17 deletions cue/ast/ident_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,8 @@ func TestLabelName(t *testing.T) {
out: "foo bar",
isIdent: false,
}, {
in: &ast.Ident{Name: "`foo`"},
out: "foo",
isIdent: true,
in: &ast.Ident{Name: "`foo`"},
err: true,
}, {
in: &ast.Ident{Name: ""},
out: "",
Expand Down Expand Up @@ -105,20 +104,6 @@ func TestLabelName(t *testing.T) {
in: &ast.Ident{Name: "#_Def"},
out: "#_Def",
isIdent: true,
}, {
in: &ast.Ident{Name: "`foo-bar`"},
out: "foo-bar",
isIdent: true,
}, {
in: &ast.Ident{Name: "`foo-bar\x00`"},
out: "",
isIdent: false,
err: true,
}, {
in: &ast.Ident{Name: "`foo-bar\x00`"},
out: "",
isIdent: false,
err: true,
}, {
in: ast.NewBool(true),
out: "true",
Expand Down

0 comments on commit f8ec1f4

Please sign in to comment.