feat(yaml/unstable): add useMaps option to parse mappings into Maps - #7290
Open
tomas-zijdemans wants to merge 5 commits into
Open
feat(yaml/unstable): add useMaps option to parse mappings into Maps#7290tomas-zijdemans wants to merge 5 commits into
tomas-zijdemans wants to merge 5 commits into
Conversation
Adds an opt-in useMaps boolean to the unstable parse() options: mappings
construct Map<unknown, unknown> at every depth, keys keep their parsed
types (3: is the number 3, "3": the string "3"), complex keys stay
structural, and duplicate keys compare SameValueZero. !!set constructs a
Set, !!omap a Map, and !!pairs an array of [key, value] pairs under the
flag. The unstable stringify() gains intrinsic Map/Set output (insertion
order, explicit ?-key form for collection keys, !!set tag for Sets) so
values round-trip; the stable modules are unchanged.
Internally the loader forks on a private container protocol
(create/has/set/entries) with plain-object and Map adapters, so the
legacy path keeps its direct-assignment fast path and __proto__
handling, and Maps are allocated where {} was allocated today so anchors
and cycles need no new mechanism.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7290 +/- ##
==========================================
+ Coverage 95.03% 95.08% +0.04%
==========================================
Files 617 617
Lines 51637 51788 +151
Branches 9359 9414 +55
==========================================
+ Hits 49075 49242 +167
+ Misses 2021 2008 -13
+ Partials 541 538 -3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…ction, and flow-style Map anchors
…versal, tighten comments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds an opt-in
useMapsboolean to the unstableparse()/parseAll(): mappings come back asMaps at every depth, and keys keep their parsed types instead of being coerced to strings.3:is the number3,"3":is the string"3". Closes #7283.The unstable
stringify()learns to writeMapandSetintrinsically, with no new option: aMaphas exactly one sensible representation (a mapping in insertion order), sostringify(parse(src, { useMaps: true }))round-trips. Stableparse()andstringify()are byte-for-byte unchanged, pinned by the existing tests plus a new one assertingstringify(new Map(...))still yields{}\n.What changed
useMaps?: boolean(defaultfalse) on the unstableParseOptions, with the full contract in TSDoc. Keys resolve through the schema exactly like values, complex keys (sequences, mappings) are legal, and the"[object Object]"substitution plus the "nested arrays are not supported inside keys" error do not apply in this mode.!!setconstructs aSet,!!omapaMap,!!pairsan array of[key, value]pairs under the flag. These ride along because their constructs areObject.keys-based and would break onMapinput.3: A3), collection keys in explicit? keyform on their own lines.Sets get the!!settag. Both participate in duplicate detection and&ref_Nanchors, including objects used as keys.Decisions worth reviewing
unknown. A conditional type keyed on the option lies as soon asextraTypesor the extended schema is in play.Mapkeys, so3and"3"coexist. Structurally equal complex keys are distinct unless they are the same aliased node. Deep-equality hashing is a hole with no bottom, so I stayed out of it.Mapis allocated exactly where{}is allocated today, before any pair lands, so anchors, aliases, and cycles need no new mechanism. Converting after the fact inconstruct()cannot work: by then keys are strings and aliases point at the old object.create/has/set/entries) with a plain-object adapter and aMapadapter. The legacy adapter keeps the direct-assignment fast path from perf(yaml): use direct assignment for mapping keys #7126 and the__proto__armor. If a public tag seam ever becomes worth it, this makes it an unhiding rather than a rewrite.sortKeysdoes not apply toMapentries (insertion order is the contract, and the callback is string-typed). Documented in one sentence.One known wart:
!!setwith a null body (--- !!set, no entries) still constructs{}under the flag, because tag constructs never see parser options. An empty flow mapping (!!set {}) constructs an emptySetcorrectly.Testing
Fifteen new tests across
parse_test.tsandstringify_test.ts, covering the issue's exact YAML,2:vs"2":, complex and aliased keys, duplicate detection with and withoutallowDuplicateKeys, merge keys, cycles,__proto__as an inert key, set/omap/pairs, explicit-key stringify, anchors,condenseFlow, and full round-trips. All 111 yaml tests pass, along withdeno task lint,deno fmt --check, and the doc tests.