Skip to content

Commit 4b914fb

Browse files
Fix field visibility of object comprehension fields to inherit
This should make C++ Jsonnet match the existing behaviour of Go-Jsonnet. Object comprehensions do not support differing field visibility, that is an object comprehension with a "hidden" or "forced-visible" field such as `{[k]::1 for k in ["x"]}` is rejected with a syntax error. However, intuitively the `{[key_expr]: value_expr for x in ...}` syntax seems like it should behave similarly to a normal (non-comprehension) object that uses default field visibility. Default field visibility is to 'inherit' visibility when merging objects with the + operator, and this is the existing behaviour of Go-Jsonnet. Example case: ./jsonnet -e '{"one":: "base"} + {[k]: "derived" for k in ["one"]}' Before this commit, Go-Jsonnet output: { } Before this commit, C++ Jsonnet output: { "one": "derived" } Bug report: #1111
1 parent 55eafec commit 4b914fb

File tree

3 files changed

+11
-1
lines changed

3 files changed

+11
-1
lines changed

core/vm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ class Interpreter {
748748

749749
} else if (auto *obj = dynamic_cast<const HeapComprehensionObject *>(obj_)) {
750750
for (const auto &f : obj->compValues)
751-
r[f.first] = ObjectField::VISIBLE;
751+
r[f.first] = ObjectField::INHERIT;
752752
}
753753
return r;
754754
}

test_suite/object.jsonnet

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ local obj = {
8080

8181
std.assertEqual(obj, { ["f" + x + y + z]: { x: x, y: y, z: z } for x in [1, 2, 3] for y in [1, 4, 6] if x + 2 < y for z in [true, false] }) &&
8282

83+
// Tests for #1111 - object comprehension fields should use "inherit" visibility.
84+
std.assertEqual(std.objectFields({ x: 1 } + { [k]: 2 for k in ['x'] }), ['x']) &&
85+
std.assertEqual(std.objectFields({ x:: 1 } + { [k]: 2 for k in ['x'] }), []) &&
86+
std.assertEqual(std.objectFields({ x::: 1 } + { [k]: 2 for k in ['x'] }), ['x']) &&
87+
8388
std.assertEqual({ f: { foo: 7, bar: 1 } { [self.name]+: 3, name:: "foo" }, name:: "bar" },
8489
{ f: { foo: 7, bar: 4 } }) &&
8590

test_suite/object.jsonnet.fmt.golden

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ local obj = {
8080

8181
std.assertEqual(obj, { ['f' + x + y + z]: { x: x, y: y, z: z } for x in [1, 2, 3] for y in [1, 4, 6] if x + 2 < y for z in [true, false] }) &&
8282

83+
// Tests for #1111 - object comprehension fields should use "inherit" visibility.
84+
std.assertEqual(std.objectFields({ x: 1 } + { [k]: 2 for k in ['x'] }), ['x']) &&
85+
std.assertEqual(std.objectFields({ x:: 1 } + { [k]: 2 for k in ['x'] }), []) &&
86+
std.assertEqual(std.objectFields({ x::: 1 } + { [k]: 2 for k in ['x'] }), ['x']) &&
87+
8388
std.assertEqual({ f: { foo: 7, bar: 1 } { [self.name]+: 3, name:: 'foo' }, name:: 'bar' },
8489
{ f: { foo: 7, bar: 4 } }) &&
8590

0 commit comments

Comments
 (0)