diff --git a/cue/types.go b/cue/types.go index b37631ffa..6ef9b5c86 100644 --- a/cue/types.go +++ b/cue/types.go @@ -984,6 +984,24 @@ func (v Value) Pos() token.Pos { // TODO: IsFinal: this value can never be changed. +// IsClosed reports whether a list of struct is closed. It reports false when +// when the value is not a list or struct. +func (v Value) IsClosed() bool { + switch v.Kind() { + case StructKind: + if st, ok := v.path.val().(*structLit); ok { + return st.closeStatus.shouldClose() + } + case ListKind: + if l, ok := v.path.val().(*list); ok { + if n, ok := l.len.(*numLit); ok { + return n.intValue(v.ctx()) == len(l.elem.arcs) + } + } + } + return false +} + // IsConcrete reports whether the current value is a concrete scalar value // (not relying on default values), a terminal error, a list, or a struct. // It does not verify that values of lists or structs are concrete themselves. diff --git a/cue/types_test.go b/cue/types_test.go index 4a9611e5e..aa4da04c0 100644 --- a/cue/types_test.go +++ b/cue/types_test.go @@ -50,6 +50,7 @@ func TestValueType(t *testing.T) { json string valid bool concrete bool + closed bool // pos token.Pos }{{ // Not a concrete value. value: `v: _`, @@ -151,11 +152,18 @@ func TestValueType(t *testing.T) { kind: StructKind, incompleteKind: StructKind, concrete: true, + }, { + value: `v: close({})`, + kind: StructKind, + incompleteKind: StructKind, + concrete: true, + closed: true, }, { value: `v: []`, kind: ListKind, incompleteKind: ListKind, concrete: true, + closed: true, }, { value: `v: {a: int, b: [1][a]}.b`, kind: BottomKind, @@ -199,6 +207,9 @@ func TestValueType(t *testing.T) { if got := v.IsConcrete(); got != tc.concrete { t.Errorf("IsConcrete: got %v; want %v", got, tc.concrete) } + if got := v.IsClosed(); got != tc.closed { + t.Errorf("IsClosed: got %v; want %v", got, tc.closed) + } }) } } diff --git a/cue/value.go b/cue/value.go index 3ba7d6592..52abfd194 100644 --- a/cue/value.go +++ b/cue/value.go @@ -397,7 +397,6 @@ func (x *numLit) isInt(ctx *context) bool { func (x *numLit) intValue(ctx *context) int { v, err := x.v.Int64() if err != nil { - ctx.mkErr(x, "intValue: %v", err) return 0 } return int(v)