Skip to content

Commit

Permalink
internal/core/export: dedup let clauses for merged structs
Browse files Browse the repository at this point in the history
Let deduping already existed, but it could miss cases where
an identical let was added to the same scope, but originating
from different conjuncts, where the let originated from the
same struct.

Fixes #593

Change-Id: I47c806096ba885421005dfb297ae700c1c734040
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7723
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
  • Loading branch information
mpvl committed Nov 21, 2020
1 parent 56eb4b1 commit 1e0faf0
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 6 deletions.
26 changes: 22 additions & 4 deletions internal/core/export/adt.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,30 @@ func (e *exporter) adt(expr adt.Expr, conjuncts []adt.Conjunct) ast.Expr {
f.let = map[adt.Expr]*ast.LetClause{}
}
label := e.uniqueLetIdent(x.Label, x.X)
let = &ast.LetClause{
Ident: e.ident(label),
Expr: e.expr(x.X),

name := label.IdentString(e.ctx)

// A let may be added multiple times to the same scope as a result
// of how merging works. If that happens here it must be one
// originating from the same expression, and it is safe to drop.
for _, elt := range f.scope.Elts {
if a, ok := elt.(*ast.LetClause); ok {
if a.Ident.Name == name {
let = a
break
}
}
}

if let == nil {
let = &ast.LetClause{
Ident: e.ident(label),
Expr: e.expr(x.X),
}
f.scope.Elts = append(f.scope.Elts, let)
}

f.let[x.X] = let
f.scope.Elts = append(f.scope.Elts, let)
}
ident := ast.NewIdent(let.Ident.Name)
ident.Node = let
Expand Down
118 changes: 116 additions & 2 deletions internal/core/export/testdata/let.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,38 @@ x: "foo"
// Issue #590
let Y = x
y: Y
-- issue593.cue --
cfgs: [ for crd in ["one", "two"] {
metadata: {
name: crd
}
}]
for cfg in cfgs {
let filepath = "kind-\(cfg.name)"
files: {
"\(filepath)": {
patches: cfg
}
}
}

-- out/definition --

{
cfgs: [ for crd in ["one", "two"] {
metadata: {
name: crd
}
}]
for cfg in cfgs {
let filepath = "kind-\(cfg.name)"
files: {
"\(filepath)": {
patches: cfg
}
}
}
}
let X = 1 + 1
#Foo: X
x: "foo"
Expand All @@ -29,26 +59,110 @@ y: Y & Y_1
[#Foo]
[x]
[y]
[cfgs]
[cfgs 0]
[cfgs 0 metadata]
[cfgs 0 metadata name]
[cfgs 1]
[cfgs 1 metadata]
[cfgs 1 metadata name]
[files]
-- out/value --
== Simplified
{
x: "foo"
cfgs: [{
metadata: {
name: "one"
}
}, {
metadata: {
name: "two"
}
}]
let filepath = "kind-\(cfg.name)"
files: {
"\(filepath)": {
patches: cfg
}
} & {
"\(filepath)": {
patches: cfg
}
}
y: "foo"
}
== Raw
{
#Foo: 2
x: "foo"
y: "foo"
cfgs: [{
metadata: {
name: "one"
}
}, {
metadata: {
name: "two"
}
}]
let filepath = "kind-\(cfg.name)"
files: {
"\(filepath)": {
patches: cfg
}
} & {
"\(filepath)": {
patches: cfg
}
}
y: "foo"
}
== Final
{
x: "foo"
cfgs: [{
metadata: {
name: "one"
}
}, {
metadata: {
name: "two"
}
}]
let filepath = "kind-\(cfg.name)"
files: {
"\(filepath)": {
patches: cfg
}
} & {
"\(filepath)": {
patches: cfg
}
}
y: "foo"
}
== All
{
#Foo: 2
x: "foo"
y: "foo"
cfgs: [{
metadata: {
name: "one"
}
}, {
metadata: {
name: "two"
}
}]
let filepath = "kind-\(cfg.name)"
files: {
"\(filepath)": {
patches: cfg
}
} & {
"\(filepath)": {
patches: cfg
}
}
y: "foo"
}

0 comments on commit 1e0faf0

Please sign in to comment.