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 comp.jsonnet
{
"0": 1
}
$ jsonnetfmt comp.jsonnet
{ '0': 1 for x in [1] }
$ jsonnetfmt comp.jsonnet | jsonnet -
<stdin>: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.
jsonnetfmtformats a valid object comprehension into one that no longer parses. It strips the[...]brackets off a string/identifier-literal computed key, but object comprehensions requirethe
[expr]key syntax, so the formatted output is rejected by the evaluator.Repro (v0.22.0):
comp.jsonnet:{['0']: 1 for x in [1]}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:
Root cause looks like the
['literal'] -> literalfield simplification (correct for normalobjects, since
{['a']: 1}=={a: 1}) is being applied inside object comprehensions, wherethat 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.