cue/parser: record position of deprecated feature
Change-Id: I8f1dbac1dd325324977a5e08ca94c64866f1a8d6
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3875
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/parser/interface.go b/cue/parser/interface.go
index ce09af3..302eb38 100644
--- a/cue/parser/interface.go
+++ b/cue/parser/interface.go
@@ -17,6 +17,8 @@
package parser
import (
+ "fmt"
+
"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/ast/astutil"
"cuelang.org/go/cue/errors"
@@ -87,6 +89,16 @@
return -1000 + 100*minor + patch
}
+// DeprecationError is a sentinel error to indicate that an error is
+// related to an unsupported old CUE syntax.
+type DeprecationError struct {
+ Version int
+}
+
+func (e *DeprecationError) Error() string {
+ return fmt.Sprintf("try running `cue fmt` on the file to upgrade.")
+}
+
// Latest specifies the latest version of the parser, effectively setting
// the strictest implementation.
const Latest = latest
diff --git a/cue/parser/parser.go b/cue/parser/parser.go
index 296b19e..4744ceb 100644
--- a/cue/parser/parser.go
+++ b/cue/parser/parser.go
@@ -275,7 +275,7 @@
// Scan the comment for '\n' chars and adjust endline accordingly.
endline = p.file.Line(p.pos)
if p.lit[1] == '*' {
- p.assertV0(0, 10, "block quotes")
+ p.assertV0(p.pos, 0, 10, "block quotes")
// don't use range here - no need to decode Unicode code points
for i := 0; i < len(p.lit); i++ {
@@ -368,9 +368,12 @@
}
}
-func (p *parser) assertV0(minor, patch int, name string) {
- if p.version != 0 && p.version > version0(minor, patch) {
- p.errf(p.pos, "%s deprecated as of v0.%d.%d", name, minor, patch+1)
+func (p *parser) assertV0(pos token.Pos, minor, patch int, name string) {
+ v := version0(minor, patch)
+ if p.version != 0 && p.version > v {
+ p.errors = errors.Append(p.errors,
+ errors.Wrapf(&DeprecationError{v}, pos,
+ "%s deprecated as of v0.%d.%d", name, minor, patch+1))
}
}
@@ -826,7 +829,7 @@
switch p.tok {
case token.IDENT, token.STRING, token.LSS, token.INTERPOLATION, token.LBRACK:
- p.assertV0(0, 12, "space-separated labels")
+ p.assertV0(p.pos, 0, 12, "space-separated labels")
field := &ast.Field{}
m.Value = &ast.StructLit{Elts: []ast.Decl{field}}
m = field
@@ -909,6 +912,7 @@
fallthrough
case token.FOR, token.IF:
+ p.assertV0(p.pos, 0, 10, "old-style comprehensions")
if !allowComprehension {
p.errf(p.pos, "comprehension not allowed for this field")
}
@@ -1070,7 +1074,7 @@
p.next()
}
- p.assertV0(0, 12, "template labels")
+ p.assertV0(p.pos, 0, 12, "template labels")
label = &ast.TemplateLabel{Langle: pos, Ident: ident, Rangle: gtr}
c.closeNode(p, label)
ok = true