Skip to content

Commit

Permalink
internal/core/adt: improve error message for optional fields
Browse files Browse the repository at this point in the history
Fixes #455

Change-Id: Ic1d2a14541a9b6507db64502a56891c92a382e32
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7802
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
  • Loading branch information
mpvl committed Nov 28, 2020
1 parent d49777f commit d0dd888
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 6 deletions.
4 changes: 2 additions & 2 deletions cue/testdata/fulleval/029_Issue_#94.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ index: {
}
select: (struct){
opt: (_|_){
// [incomplete] select.opt: undefined field opt:
// [incomplete] select.opt: cannot reference optional field opt:
// ./in.cue:10:15
}
txt: (int){ 2 }
Expand All @@ -107,7 +107,7 @@ index: {
}
index: (struct){
opt: (_|_){
// [incomplete] index.opt: undefined field opt:
// [incomplete] index.opt: cannot reference optional field opt:
// ./in.cue:17:15
}
txt: (int){ 2 }
Expand Down
2 changes: 1 addition & 1 deletion cue/testdata/references/optional.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ a: {
(struct){
a: (struct){
b: (_|_){
// [incomplete] a.b: undefined field foo:
// [incomplete] a.b: cannot reference optional field foo:
// ./in.cue:4:8
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ r: {
(struct){
r: (struct){
b: (_|_){
// [incomplete] r.b: undefined field a:
// [incomplete] r.b: cannot reference optional field a:
// ./in.cue:3:6
}
c: (_|_){
// [incomplete] r.c: undefined field a:
// [incomplete] r.c: cannot reference optional field a:
// ./in.cue:4:8
}
}
Expand Down
4 changes: 4 additions & 0 deletions internal/core/adt/composite.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,10 @@ type Acceptor interface {
// OptionalTypes returns a bit field with the type of optional constraints
// that are represented by this Acceptor.
OptionalTypes() OptionalType

// IsOptional reports whether a field is explicitly defined as optional,
// as opposed to whether it is allowed by a pattern constraint.
IsOptional(f Feature) bool
}

// OptionalType is a bit field of the type of optional constraints in use by an
Expand Down
7 changes: 6 additions & 1 deletion internal/core/adt/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,12 @@ func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature) *Vertex {
c.addErrf(code, pos, "index out of range [%d] with length %d",
l.Index(), len(x.Elems()))
} else {
c.addErrf(code, pos, "undefined field %s", label)
if code != 0 && x.Closed != nil && x.Closed.IsOptional(l) {
c.addErrf(code, pos,
"cannot reference optional field %s", label)
} else {
c.addErrf(code, pos, "undefined field %s", label)
}
}
}
return a
Expand Down
8 changes: 8 additions & 0 deletions internal/core/eval/closed.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ func (a *acceptor) OptionalTypes() (mask adt.OptionalType) {
return mask
}

func (a *acceptor) IsOptional(label adt.Feature) bool {
optional := false
a.visitAllFieldSets(func(f *fieldSet) {
optional = optional || f.IsOptional(label)
})
return optional
}

// A disjunction acceptor represents a disjunction of all possible fields. Note
// that this is never used in evaluation as evaluation stops at incomplete nodes
// and a disjunction is incomplete. When the node is referenced, the original
Expand Down
9 changes: 9 additions & 0 deletions internal/core/eval/optionals.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ func (o *fieldSet) OptionalTypes() (mask adt.OptionalType) {
return mask
}

func (o *fieldSet) IsOptional(label adt.Feature) bool {
for _, f := range o.fields {
if f.label == label && len(f.optional) > 0 {
return true
}
}
return false
}

type field struct {
label adt.Feature
optional []adt.Node
Expand Down

0 comments on commit d0dd888

Please sign in to comment.