jsonnetfmt produces invalid output for object comprehensions with literal computed keys
- Dominant language
- Go
- Stars
- 1.8k
- Forks
- 263
- PR merge metrics
- No merged PRs in 30d
Description
`jsonnetfmt` formats a valid object comprehension into one that no longer parses. It strips the
`[...]` brackets off a string/identifier-literal computed key, but object comprehensions require
the `[expr]` key syntax, so the formatted output is rejected by the evaluator.
Repro (v0.22.0):
`comp.jsonnet`:
```jsonnet
{['0']: 1 for x in [1]}
```
```
$ jsonnet comp.jsonnet
{
"0": 1
}
$ jsonnetfmt comp.jsonnet
{ '0': 1 for x in [1] }
$ jsonnetfmt comp.jsonnet | jsonnet -
:1:10-13 Object comprehensions can only have [e] fields
```
So formatting a valid file yields a file that fails to evaluate.
The bug is specific to comprehension keys that are simple literals. Complex keys keep their
brackets and stay valid:
```
$ echo '{[std.toString(0)]: 1 for x in [1]}' | jsonnetfmt -
{ [std.toString(0)]: 1 for x in [1] } # correct, still parses
```
Root cause looks like the `['literal'] -> literal` field simplification (correct for normal
objects, since `{['a']: 1}` == `{a: 1}`) is being applied inside object comprehensions, where
that rewrite is not valid. The fix would be to skip the simplification when the field is part of
a comprehension.
Found via a formatter idempotence check and confirmed with the repro above on v0.22.0.
Contributor guide
Assessment
This issue has not been assessed yet.