internal/core/export: fix definition wrapping
- use hidden definitions (for real)
- also handle recurisve cases
Change-Id: Ie44a9e5f67db36cd8bad0a255ddb8053684a1723
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9486
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Paul Jolly <paul@myitcv.org.uk>
diff --git a/cmd/cue/cmd/testdata/script/issue304.txt b/cmd/cue/cmd/testdata/script/issue304.txt
index 61c41a4..ef46457 100644
--- a/cmd/cue/cmd/testdata/script/issue304.txt
+++ b/cmd/cue/cmd/testdata/script/issue304.txt
@@ -3,8 +3,8 @@
-- expect-stdout --
-#_def
-#_def: {
+_#def
+_#def: {
x: int
body?: {
a: int
diff --git a/internal/core/adt/closed.go b/internal/core/adt/closed.go
index 39a00fa..045179c 100644
--- a/internal/core/adt/closed.go
+++ b/internal/core/adt/closed.go
@@ -70,6 +70,29 @@
// TODO(errors): return a dedicated ConflictError that can track original
// positions on demand.
+func (v *Vertex) IsInOneOf(t SpanType) bool {
+ for _, s := range v.Structs {
+ if s.CloseInfo.IsInOneOf(t) {
+ return true
+ }
+ }
+ return false
+}
+
+// IsRecursivelyClosed returns true if this value is either a definition or unified
+// with a definition.
+func (v *Vertex) IsRecursivelyClosed() bool {
+ if v.IsInOneOf(DefinitionSpan) {
+ return true
+ }
+ for p := v; p != nil; p = p.Parent {
+ if p.Label.IsDef() {
+ return true
+ }
+ }
+ return false
+}
+
type closeNodeType uint8
const (
diff --git a/internal/core/export/export.go b/internal/core/export/export.go
index d96ed3c..b24e7ec 100644
--- a/internal/core/export/export.go
+++ b/internal/core/export/export.go
@@ -97,18 +97,19 @@
e := newExporter(p, r, pkgID, v)
e.markUsedFeatures(v)
- if v.Label.IsDef() {
+ isDef := v.IsRecursivelyClosed()
+ if isDef {
e.inDefinition++
}
expr := e.expr(v)
- if v.Label.IsDef() {
+ if isDef {
e.inDefinition--
if s, ok := expr.(*ast.StructLit); ok {
expr = ast.NewStruct(
- ast.Embed(ast.NewIdent("#_def")),
- ast.NewIdent("#_def"), s,
+ ast.Embed(ast.NewIdent("_#def")),
+ ast.NewIdent("_#def"), s,
)
}
}
diff --git a/internal/core/export/export_test.go b/internal/core/export/export_test.go
index c61699f..3486ccf 100644
--- a/internal/core/export/export_test.go
+++ b/internal/core/export/export_test.go
@@ -156,6 +156,7 @@
return n, nil
},
out: `#Provider: {ID: string, notConcrete: bool, a: int, b: a+1}, providers: {foo: {ID: "12345", notConcrete: bool, a: int, b: a+1}}`,
+ p: export.All,
}, {
// Issue #882
in: func(r *adt.OpContext) (adt.Expr, error) {
@@ -173,6 +174,21 @@
},
out: `#One: {version: string}, ones: {[string]: #One}`,
p: export.All,
+ }, {
+ // Indicate closedness in an element that is closed and misses parent
+ // context.
+ // Issue #882
+ in: func(r *adt.OpContext) (adt.Expr, error) {
+ v := ctx.CompileString(`
+ #A: b: c: string
+ `)
+ v = v.LookupPath(cue.ParsePath("#A.b"))
+
+ _, n := value.ToInternal(v)
+ return n, nil
+ },
+ out: `_#def, _#def: {c: string}`,
+ p: export.All,
}}
for _, tc := range testCases {
t.Run("", func(t *testing.T) {