cue: allow alias reuse in subscopes
Fixes #232
Change-Id: I5a6853926efbb76a86b438e8f5be62bbdd8cd3f1
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/4420
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/ast.go b/cue/ast.go
index bfbaae6..95cbf7e 100644
--- a/cue/ast.go
+++ b/cue/ast.go
@@ -83,7 +83,8 @@
allowAuto bool // allow builtin packages without import
// make unique per level to avoid reuse of structs being an issue.
- astMap map[ast.Node]scope
+ astMap map[ast.Node]scope
+ aliasMap map[ast.Node]value
errors errors.Error
}
@@ -120,6 +121,7 @@
resolveRoot: resolveRoot,
allowAuto: allowAuto,
astMap: map[ast.Node]scope{},
+ aliasMap: map[ast.Node]value{},
}
return v
}
@@ -528,9 +530,15 @@
// Pkg nil ImportSpec
if x, ok := n.Node.(*ast.Alias); ok {
+ // TODO(lang): should we exempt definitions? The substitution
+ // principle says we should not.
+ if ret = v.aliasMap[x.Expr]; ret != nil {
+ break
+ }
old := v.ctx().inDefinition
v.ctx().inDefinition = 0
ret = v.walk(x.Expr)
+ v.aliasMap[x.Expr] = ret
v.ctx().inDefinition = old
break
}
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index def9e29..26bde55 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -2854,6 +2854,31 @@
foo: json.Marshal(input)
`,
out: `<0>{input: string, foo: <1>.Marshal (<2>.input)}`,
+ }, {
+ desc: "alias reuse in nested scope",
+ in: `
+ Foo :: {
+ X = or([ k for k, _ in {} ])
+ connection: [X]: X
+ }
+ A :: {
+ foo: "key"
+ X = foo
+ a: foo: [X]: X
+ }
+ B :: {
+ foo: string
+ X = foo
+ a: foo: [X]: X
+ }
+ b: B & { foo: "key" }
+ `,
+ out: `<0>{` +
+ `Foo :: <1>C{connection: <2>C{[or ([ <3>for k, _ in <4>{} yield <3>.k ])]: <5>(_: string)->or ([ <3>for k, _ in <4>{} yield <3>.k ]), }}, ` +
+ `A :: <6>C{foo: "key", a: <7>C{foo: <8>C{["key"]: <9>(_: string)-><10>.foo, }}}, ` +
+ `B :: <11>C{foo: string, a: <12>C{foo: <13>C{[string]: <14>(_: string)-><15>.foo, }}}, ` +
+ `b: <16>C{foo: "key", a: <17>C{foo: <18>C{["key"]: <19>(_: string)-><20>.foo, }}}` +
+ `}`,
}}
rewriteHelper(t, testCases, evalFull)
}