cue: allow valid reference cycles in export

Fixes #58

Change-Id: Ic2e4d1f02c002a678d72f6ff45b207857f8971d2
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3440
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/ast.go b/cue/ast.go
index 8f72cb5..07c4d1a 100644
--- a/cue/ast.go
+++ b/cue/ast.go
@@ -151,7 +151,7 @@
 		for _, a := range r.arcs {
 			if a.feature == label {
 				return &selectorExpr{newExpr(n),
-					&nodeRef{baseValue: newExpr(n), node: r}, label}
+					&nodeRef{baseValue: newExpr(n), node: r, label: label}, label}
 			}
 		}
 		if v.inSelector > 0 {
@@ -486,12 +486,10 @@
 			ret = &nodeRef{baseValue: newExpr(n), node: n2}
 			ret = &selectorExpr{newExpr(n), ret, f}
 		} else {
+			// Package or direct ancestor node.
 			n2 := v.mapScope(n.Node)
-			ref := &nodeRef{baseValue: newExpr(n), node: n2}
+			ref := &nodeRef{baseValue: newExpr(n), node: n2, label: f}
 			ret = ref
-			if inst := v.ctx().getImportFromNode(n2); inst != nil {
-				ref.short = f
-			}
 		}
 
 	case *ast.BottomLit:
diff --git a/cue/binop.go b/cue/binop.go
index 7a54bdb..0bec239 100644
--- a/cue/binop.go
+++ b/cue/binop.go
@@ -1137,7 +1137,9 @@
 		max, ok := n.(*numLit)
 		if !ok || len(xa) < max.intValue(ctx) {
 			src := mkBin(ctx, src.Pos(), op, x.typ, y.typ)
-			typ = binOp(ctx, src, op, x.typ.(evaluated), y.typ.(evaluated))
+			xt := x.typ.evalPartial(ctx)
+			yt := y.typ.evalPartial(ctx)
+			typ = binOp(ctx, src, op, xt, yt)
 			if isBottom(typ) {
 				return ctx.mkErr(src, "conflicting list element types: %v", typ)
 			}
diff --git a/cue/copy.go b/cue/copy.go
index 879758a..335a29d 100644
--- a/cue/copy.go
+++ b/cue/copy.go
@@ -26,7 +26,7 @@
 		if node == x.node {
 			return x, false
 		}
-		return &nodeRef{x.baseValue, node, x.short}, false
+		return &nodeRef{x.baseValue, node, x.label}, false
 
 	case *structLit:
 		arcs := make(arcs, len(x.arcs))
diff --git a/cue/eval.go b/cue/eval.go
index 9874a9b..7a3dea9 100644
--- a/cue/eval.go
+++ b/cue/eval.go
@@ -248,15 +248,14 @@
 		defer func() { ctx.debugPrint("result:", result) }()
 	}
 	n := x.len.evalPartial(ctx)
