Skip to content
This repository has been archived by the owner on Nov 18, 2021. It is now read-only.

Commit

Permalink
cue: fix exporting of label aliases
Browse files Browse the repository at this point in the history
These could sometimes be dropped when  exported.
This also changes the default expression (if none is
specified) from '_' to 'string'.

Change-Id: I5713ffec945aab1c289f551bf814e0123b85647b
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3961
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
  • Loading branch information
mpvl committed Nov 9, 2019
1 parent 5c2d937 commit 40d2667
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 20 deletions.
3 changes: 3 additions & 0 deletions cue/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,9 @@ func (v *astVisitor) walk(astNode ast.Node) (ret value) {
n2 := v.mapScope(n.Scope)
ret = &nodeRef{baseValue: newExpr(n), node: n2}

// Allow different names to refer to the same field in unification. We
// do this by anonymizing the the reference. This then has to be
// resolved again when refering to lambdas.
l, lambda := n2.(*lambdaExpr)
if lambda && len(l.params.arcs) == 1 {
f = 0
Expand Down
36 changes: 26 additions & 10 deletions cue/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,12 @@ func (p *exporter) mkTemplate(v value, n *ast.Ident) ast.Label {
if v != nil {
expr = p.expr(v)
} else {
expr = ast.NewIdent("_")
expr = ast.NewIdent("string")
}
switch n.Name {
case "", "_":
default:
expr = &ast.Alias{Ident: n, Expr: ast.NewIdent("_")}
expr = &ast.Alias{Ident: n, Expr: ast.NewIdent("string")}
}
return ast.NewList(expr)
}
Expand Down Expand Up @@ -312,6 +312,16 @@ func (p *exporter) isClosed(x *structLit) bool {
return x.closeStatus.shouldClose()
}

func (p *exporter) badf(msg string, args ...interface{}) ast.Expr {
msg = fmt.Sprintf(msg, args...)
bad := &ast.BadExpr{}
bad.AddComment(&ast.CommentGroup{
Doc: true,
List: []*ast.Comment{{Text: "// " + msg}},
})
return bad
}

func (p *exporter) expr(v value) ast.Expr {
// TODO: use the raw expression for convert incomplete errors downstream
// as well.
Expand Down Expand Up @@ -365,17 +375,24 @@ func (p *exporter) expr(v value) ast.Expr {
if n != nil {
return ast.NewSel(n, p.ctx.labelStr(x.feature))
}
ident := p.identifier(x.feature)
f := x.feature
ident := p.identifier(f)
node, ok := x.x.(*nodeRef)
if !ok {
// TODO: should not happen: report error
return p.badf("selector without node")
}
if l, ok := node.node.(*lambdaExpr); ok && len(l.arcs) == 1 {
f = l.params.arcs[0].feature
// TODO: ensure it is shadowed.
ident = p.identifier(f)
return ident
}
// TODO: nodes may have changed. Use different algorithm.

// TODO: nodes may have been shadowed. Use different algorithm.
conflict := false
for i := len(p.stack) - 1; i >= 0; i-- {
e := &p.stack[i]
if e.from != x.feature {
if e.from != f {
continue
}
if e.key != node.node {
Expand All @@ -385,18 +402,17 @@ func (p *exporter) expr(v value) ast.Expr {
if conflict {
ident = e.to
if e.to == nil {
name := p.unique(p.ctx.labelStr(x.feature))
name := p.unique(p.ctx.labelStr(f))
e.syn.Elts = append(e.syn.Elts, &ast.Alias{
Ident: p.ident(name),
Expr: p.identifier(x.feature),
Expr: p.identifier(f),
})
ident = p.ident(name)
e.to = ident
}
}
return ident
break
}
// TODO: should not happen: report error
return ident

case *indexExpr:
Expand Down
39 changes: 29 additions & 10 deletions cue/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,8 @@ func TestExport(t *testing.T) {
emb
}
e :: {
[_]: <100
b: int
[string]: <100
b: int
f
}
}`),
Expand Down Expand Up @@ -429,7 +429,7 @@ func TestExport(t *testing.T) {
out: unindent(`
{
b: [{
[X=_]: int
[X=string]: int
if a > 4 {
f: 4
}
Expand Down Expand Up @@ -686,7 +686,7 @@ func TestExportFile(t *testing.T) {
out: unindent(`
{
A: {
[_]: B
[string]: B
} @protobuf(1,"test")
B: {
} & ({
Expand Down Expand Up @@ -715,7 +715,7 @@ func TestExportFile(t *testing.T) {
eval: true,
in: `
A :: { b: int }
a: A & { [_]: <10 }
a: A & { [string]: <10 }
B :: a
`,
out: unindent(`
Expand Down Expand Up @@ -780,15 +780,15 @@ func TestExportFile(t *testing.T) {
out: unindent(`
{
T :: {
[_]: int64
[string]: int64
}
X :: {
[_]: int64
x: int64
[string]: int64
x: int64
}
x: {
[_]: int64
x: int64
[string]: int64
x: int64
}
}`),
}, {
Expand Down Expand Up @@ -910,6 +910,25 @@ func TestExportFile(t *testing.T) {
})
}
}`),
}, {
eval: true,
in: `
x: [string]: int
a: [P=string]: {
b: x[P]
c: P
e: len(P)
}
`,
out: unindent(`
{
x: [string]: int
a: [P=string]: {
b: x[P]
c: string
e: len(P)
}
}`),
}}
for _, tc := range testCases {
t.Run("", func(t *testing.T) {
Expand Down

0 comments on commit 40d2667

Please sign in to comment.