cue: pass on compile-time errors
Be more aggressive with compile-time errors.
These were currently burried in the data
and only surfaced when explicitly visited.
Change-Id: I690c5c20ea40b9a43117bce72770c8ee824f99da
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3762
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/ast.go b/cue/ast.go
index 07c4d1a..a4ac89f 100644
--- a/cue/ast.go
+++ b/cue/ast.go
@@ -47,10 +47,8 @@
if isBottom(result) {
val := newValueRoot(v.ctx(), result)
v.errors = errors.Append(v.errors, val.toErr(result.(*bottom)))
- return v.errors
}
-
- return nil
+ return v.errors
}
type astVisitor struct {
diff --git a/cue/ast_test.go b/cue/ast_test.go
index 2b510ce..1517236 100644
--- a/cue/ast_test.go
+++ b/cue/ast_test.go
@@ -255,8 +255,11 @@
a: *1,
b: **1 | 2
`,
- out: `<0>{a: _|_(preference mark not allowed at this position), ` +
- `b: (*_|_(preference mark not allowed at this position) | 2)}`,
+ out: `a: preference mark not allowed at this position:
+ test:2:7
+b: preference mark not allowed at this position:
+ test:3:8
+<0>{}`,
}, {
in: `
a: int @foo(1,"str")
diff --git a/cue/build.go b/cue/build.go
index 532cdde..3a8712b 100644
--- a/cue/build.go
+++ b/cue/build.go
@@ -323,7 +323,8 @@
// inst.instance.inst = p
inst.Err = resolveFiles(idx, p)
for _, f := range files {
- inst.insertFile(f)
+ err := inst.insertFile(f)
+ inst.Err = errors.Append(inst.Err, err)
}
}
inst.ImportPath = p.ImportPath
diff --git a/cue/build/instance.go b/cue/build/instance.go
index c0197a6..b8a792c 100644
--- a/cue/build/instance.go
+++ b/cue/build/instance.go
@@ -21,6 +21,7 @@
"unicode"
"cuelang.org/go/cue/ast"
+ "cuelang.org/go/cue/ast/astutil"
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/parser"
"cuelang.org/go/cue/token"
@@ -206,6 +207,9 @@
// AddSyntax adds the given file to list of files for this instance. The package
// name of the file must match the package name of the instance.
func (inst *Instance) AddSyntax(file *ast.File) errors.Error {
+ astutil.Resolve(file, func(pos token.Pos, msg string, args ...interface{}) {
+ inst.Err = errors.Append(inst.Err, errors.Newf(pos, msg, args...))
+ })
_, pkg, pos := internal.PackageInfo(file)
if !inst.setPkg(pkg) && pkg != inst.PkgName {
err := errors.Newf(pos,
diff --git a/cue/build_test.go b/cue/build_test.go
index 832ceea..cd89e92 100644
--- a/cue/build_test.go
+++ b/cue/build_test.go
@@ -65,7 +65,7 @@
`),
}
pkg2 := &bimport{
- "example.com/foo/pkg2",
+ "example.com/foo/pkg2:pkg",
files(`
package pkg
@@ -152,18 +152,18 @@
files(
`package test
- import "example.com/foo/pkg2"
+ import "example.com/foo/pkg2:pkg"
"Hello \(pkg2.Number)!"`),
}),
- `imported and not used: "example.com/foo/pkg2"`,
+ `imported and not used: "example.com/foo/pkg2:pkg" (and 1 more errors)`,
// `file0.cue:5:14: unresolved reference pkg2`,
}, {
insts(pkg2, &bimport{"",
files(
`package test
- import "example.com/foo/pkg2"
+ import "example.com/foo/pkg2:pkg"
"Hello \(pkg.Number)!"`),
}),
diff --git a/cue/go_test.go b/cue/go_test.go
index e16017e..d0411b4 100644
--- a/cue/go_test.go
+++ b/cue/go_test.go
@@ -125,7 +125,7 @@
}, {
time.Date(2019, 4, 1, 0, 0, 0, 0, time.UTC), `"2019-04-01T00:00:00Z"`,
}}
- inst := getInstance(t, "foo")
+ inst := getInstance(t, "{}")
b := ast.NewIdent("dummy")
for _, tc := range testCases {
ctx := inst.newContext()
@@ -228,7 +228,7 @@
time.Now, // a function
"_|_(unsupported Go type (func() time.Time))",
}}
- inst := getInstance(t, "foo")
+ inst := getInstance(t, "{}")
for _, tc := range testCases {
ctx := inst.newContext()
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index f5db2a2..f3bac0a 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -28,6 +28,7 @@
}
func compileFile(t *testing.T, body string) (*context, *structLit) {
+ t.Helper()
ctx, inst, errs := compileInstance(t, body)
if errs != nil {
t.Fatal(errs)
diff --git a/cue/subsume_test.go b/cue/subsume_test.go
index 176b092..b95dd72 100644
--- a/cue/subsume_test.go
+++ b/cue/subsume_test.go
@@ -173,27 +173,29 @@
// Call
113: {subsumes: true, in: `
- a: fn(),
- b: fn()`,
+ a: fn()
+ b: fn()
+ fn: _`,
},
- // TODO: allow subsumption of unevaluated values?
- 114: {subsumes: true, in: `
- a: len(),
- b: len(1)`,
+ 114: {subsumes: false, in: `
+ a: fn(),
+ b: fn(1)
+ fn: _`,
},
115: {subsumes: true, in: `
a: fn(2)
- b: fn(2)`,
+ b: fn(2)
+ fn: _`,
},
- // TODO: allow subsumption of unevaluated values?
116: {subsumes: true, in: `
a: fn(number)
- b: fn(2)`,
+ b: fn(2)
+ fn: _`,
},
- // TODO: allow subsumption of unevaluated values?
- 117: {subsumes: true, in: `
+ 117: {subsumes: false, in: `
a: fn(2)
- b: fn(number)`,
+ b: fn(number)
+ fn: _`,
},
// TODO: allow subsumption of unevaluated values?
diff --git a/cue/types_test.go b/cue/types_test.go
index cc991f1..c892443 100644
--- a/cue/types_test.go
+++ b/cue/types_test.go
@@ -63,13 +63,13 @@
kind: BottomKind,
incompleteKind: BottomKind,
concrete: true,
- }, { // TODO: should be error{
- value: `v: b`,
+ }, {
+ value: `v: b, b: 1&2`,
kind: BottomKind,
incompleteKind: BottomKind,
concrete: true,
}, {
- value: `v: (b[a])`,
+ value: `v: (b[a]), b: 1, a: 1`,
kind: BottomKind,
incompleteKind: BottomKind,
concrete: true,
@@ -79,7 +79,7 @@
kind: BottomKind,
incompleteKind: BoolKind,
}, {
- value: `v: ([][b])`,
+ value: `v: ([][b]), b: "d"`,
kind: BottomKind,
incompleteKind: BottomKind,
concrete: true,
@@ -1129,10 +1129,9 @@
t.Run(tc.desc, func(t *testing.T) {
r := Runtime{}
inst, err := r.Parse("validate", tc.in)
- if err != nil {
- t.Fatal(err)
+ if err == nil {
+ err = inst.Value().Validate(tc.opts...)
}
- err = inst.Value().Validate(tc.opts...)
if gotErr := err != nil; gotErr != tc.err {
t.Errorf("got %v; want %v", err, tc.err)
}
diff --git a/doc/tutorial/basics/6_expressions/25_interpolfield.txt b/doc/tutorial/basics/6_expressions/25_interpolfield.txt
index 963828c..9c90fdf 100644
--- a/doc/tutorial/basics/6_expressions/25_interpolfield.txt
+++ b/doc/tutorial/basics/6_expressions/25_interpolfield.txt
@@ -1,5 +1,5 @@
-cue eval -i genfield.cue
-cmp stdout expect-stdout-cue
+! cue eval genfield.cue
+cmp stderr expect-stderr
-- frontmatter.toml --
title = "Interpolation of Field Names"
@@ -18,10 +18,6 @@
butterAndCheese: hasButter && hasCheese
}
--- expect-stdout-cue --
-sandwich: {
- type: "Cheese"
- hasButter: true
- butterAndCheese: _|_ // reference "hasCheese" not found
- hasCheese: true
-}
+-- expect-stderr --
+sandwich.butterAndCheese: reference "hasCheese" not found:
+ ./genfield.cue:5:35
diff --git a/doc/tutorial/basics/6_expressions/80_coalesce.txt b/doc/tutorial/basics/6_expressions/80_coalesce.txt
index 783e6c9..41cd1e1 100644
--- a/doc/tutorial/basics/6_expressions/80_coalesce.txt
+++ b/doc/tutorial/basics/6_expressions/80_coalesce.txt
@@ -34,7 +34,7 @@
b: *list[5] | "None"
n: [null]
-v: *n[0]&string | "default"
+v: *(n[0]&string) | "default"
-- expect-stdout-cue --
list: ["Cat", "Mouse", "Dog"]