Skip to content

Commit 6167d7d

Browse files
committed
tools/fix: merge calls to list.Concat
Previously, `cue fix` would correctly convert list addition to calls to `list.Concat`. However, chains of list-addition would not be merged, which causes `cue fix` to create somewhat unreadable code, such as: l: list.Concat([list.Concat([list.Concat([["a"], ["b"]]), ["c"]), ["d"]]) But it's not tricky to detect that an argument to + is itself a call to `list.Concat` and thus flatten such trees to a single call to list.Concat. Fixes #3523 Change-Id: I9bb57fe3d576725ad5d2ae850b809d6b858e9f51 Signed-off-by: Matthew Sackman <[email protected]> Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1202868 TryBot-Result: CUEcueckoo <[email protected]> Reviewed-by: Daniel Martí <[email protected]>
1 parent 12ac20b commit 6167d7d

File tree

2 files changed

+61
-4
lines changed

2 files changed

+61
-4
lines changed

tools/fix/fix.go

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,27 @@ func File(f *ast.File, o ...Option) *ast.File {
6969
x, y := n.X, n.Y
7070
_, xIsList := x.(*ast.ListLit)
7171
_, yIsList := y.(*ast.ListLit)
72-
if !(xIsList || yIsList) {
73-
break
74-
}
72+
_, xIsConcat := concatCallArgs(x)
73+
_, yIsConcat := concatCallArgs(y)
74+
7575
if n.Op == token.ADD {
76+
if !(xIsList || xIsConcat || yIsList || yIsConcat) {
77+
break
78+
}
7679
// Rewrite list addition to use list.Concat
80+
exprs := expandConcats(x, y)
7781
ast.SetRelPos(x, token.NoSpace)
7882
c.Replace(ast.NewCall(
7983
ast.NewSel(&ast.Ident{
8084
Name: "list",
8185
Node: ast.NewImport(nil, "list"),
82-
}, "Concat"), ast.NewList(x, y)),
86+
}, "Concat"), ast.NewList(exprs...)),
8387
)
88+
8489
} else {
90+
if !(xIsList || yIsList) {
91+
break
92+
}
8593
// Rewrite list multiplication to use list.Repeat
8694
if !xIsList {
8795
x, y = y, x
@@ -115,3 +123,42 @@ func File(f *ast.File, o ...Option) *ast.File {
115123
}
116124
return f
117125
}
126+
127+
func expandConcats(exprs ...ast.Expr) (result []ast.Expr) {
128+
for _, expr := range exprs {
129+
list, ok := concatCallArgs(expr)
130+
if ok {
131+
result = append(result, expandConcats(list.Elts...)...)
132+
} else {
133+
result = append(result, expr)
134+
}
135+
}
136+
return result
137+
}
138+
139+
func concatCallArgs(expr ast.Expr) (*ast.ListLit, bool) {
140+
call, ok := expr.(*ast.CallExpr)
141+
if !ok {
142+
return nil, false
143+
}
144+
sel, ok := call.Fun.(*ast.SelectorExpr)
145+
if !ok {
146+
return nil, false
147+
}
148+
name, ok := sel.X.(*ast.Ident)
149+
if !ok || name.Name != "list" {
150+
return nil, false
151+
}
152+
name, ok = sel.Sel.(*ast.Ident)
153+
if !ok || name.Name != "Concat" {
154+
return nil, false
155+
}
156+
if len(call.Args) != 1 {
157+
return nil, false
158+
}
159+
list, ok := call.Args[0].(*ast.ListLit)
160+
if !ok {
161+
return nil, false
162+
}
163+
return list, true
164+
}

tools/fix/fix_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ b: a + a
7373
c: a + [8]
7474
d: [9] + a
7575
e: [0] + [1]
76+
f: [0] + [1] + [2]
77+
g: list.Concat([[0], [1, 2]]) + list.Concat([[3, 4], [5]])
78+
h: list.Concat([[0], [1, 2]]) + [3] + [4] + list.Concat([[5, 6], [7]])
79+
i: list.Concat(list.Concat([[0], [1, 2]]), list.Concat([[3, 4], [5]]))
7680
`,
7781
out: `import "list"
7882
@@ -81,6 +85,10 @@ b: a + a
8185
c: list.Concat([a, [8]])
8286
d: list.Concat([[9], a])
8387
e: list.Concat([[0], [1]])
88+
f: list.Concat([[0], [1], [2]])
89+
g: list.Concat([[0], [1, 2], [3, 4], [5]])
90+
h: list.Concat([[0], [1, 2], [3], [4], [5, 6], [7]])
91+
i: list.Concat(list.Concat([[0], [1, 2]]), list.Concat([[3, 4], [5]]))
8492
`,
8593
},
8694

@@ -92,6 +100,7 @@ c: 4
92100
d: [7] * c
93101
e: c * [8]
94102
f: [9] * 5
103+
g: ([9] * 5) + (6 * [10])
95104
`,
96105
out: `import "list"
97106
@@ -101,6 +110,7 @@ c: 4
101110
d: list.Repeat([7], c)
102111
e: list.Repeat([8], c)
103112
f: list.Repeat([9], 5)
113+
g: (list.Repeat([9], 5)) + (list.Repeat([10], 6))
104114
`,
105115
},
106116
}

0 commit comments

Comments
 (0)