encoding/openapi: support Definitions

Fixes #131

Change-Id: Ic7581a22dddb0c6b01707c78ea9b051abfa0e0e2
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3584
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/encoding/openapi/build.go b/encoding/openapi/build.go
index 5fee0a5..8dc1db7 100644
--- a/encoding/openapi/build.go
+++ b/encoding/openapi/build.go
@@ -101,7 +101,7 @@
 
 	// Although paths is empty for now, it makes it valid OpenAPI spec.
 
-	i, err := inst.Value().Fields()
+	i, err := inst.Value().Fields(cue.Definitions(true))
 	if err != nil {
 		return nil, err
 	}
@@ -281,7 +281,11 @@
 	switch op, a := v.Expr(); op {
 	case cue.SelectorOp:
 		field, _ := a[1].String()
-		v = b.resolve(a[0]).Lookup(field)
+		f, _ := b.resolve(a[0]).LookupField(field)
+		v = cue.Value{}
+		if !f.IsOptional {
+			v = f.Value
+		}
 	}
 	return v
 }
@@ -615,7 +619,7 @@
 	}
 
 	required := []string{}
-	for i, _ := v.Fields(cue.Optional(false), cue.Hidden(false)); i.Next(); {
+	for i, _ := v.Fields(); i.Next(); {
 		required = append(required, i.Label())
 	}
 	if len(required) > 0 {
@@ -631,7 +635,7 @@
 		properties = &OrderedMap{}
 	}
 
-	for i, _ := v.Fields(cue.Optional(true), cue.Hidden(false)); i.Next(); {
+	for i, _ := v.Fields(cue.Optional(true)); i.Next(); {
 		label := i.Label()
 		var core *builder
 		if b.core != nil {
diff --git a/encoding/openapi/openapi_test.go b/encoding/openapi/openapi_test.go
index ea634ac..56a96cc 100644
--- a/encoding/openapi/openapi_test.go
+++ b/encoding/openapi/openapi_test.go
@@ -24,6 +24,7 @@
 	"testing"
 
 	"cuelang.org/go/cue"
+	"cuelang.org/go/cue/errors"
 	"cuelang.org/go/cue/load"
 	"github.com/kylelemons/godebug/diff"
 )
@@ -111,12 +112,21 @@
 				return strings.Join(path, ".")
 			},
 		},
+	}, {
+		"issue131.cue",
+		"issue131.json",
+		&Generator{Info: info, SelfContained: true},
 	}}
 	for _, tc := range testCases {
 		t.Run(tc.out, func(t *testing.T) {
-			filename := filepath.Join("testdata", filepath.FromSlash(tc.in))
+			filename := filepath.FromSlash(tc.in)
 
-			inst := cue.Build(load.Instances([]string{filename}, nil))[0]
+			inst := cue.Build(load.Instances([]string{filename}, &load.Config{
+				Dir: "./testdata",
+			}))[0]
+			if inst.Err != nil {
+				t.Fatal(errors.Details(inst.Err, nil))
+			}
 
 			b, err := Gen(inst, tc.config)
 			if err != nil {
diff --git a/encoding/openapi/testdata/cue.mod b/encoding/openapi/testdata/cue.mod
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/encoding/openapi/testdata/cue.mod
diff --git a/encoding/openapi/testdata/issue131.cue b/encoding/openapi/testdata/issue131.cue
new file mode 100644
index 0000000..5a8dd88
--- /dev/null
+++ b/encoding/openapi/testdata/issue131.cue
@@ -0,0 +1,7 @@
+package ext
+
+import "example.com/blocks"
+
+Blocks :: {
+	block1: blocks.Block
+}
diff --git a/encoding/openapi/testdata/issue131.json b/encoding/openapi/testdata/issue131.json
new file mode 100644
index 0000000..1fc5e56
--- /dev/null
+++ b/encoding/openapi/testdata/issue131.json
@@ -0,0 +1,40 @@
+{
+   "openapi": "3.0.0",
+   "info": {
+      "title": "test",
+      "version": "v1"
+   },
+   "paths": {},
+   "components": {
+      "schemas": {
+         "Blocks": {
+            "type": "object",
+            "required": [
+               "block1"
+            ],
+            "properties": {
+               "block1": {
+                  "$ref": "#/components/schemas/Block"
+               }
+            }
+         },
+         "Block": {
+            "type": "object",
+            "required": [
+               "a",
+               "b"
+            ],
+            "properties": {
+               "a": {
+                  "type": "number",
+                  "exclusiveMinimum": 50
+               },
+               "b": {
+                  "type": "number",
+                  "exclusiveMaximum": 10
+               }
+            }
+         }
+      }
+   }
+}
\ No newline at end of file
diff --git a/encoding/openapi/testdata/oneof.cue b/encoding/openapi/testdata/oneof.cue
index d318c50..768b442 100644
--- a/encoding/openapi/testdata/oneof.cue
+++ b/encoding/openapi/testdata/oneof.cue
@@ -1,10 +1,10 @@
-MyString: {
+MyString :: {
 	exact: string
 } | {
 	regex: string
 }
 
-MyInt: int
+MyInt :: int
 
 Foo: {
 	include: MyString
diff --git a/encoding/openapi/testdata/pkg/example.com/blocks/blocks.cue b/encoding/openapi/testdata/pkg/example.com/blocks/blocks.cue
new file mode 100644
index 0000000..fe9b8ce
--- /dev/null
+++ b/encoding/openapi/testdata/pkg/example.com/blocks/blocks.cue
@@ -0,0 +1,6 @@
+package blocks
+
+Block :: {
+	a: >50
+	b: <10
+}