google / google/go-jsonnet

jsonnetfmt produces invalid output for object comprehensions with literal computed keys

Open
#879 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.