cue: add optional fields
Optional fields are crucial in making it manageable
to work with very large struct types, like those of
Kubernetes. Without optional fields, the fields of
a simple K8s configuration would be lost in the noise
compared to the default value of every expanded field.
It also allows writing:
foo?: MyStruct
instead of
foo: *null | MyStruct
which gets old quickly when one has hundreds of
such fields.
Updates #24
Change-Id: I856d9a3e20584750b911784924fa18d4557b9920
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/1700
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cue/ast.go b/cue/ast.go
index b6924b4..5e02b9e 100644
--- a/cue/ast.go
+++ b/cue/ast.go
@@ -112,7 +112,7 @@
ctx := v.ctx()
label := v.label(n.Name, true)
if r := v.resolveRoot; r != nil {
- if value, _ := r.lookup(v.ctx(), label); value != nil {
+ if a := r.lookup(v.ctx(), label); a.val() != nil {
return &selectorExpr{newExpr(n),
&nodeRef{baseValue: newExpr(n), node: r}, label}
}
@@ -252,6 +252,7 @@
v.object.comprehensions = append(v.object.comprehensions, fc)
case *ast.Field:
+ opt := n.Optional != token.NoPos
switch x := n.Label.(type) {
case *ast.Interpolation:
yielder := &yield{baseValue: newNode(x)}
@@ -261,6 +262,7 @@
}
yielder.key = v.walk(x)
yielder.value = v.walk(n.Value)
+ yielder.opt = opt
v.object.comprehensions = append(v.object.comprehensions, fc)
case *ast.TemplateLabel:
@@ -289,7 +291,7 @@
return v.error(n.Label, "invalid field name: %v", n.Label)
}
if f != 0 {
- v.object.insertValue(v.ctx(), f, v.walk(n.Value), attrs)
+ v.object.insertValue(v.ctx(), f, opt, v.walk(n.Value), attrs)
}
default: