cue/parser: improve error message for misused keywords
Change-Id: Id6eb40d23e3a5ad7737933c1e188f0822d047df8
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3963
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/parser/parser.go b/cue/parser/parser.go
index 4744ceb..7ef6ef1 100644
--- a/cue/parser/parser.go
+++ b/cue/parser/parser.go
@@ -1008,11 +1008,25 @@
case token.IF, token.FOR, token.IN, token.LET:
// Keywords representing clauses.
- label = &ast.Ident{
- NamePos: p.pos,
+ pos := p.pos
+ ident := &ast.Ident{
+ NamePos: pos,
Name: p.lit,
}
+ c := p.openComments()
p.next()
+ expr = c.closeExpr(p, ident)
+
+ if p.tok != token.COLON && p.tok != token.ISA {
+ c = p.openComments()
+ p.errf(pos, "expected operand, found '%s'", ident.Name)
+ expr = &ast.BadExpr{From: pos, To: p.pos}
+ // Sync expression.
+ expr = p.parseBinaryExprTail(false, token.LowestPrec+1, expr)
+ expr = c.closeExpr(p, expr)
+ break
+ }
+ label = ident
ok = true
case token.LSS:
diff --git a/cue/parser/parser_test.go b/cue/parser/parser_test.go
index 4148d6e..e6f83fe 100644
--- a/cue/parser/parser_test.go
+++ b/cue/parser/parser_test.go
@@ -453,6 +453,12 @@
`[Y=string]: {name: Y}, ` +
`X1=[X2=<"d"]: {name: X2}, ` +
`Y1=foo: {Y2=bar: [Y1, Y2]}`,
+ }, {
+ desc: "error when keyword is used in expression",
+ in: `
+ foo: in & 2
+ `,
+ out: "foo: <*ast.BadExpr>&2\nexpected operand, found 'in'",
}}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
@@ -461,10 +467,11 @@
mode = append(mode, ParseComments)
}
f, err := ParseFile("input", tc.in, mode...)
+ got := debugStr(f)
if err != nil {
- t.Errorf("unexpected error: %v", err)
+ got += "\n" + err.Error()
}
- if got := debugStr(f); got != tc.out {
+ if got != tc.out {
t.Errorf("\ngot %q;\nwant %q", got, tc.out)
}
})
@@ -639,7 +646,8 @@
func TestX(t *testing.T) {
t.Skip()
- f, err := ParseFile("input", `a: b:: c?: <Name>: d: 1`)
+ f, err := ParseFile("input", `
+ `)
if err != nil {
t.Errorf("unexpected error: %v", err)
}