Skip to content

Commit e7e27e0

Browse files
committed
internal/core/export: allow showing recursive errors.
Change-Id: I40393ce06fe3728c9a362ee68845e55a67119057 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7848 Reviewed-by: CUE cueckoo <[email protected]> Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent 039fb59 commit e7e27e0

File tree

4 files changed

+150
-12
lines changed

4 files changed

+150
-12
lines changed

internal/core/export/export.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ type Profile struct {
4747
ShowDocs bool
4848
ShowAttributes bool
4949

50-
// AllowErrorType
50+
// ShowErrors treats errors as values and will not percolate errors up.
51+
ShowErrors bool
5152
// Use unevaluated conjuncts for these error types
5253
// IgnoreRecursive
5354

@@ -176,6 +177,7 @@ func Vertex(r adt.Runtime, pkgID string, n *adt.Vertex) (*ast.File, errors.Error
176177

177178
func (p *Profile) Vertex(r adt.Runtime, pkgID string, n *adt.Vertex) (*ast.File, errors.Error) {
178179
e := exporter{
180+
ctx: eval.NewContext(r, nil),
179181
cfg: p,
180182
index: r,
181183
pkgID: pkgID,

internal/core/export/testdata/adt.txtar

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ y1: {
7979

8080
}
8181

82+
errorStructDef: {
83+
a: 1
84+
b: 1 & 2
85+
86+
#Def: 1
87+
}
88+
89+
errorList: [
90+
1,
91+
1 & 2,
92+
]
93+
94+
errorListDef: {
95+
errorList
96+
97+
#Def: 1
98+
}
99+
82100
-- out/definition --
83101
import mystrings "strings"
84102

@@ -144,6 +162,16 @@ y1: {
144162
"foo\(i)": v
145163
}
146164
}
165+
errorStructDef: {
166+
a: 1
167+
b: _|_ // conflicting values 2 and 1
168+
#Def: 1
169+
}
170+
errorList: [1, 1 & 2]
171+
errorListDef: {
172+
errorList
173+
#Def: 1
174+
}
147175
-- out/doc --
148176
[]
149177
[p1]
@@ -192,6 +220,17 @@ y1: {
192220
[y1 bar2]
193221
[y1 foo1]
194222
[y1 foo2]
223+
[errorStructDef]
224+
[errorStructDef a]
225+
[errorStructDef b]
226+
[errorStructDef #Def]
227+
[errorList]
228+
[errorList 0]
229+
[errorList 1]
230+
[errorListDef]
231+
[errorListDef #Def]
232+
[errorListDef 0]
233+
[errorListDef 1]
195234
[x]
196235
-- out/value --
197236
== Simplified
@@ -201,4 +240,68 @@ _|_ // e3: index out of range [2] with length 2
201240
== Final
202241
_|_ // e3: index out of range [2] with length 2
203242
== All
204-
_|_ // e3: index out of range [2] with length 2
243+
{
244+
p1: {}
245+
d1: {
246+
foobar: int
247+
}
248+
bar: "bar"
249+
250+
// XXX: reference not resolving.
251+
d2: {
252+
foobar: {
253+
name: "xx"
254+
foo: "xx"
255+
}
256+
}
257+
bytes: '\xeb \x1a\xf5\xaa\xf0\xd6\x06)'
258+
c1: true
259+
s1: """
260+
multi
261+
bar
262+
line
263+
"""
264+
l1: [3]
265+
l2: []
266+
l3: []
267+
l4: [1, 2]
268+
n1: 1.0
269+
n10: 10
270+
271+
// t is true
272+
t: true
273+
e1: <1.0
274+
e2: >1.0 & <10
275+
e3: _|_ // e3: index out of range [2] with length 2
276+
e4: _|_ // e4: index 3 out of range
277+
e5: _|_ // e3: index out of range [2] with length 2
278+
e6: false
279+
e7: true
280+
e8?: true
281+
m1: {
282+
// foo is an optional field
283+
foo?: 3
284+
285+
// bar is a field
286+
bar: 4
287+
}
288+
y1: {
289+
src: [1, 2, 3]
290+
foo0: 1
291+
bar1: 2
292+
bar2: 3
293+
foo1: 2
294+
foo2: 3
295+
}
296+
errorStructDef: {
297+
a: 1
298+
b: _|_ // errorStructDef.b: conflicting values 2 and 1
299+
#Def: 1
300+
}
301+
errorList: [1, _|_]
302+
x: int
303+
errorListDef: {
304+
#Def: 1
305+
[1, _|_]
306+
}
307+
}

internal/core/export/value.go

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,26 @@ func (e *exporter) vertex(n *adt.Vertex) (result ast.Expr) {
5555
}
5656

5757
case *adt.Bottom:
58-
if !x.IsIncomplete() || len(n.Conjuncts) == 0 {
58+
switch {
59+
case e.cfg.ShowErrors && x.ChildError:
60+
// TODO(perf): use precompiled arc statistics
61+
if len(n.Arcs) > 0 && n.Arcs[0].Label.IsInt() && !e.showArcs(n) {
62+
result = e.listComposite(n)
63+
} else {
64+
result = e.structComposite(n)
65+
}
66+
67+
case !x.IsIncomplete() || len(n.Conjuncts) == 0:
5968
result = e.bottom(x)
60-
break
61-
}
6269

63-
// fall back to expression mode
64-
a := []ast.Expr{}
65-
for _, c := range n.Conjuncts {
66-
a = append(a, e.expr(c.Expr()))
70+
default:
71+
// fall back to expression mode
72+
a := []ast.Expr{}
73+
for _, c := range n.Conjuncts {
74+
a = append(a, e.expr(c.Expr()))
75+
}
76+
result = ast.NewBinExpr(token.AND, a...)
6777
}
68-
result = ast.NewBinExpr(token.AND, a...)
6978

7079
case adt.Value:
7180
if e.showArcs(n) {
@@ -339,6 +348,24 @@ func (e *exporter) structComposite(v *adt.Vertex) ast.Expr {
339348
case *adt.ListMarker:
340349
// As lists may be long, put them at the end.
341350
defer e.addEmbed(e.listComposite(v))
351+
case *adt.Bottom:
352+
if !e.cfg.ShowErrors || !x.ChildError {
353+
// Should not be reachable, but just in case. The output will be
354+
// correct.
355+
e.addEmbed(e.value(x))
356+
return s
357+
}
358+
// Always also show regular fields, even when list, as we are in
359+
// debugging mode.
360+
showRegular = true
361+
// TODO(perf): do something better
362+
for _, a := range v.Arcs {
363+
if a.Label.IsInt() {
364+
defer e.addEmbed(e.listComposite(v))
365+
break
366+
}
367+
}
368+
342369
case adt.Value:
343370
e.addEmbed(e.value(x))
344371
}

internal/core/export/value_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,17 @@ func TestValue(t *testing.T) {
5757
ctx := eval.NewContext(r, v)
5858
v.Finalize(ctx)
5959

60+
all := export.All
61+
all.ShowErrors = true
62+
6063
for _, tc := range []struct {
6164
name string
6265
fn func(r adt.Runtime, id string, v adt.Value) (ast.Expr, errors.Error)
6366
}{
6467
{"Simplified", export.Simplified.Value},
6568
{"Raw", export.Raw.Value},
6669
{"Final", export.Final.Value},
67-
{"All", export.All.Value},
70+
{"All", all.Value},
6871
} {
6972
fmt.Fprintln(t, "==", tc.name)
7073
x, errs := tc.fn(r, pkgID, v)
@@ -99,7 +102,10 @@ strings.MinRunes(4) & strings.MaxRunes(7)
99102
ctx := eval.NewContext(r, v)
100103
v.Finalize(ctx)
101104

102-
x, errs := export.Simplified.Value(r, "main", v)
105+
p := export.All
106+
p.ShowErrors = true
107+
108+
x, errs := p.Value(r, "main", v)
103109
if errs != nil {
104110
t.Fatal(errs)
105111
}

0 commit comments

Comments
 (0)