-	t := x.typ.evalPartial(ctx)
-	if err := firstBottom(n, t); err != nil {
-		return err
+	if isBottom(n) {
+		return n
 	}
 	s := x.elem.evalPartial(ctx).(*structLit)
-	if s == x.elem && n == x.len && t == x.typ {
+	if s == x.elem && n == x.len {
 		return x
 	}
-	return &list{x.baseValue, s, t, n}
+	return &list{x.baseValue, s, x.typ, n}
 }
 
 func (x *listComprehension) evalPartial(ctx *context) evaluated {
diff --git a/cue/export.go b/cue/export.go
index 3d32ba8..72b25d5 100644
--- a/cue/export.go
+++ b/cue/export.go
@@ -226,18 +226,50 @@
 	return s
 }
 
+func (p *exporter) isComplete(v value, all bool) bool {
+	switch x := v.(type) {
+	case *numLit, *stringLit, *bytesLit, *nullLit, *boolLit:
+		return true
+	case *list:
+		return true
+	case *structLit:
+		return !all
+	case *bottom:
+		return !isIncomplete(x)
+	}
+	return false
+}
+
+func (p *exporter) recExpr(v value, e evaluated) ast.Expr {
+	m := p.ctx.manifest(e)
+	if !p.isComplete(m, false) && !p.mode.concrete {
+		// TODO: do something more principled than this hack.
+		// This likely requires disjunctions to keep track of original
+		// values (so using arcs instead of values).
+		p := &exporter{p.ctx, options{concrete: true, raw: true}, p.stack, p.top, p.imports, p.inDef}
+		if _, ok := v.(*disjunction); ok || isBottom(e) {
+			return p.expr(v)
+		}
+		return p.expr(e)
+	}
+	return p.expr(e)
+}
+
 func (p *exporter) expr(v value) ast.Expr {
 	// TODO: use the raw expression for convert incomplete errors downstream
 	// as well.
-	if doEval(p.mode) {
+	if doEval(p.mode) || p.mode.concrete {
 		e := v.evalPartial(p.ctx)
 		x := p.ctx.manifest(e)
-		if isIncomplete(x) {
+
+		if !p.isComplete(x, true) {
 			if isBottom(e) {
 				p = &exporter{p.ctx, options{raw: true}, p.stack, p.top, p.imports, p.inDef}
 				return p.expr(v)
 			}
-			v = e
+			if doEval(p.mode) {
+				v = e
+			}
 		} else {
 			v = x
 		}
@@ -258,15 +290,18 @@
 		return ast.NewSel(ast.NewIdent(short), x.Name)
 
 	case *nodeRef:
-		if x.short == 0 {
+		if x.label == 0 {
+			// NOTE: this nodeRef is used within a selector.
 			return nil
 		}
-		inst := p.ctx.getImportFromNode(x.node)
-		if inst == nil {
-			return nil // should not happen!
+		short := p.ctx.labelStr(x.label)
+
+		if inst := p.ctx.getImportFromNode(x.node); inst != nil {
+			return ast.NewIdent(p.shortName(inst, short, inst.ImportPath))
 		}
-		short := p.ctx.labelStr(x.short)
-		return ast.NewIdent(p.shortName(inst, short, inst.ImportPath))
+
+		// fix shadowed label.
+		return ast.NewIdent(short)
 
 	case *selectorExpr:
 		n := p.expr(x.x)
@@ -504,8 +539,13 @@
 	case *list:
 		list := &ast.ListLit{}
 		var expr ast.Expr = list
-		for _, e := range x.elem.arcs {
-			list.Elts = append(list.Elts, p.expr(e.v))
+		for i, a := range x.elem.arcs {
+			if !doEval(p.mode) {
+				list.Elts = append(list.Elts, p.expr(a.v))
+			} else {
+				e := x.elem.at(p.ctx, i)
+				list.Elts = append(list.Elts, p.recExpr(a.v, e))
+			}
 		}
 		max := maxNum(x.len)
 		num, ok := max.(*numLit)
@@ -576,6 +616,7 @@
 			return nil, err
 		}
 	}
+
 	for _, a := range x.arcs {
 		p.stack = append(p.stack, remap{
 			key:  x,
@@ -632,13 +673,7 @@
 		if !doEval(p.mode) {
 			f.Value = p.expr(a.v)
 		} else {
-			e := x.at(p.ctx, i)
-			if v := p.ctx.manifest(e); isIncomplete(v) && !p.mode.concrete && isBottom(e) {
-				p := &exporter{p.ctx, options{raw: true}, p.stack, p.top, p.imports, p.inDef}
-				f.Value = p.expr(a.v)
-			} else {
-				f.Value = p.expr(e)
-			}
+			f.Value = p.recExpr(a.v, x.at(p.ctx, i))
 		}
 		p.inDef = oldInDef
 		if a.attrs != nil && !p.mode.omitAttrs {
diff --git a/cue/export_test.go b/cue/export_test.go
index b1c179e..80241aa 100644
--- a/cue/export_test.go
+++ b/cue/export_test.go
@@ -198,8 +198,8 @@
 			}`,
 		out: unindent(`
 			{
-				a: 1 | 2
-				b: [1 | 2]
+				a: 1 | 2 | *_|_
+				b: [1 | 2 | *_|_]
 			}`),
 	}, {
 		raw:  true,
@@ -447,6 +447,102 @@
 		
 			}
 		}`),
+	}, {
+		raw:  true,
+		eval: true,
+		in: `{
+			Foo :: {
+			Bar :: Foo | string
+			}
+		}`,
+		out: unindent(`
+		{
+			Foo :: {
+				Bar :: Foo | string
+			}
+		}`),
+	}, {
+		raw:  true,
+		eval: true,
+		in: `{
+				FindInMap :: {
+					"Fn::FindInMap" :: [string | FindInMap]
+				}
+				a: [...string]
+			}`,
+		out: unindent(`
+			{
+				FindInMap :: {
+					"Fn::FindInMap" :: [string | FindInMap]
+				}
+				a: []
+			}`)}, {
+		raw:  true,
+		eval: true,
+		in: `{
+				And :: {
+					"Fn::And": [...(3 | And)]
+				}
+				Ands: And & {
+					"Fn::And" : [_]
+				}
+			}`,
+		out: unindent(`
+			{
+				And :: {
+					"Fn::And": []
+				}
+				Ands "Fn::And": [3 | And]
+			}`),
+	}, {
+		raw:  true,
+		eval: true,
+		in: `{
+			Foo :: {
+				sgl: Bar
+				ref: null | Foo
+				ext: Bar | null
+				ref: null | Foo
+				ref2: null | Foo.sgl
+				...
+			}
+			Foo :: {
+				Foo: 2
+				...
+			}
+			Bar :: string
+		}`,
+		out: unindent(`
+		{
+			FOO = Foo
+			FOO658221 = Foo
+			Foo :: {
+				Foo: 2
+				sgl: string
+				ref: null | {
+					Foo:  2
+					sgl:  Bar
+					ref:  (null | FOO) & (null | FOO)
+					ext:  Bar | null
+					ref2: null | FOO.sgl
+				}
+				ext:  Bar | null
+				ref2: null | FOO658221.sgl
+			}
+			Bar :: string
+		}`),
+	}, {
+		raw:  true,
+		eval: true,
+		in: `{
+			A: [uint]
+			B: A & ([10] | [192])
+		}`,
+		out: unindent(`
+		{
+			A: [>=0]
+			B: [10] | [192]
+		}`),
 	}}
 	for _, tc := range testCases {
 		t.Run("", func(t *testing.T) {
diff --git a/cue/rewrite_test.go b/cue/rewrite_test.go
index b9738c1..0e1fa08 100644
--- a/cue/rewrite_test.go
+++ b/cue/rewrite_test.go
@@ -80,7 +80,7 @@
 	case *list:
 		elm := rewriteRec(ctx, x.elem, x.elem, m).(*structLit)
 		len := rewriteRec(ctx, x.len, x.len.(evaluated), m)
-		typ := rewriteRec(ctx, x.typ, x.typ.(evaluated), m)
+		typ := rewriteRec(ctx, x.typ, x.typ.evalPartial(ctx), m)
 		return &list{x.baseValue, elm, typ, len}
 	default:
 		return eval
diff --git a/cue/value.go b/cue/value.go
index 8b3ebfe..d1a1b1d 100644
--- a/cue/value.go
+++ b/cue/value.go
@@ -565,7 +565,7 @@
 			return arc{}
 		}
 	}
-	return arc{cache: x.typ.(evaluated), v: x.typ}
+	return arc{cache: x.typ.evalPartial(ctx), v: x.typ}
 }
 
 func (x *list) isOpen() bool {
@@ -966,7 +966,7 @@
 type nodeRef struct {
 	baseValue
 	node  scope
-	short label // only for packages, otherwise 0
+	label label // for direct ancestor nodes
 }
 
 func (x *nodeRef) kind() kind {
diff --git a/doc/cmd/cue.md b/doc/cmd/cue.md
index 86d32a2..58677ba 100644
--- a/doc/cmd/cue.md
+++ b/doc/cmd/cue.md
@@ -260,7 +260,6 @@
 ```
       --dryrun        force overwriting existing files
       --files         force overwriting existing files
-      --fix string    apply given fix
   -f, --force         force overwriting existing files
   -h, --help          help for import
       --list          concatenate multiple objects into a list
diff --git a/doc/tutorial/basics/defaults.md b/doc/tutorial/basics/defaults.md
index 99d9e48..c348c25 100644
--- a/doc/tutorial/basics/defaults.md
+++ b/doc/tutorial/basics/defaults.md
@@ -29,5 +29,5 @@
 `$ cue eval defaults.cue`
 ```
 replicas: 1
-protocol: "tcp" | "udp"
+protocol: "tcp" | "udp" | *_|_
 ```
\ No newline at end of file
diff --git a/doc/tutorial/basics/lists.md b/doc/tutorial/basics/lists.md
index 5bde4be..1bde51e 100644
--- a/doc/tutorial/basics/lists.md
+++ b/doc/tutorial/basics/lists.md
@@ -39,7 +39,7 @@
 `$ cue eval -i lists.cue`
 ```
 IP: [uint8, uint8, uint8, uint8]
-PrivateIP: [10, uint8, uint8, uint8] | [192, 168, uint8, uint8] | [172, >=16 & <=32, uint8, uint8]
+PrivateIP: [10, uint8, uint8, uint8] | [192, 168, uint8, uint8] | [172, >=16 & <=32 & uint8, uint8, uint8]
 myIP: [10, 2, 3, 4]
 yourIP: _|_ // empty disjunction: [((10 & (int & >=0 & int & <=255)) & 11),((int & >=0 & int & <=255) & 1),((int & >=0 & int & <=255) & 2),((int & >=0 & int & <=255) & 3)]
 ```
\ No newline at end of file
diff --git a/doc/tutorial/kubernetes/testdata/manual.out b/doc/tutorial/kubernetes/testdata/manual.out
index e4a2183..58b85a0 100644
--- a/doc/tutorial/kubernetes/testdata/manual.out
+++ b/doc/tutorial/kubernetes/testdata/manual.out
@@ -33,14 +33,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -83,14 +83,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -250,14 +250,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -419,14 +419,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -586,14 +586,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -753,14 +753,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -922,14 +922,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -1089,14 +1089,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -1258,14 +1258,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -1308,14 +1308,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -1461,14 +1461,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -1787,14 +1787,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -2009,14 +2009,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -2206,14 +2206,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -2377,14 +2377,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -2564,14 +2564,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -2614,14 +2614,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -2866,14 +2866,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -3115,14 +3115,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -3348,14 +3348,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -3580,14 +3580,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -3816,14 +3816,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -4052,14 +4052,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -4246,14 +4246,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -4305,14 +4305,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -4562,14 +4562,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -4788,14 +4788,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -5024,14 +5024,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -5716,14 +5716,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -5766,14 +5766,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -6057,14 +6057,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -6243,14 +6243,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }
@@ -6858,14 +6858,14 @@
                 template: {
                     spec: _|_ // undefined field "volume"
                     metadata: {
-                        labels: label
+                        labels: X.label
                     }
                 }
             }
             metadata: {
-                name: name
+                name: X.name
                 labels: {
-                    component: label.component
+                    component: X.label.component
                 }
             }
         }