From 3d56bc9983b14676d06f9e6471c7fcc3cb300196 Mon Sep 17 00:00:00 2001 From: bejaratommy Date: Sun, 7 Jun 2026 10:09:07 +0000 Subject: [PATCH] formatter: preserve [expr] key syntax in object comprehensions The PrettyFieldNames formatter pass was incorrectly simplifying computed string keys inside object comprehensions, e.g. turning ['0'] into '0'. While this rewrite is valid in regular objects (where {['a']: 1} == {a: 1}), object comprehensions require the [expr] key syntax; the simplified form is rejected by the parser. The fix tracks whether we are currently visiting an ObjectComp and, if so, skips the key-kind rewrite while still recursing into the field's value expression. Fixes #879 Signed-off-by: bejaratommy --- .../testdata/object_comp_literal_key.fmt.golden | 1 + .../testdata/object_comp_literal_key.jsonnet | 1 + internal/formatter/pretty_field_names.go | 15 +++++++++++++++ 3 files changed, 17 insertions(+) create mode 100644 formatter/testdata/object_comp_literal_key.fmt.golden create mode 100644 formatter/testdata/object_comp_literal_key.jsonnet diff --git a/formatter/testdata/object_comp_literal_key.fmt.golden b/formatter/testdata/object_comp_literal_key.fmt.golden new file mode 100644 index 000000000..62896cd8b --- /dev/null +++ b/formatter/testdata/object_comp_literal_key.fmt.golden @@ -0,0 +1 @@ +{ ['0']: 1 for x in [1] } diff --git a/formatter/testdata/object_comp_literal_key.jsonnet b/formatter/testdata/object_comp_literal_key.jsonnet new file mode 100644 index 000000000..62896cd8b --- /dev/null +++ b/formatter/testdata/object_comp_literal_key.jsonnet @@ -0,0 +1 @@ +{ ['0']: 1 for x in [1] } diff --git a/internal/formatter/pretty_field_names.go b/internal/formatter/pretty_field_names.go index 046f7ccd9..1d57a631b 100644 --- a/internal/formatter/pretty_field_names.go +++ b/internal/formatter/pretty_field_names.go @@ -25,6 +25,7 @@ import ( // PrettyFieldNames forces minimal syntax with field lookups and definitions type PrettyFieldNames struct { pass.Base + insideObjectComp bool } // Index prettifies the definitions. @@ -44,8 +45,22 @@ func (c *PrettyFieldNames) Index(p pass.ASTPass, index *ast.Index, ctx pass.Cont c.Base.Index(p, index, ctx) } +// ObjectComp traverses an object comprehension, skipping field key simplification +// since object comprehensions require the [expr] key syntax. +func (c *PrettyFieldNames) ObjectComp(p pass.ASTPass, node *ast.ObjectComp, ctx pass.Context) { + prev := c.insideObjectComp + c.insideObjectComp = true + c.Base.ObjectComp(p, node, ctx) + c.insideObjectComp = prev +} + // ObjectField prettifies the definitions. func (c *PrettyFieldNames) ObjectField(p pass.ASTPass, field *ast.ObjectField, ctx pass.Context) { + if c.insideObjectComp { + // Object comprehensions require [expr] key syntax; do not simplify the key. + c.Base.ObjectField(p, field, ctx) + return + } if field.Kind == ast.ObjectFieldExpr { // First try ["foo"] -> "foo". lit, ok := field.Expr1.(*ast.LiteralString)