cue/ast: introduce NewNull()

This seems like a trivial helper, but defining a null
value properly is somewhat unintuitive and
cumbersome.

This fixes a bug in the go converter and jsonschema
as well.

Change-Id: I14d2bda3b74f846dbfa7cd19c791c263dc87e7a8
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/6305
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/get_go.go b/cmd/cue/cmd/get_go.go
index 7891980..d085723 100644
--- a/cmd/cue/cmd/get_go.go
+++ b/cmd/cue/cmd/get_go.go
@@ -942,7 +942,7 @@
 	switch x := expr.(type) {
 	case *types.Pointer:
 		return &cueast.BinaryExpr{
-			X:  e.ident("null", false),
+			X:  cueast.NewNull(),
 			Op: cuetoken.OR,
 			Y:  e.makeType(x.Elem()),
 		}
diff --git a/cue.mod/pkg/github.com/SchemaStore/schemastore/src/schemas/json/github-workflow.cue b/cue.mod/pkg/github.com/SchemaStore/schemastore/src/schemas/json/github-workflow.cue
index 2a8dc62..9db3227 100644
--- a/cue.mod/pkg/github.com/SchemaStore/schemastore/src/schemas/json/github-workflow.cue
+++ b/cue.mod/pkg/github.com/SchemaStore/schemastore/src/schemas/json/github-workflow.cue
@@ -424,8 +424,7 @@
 					// environment variables. The variable is prefixed with INPUT_
 					// and converted to upper case.
 					with?: #env & {
-						args?: string, entrypoint?: string
-						...
+						args?: string, entrypoint?: string, ...
 					}
 
 					// Prevents a job from failing when a step fails. Set to true to
@@ -466,7 +465,7 @@
 					// https://help.github.com/en/articles/contexts-and-expression-syntax-for-github-actions.
 					matrix: {
 						{[=~"^(in|ex)clude$" & !~"^()$"]: [...{
-							[string]: #configuration
+											[string]: #configuration
 						}] & [_, ...]}
 
 						{[!~"^(in|ex)clude$" & !~"^()$"]: [...#configuration] & [_, ...]}
diff --git a/cue/ast/ast.go b/cue/ast/ast.go
index 798f73a..8da2de5 100644
--- a/cue/ast/ast.go
+++ b/cue/ast/ast.go
@@ -435,6 +435,12 @@
 	return &BasicLit{Kind: token.STRING, ValuePos: token.NoPos, Value: str}
 }
 
+// NewNull creates a new BasicLit configured to be a null value.
+// Useful for ASTs generated by code other than the CUE parser.
+func NewNull() *BasicLit {
+	return &BasicLit{Kind: token.NULL, Value: "null"}
+}
+
 // NewLit creates a new BasicLit with from a token type and string without
 // position.
 // Useful for ASTs generated by code other than the CUE parser.
diff --git a/cue/export.go b/cue/export.go
index 251e0e9..af4e116 100644
--- a/cue/export.go
+++ b/cue/export.go
@@ -613,7 +613,7 @@
 		}
 
 	case *nullLit:
-		return &ast.BasicLit{Kind: token.NULL, Value: "null"}
+		return ast.NewNull()
 
 	case *boolLit:
 		return ast.NewBool(x.b)
diff --git a/encoding/jsonschema/decode.go b/encoding/jsonschema/decode.go
index cbc7bb1..302084e 100644
--- a/encoding/jsonschema/decode.go
+++ b/encoding/jsonschema/decode.go
@@ -314,7 +314,7 @@
 		switch k {
 		case cue.NullKind:
 			// TODO: handle OpenAPI restrictions.
-			add(ast.NewIdent("null"))
+			add(ast.NewNull())
 		case cue.BoolKind:
 			add(ast.NewIdent("bool"))
 		case cue.StringKind:
diff --git a/encoding/protobuf/types.go b/encoding/protobuf/types.go
index 60b55af..b451fbf 100644
--- a/encoding/protobuf/types.go
+++ b/encoding/protobuf/types.go
@@ -99,7 +99,7 @@
 		}, nil)
 
 		p.setBuiltin("google.protobuf.NullValue", func() ast.Expr {
-			return ast.NewLit(token.NULL, "null")
+			return ast.NewNull()
 		}, nil)
 
 		p.setBuiltin("google.protobuf.ListValue", func() ast.Expr {