builtinManifestJSONEx, builtinManifestYamlDoc and builtinManifestTomlEx
use native Go recursion that bypasses MaxStack. A self-referential
object like {a: $} causes unbounded memory allocation until OOM.
Add i.newCall() at the top of each recursive closure, matching the
pattern used by manifestJSON in interpreter.go.
This doesn't make them fully correct, in particular directives sections
(e.g., "%YAML 1.2" directive before a document start marker) are not
handled correctly, but they weren't handled correctly before, either.
It also doesn't recognise or try to do anything about document end
markers (`...`).
This fix does allow scalar documents to be on the same line as the
document start tag which is valid per examples in the YAML spec,
see for example https://yaml.org/spec/1.2.1/#id2760844
(YAML 1.2.1 spec, section 2.3 Scalars)
It also matches the C++ jsonnet output for std.parseYaml("42\n---"),
which is a stream of two documents, a scalar and then an empty document
(where the empty document is interpreted as JSON null)
All the go-jsonnet golden output overrides should be kept here in
the go-jsonnet repo. The older override mechanism (in which the
cpp-jsonnet repo has golden files for Golang ending in .golang)
will be removed.
For https://github.com/google/go-jsonnet/issues/518 to allow users to
keep current behaviour for --string --multi, which on go-jsonnet emitted
output without adding an extra newline.
--no-trailing-newline works with all modes except --yaml-stream.
To avoid confusion, the CLI explicitly rejects the combination of both
flags used together.
This follows the same pattern as I used for the C++ implementation.
Flattening the object is probably also possible, but I think it would
involve binding references to 'super' iff they are satisfied by fields
in existing ancestors and leaving them unbound if they're unsatisfied
so that they can be late-bound by extending the output object.
That seems at least as complicated as defining a new form of
uncachedObject to represent a key-removal operation.
For https://github.com/google/go-jsonnet/issues/830
Problems:
- When iterating over an empty string in a list comprehension, the
result is an empty string. This is a bug, it should be an error.
- When iterating over a non-empty string in a list comprehension, the
expected and unexpected types in the error message are swapped.
- Error messages mention "std.flatMap" when object/list comprehensions
would iterate over a value that is neither array nor string.
```
$ jsonnet --version
Jsonnet commandline interpreter (Go implementation) v0.21.0-rc2
$ jsonnet -e '[a for a in ""]'
""
$ jsonnet -e '[a for a in "b"]'
RUNTIME ERROR: Unexpected type array, expected string
<cmdline>:1:1-17
During evaluation
$ jsonnet -e '{[a]: 1 for a in 2}'
RUNTIME ERROR: std.flatMap second param must be array / string, got number
<cmdline>:1:1-20
<cmdline>:1:1-20
During evaluation
$ jsonnet -e '[a for a in 1]'
RUNTIME ERROR: std.flatMap second param must be array / string, got number
<cmdline>:1:1-15
During evaluation
```
FWIW, the C++ implementation does not have any of these problems. It
gives:
```
RUNTIME ERROR: In comprehension, can only iterate over array.
```
In the Go implementation comprehensions are desugared to a call to
std.flatMap which does accept a string in the "arr" parameter.
The fix: Desugar comprehensions to a call to a new hidden builtin which
only accepts arrays.
This includes the stdlib additions in
https://github.com/google/jsonnet/pull/1187
Also updates golden files for go-jsonnet tests; the changes
to the goldens are mostly changes to error locations from
the standard library.