fix(compilers/openapi): keep an anchor-valued path-item key - #458
Open
fuad-daoud wants to merge 2 commits into
Open
fix(compilers/openapi): keep an anchor-valued path-item key#458fuad-daoud wants to merge 2 commits into
fuad-daoud wants to merge 2 commits into
Conversation
A Path Item Object's undeclared keys are read off the operations map the library folds them into, which is what lets them be kept verbatim. The library skips a key whose value carries a YAML anchor before that fold (speakeasy-api/openapi v1.24.1, marshaller/unmarshaller.go), so such a key entered no map and no field: it reached the IR in no form at all — no Unmodeled entry, no diagnostic — while a plainly-valued key beside it was kept and reported. Two documents differing only in that key compiled to the same IR. The raw mapping is the only place the key is written, so the census now reads it too: annotation.RawMappingKeys lists a raw mapping's keys the way RawChildNode looks one up, and undeclaredPathItemKeys diffs them against what the folded map, the model's fields, the standard methods and the x- prefix account for. Each key found only there is handed to the same keeper as the plain case, so both land under openapi:pathItem/<key> with one unknown-object-key warning apiece. The model's field list is hand-written and held to core.PathItem's own key tags by a test, which answers the concern that set the raw reading aside in #377: the vocabulary tracks the library rather than the specification by hand, and #293 has since settled the method half. Closes #412 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TJZJ8HaugGZTjzVueafLAT
RawMappingKeys's GoDoc said the pairs a `<<` merge key brings in are what the model holds. That is false for a merged-in value that is itself anchored: the library's anchor skip drops it from the model too, so neither the folded map nor the raw mapping presents it and only a merge-expanded view could — which is #395's to close. The comment now says so where the next reader lands, instead of asserting the opposite. Its "nil for a node that is not a mapping" also covered an empty mapping without saying so; the sentence and the test now name that case. Beside it: the route fixture's comment records that a plain scalar under an undeclared path-item key draws the library's type-mismatch error, and now also that an anchored scalar bypasses the fold and is kept with the warning alone — the lossless outcome, not a divergence to close by rejecting the anchored form. And the field-list pin binds its cmp.Diff before asserting on it, so a failure prints the diff rather than an opaque value. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TJZJ8HaugGZTjzVueafLAT
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.
Summary
A Path Item Object's undeclared keys are read off the operations map the library folds them into, which is what lets them be kept verbatim. The library skips a key whose value carries a YAML anchor before that fold (speakeasy-api/openapi v1.24.1,
marshaller/unmarshaller.go), so such a key entered no map and no field: it reached the IR in no form at all — noUnmodeledentry, no diagnostic — while a plainly-valued key beside it was kept and reported. Two documents differing only in that key compiled to the same IR (#412).The raw mapping is the only place the key is written, so the census now reads it too.
annotation.RawMappingKeyslists a raw mapping's keys the wayRawChildNodelooks one up — the same non-expanding reader the keeper uses, so every name it returns is one the keeper can find a value for — andundeclaredPathItemKeysdiffs them against what the folded map, the model's fields, the standard methods and thex-prefix account for. Each key found only there goes to the same keeper as the plain case, so both land underopenapi:pathItem/<key>with oneunknown-object-keywarning apiece: no new key form, reason, code or converter.nodeview.Viewwas not used, deliberately:archtestforbidsoperationandannotationfrom importing it, and a merge-expanded key set would name keys the non-expanding keeper then cannot reach. What this reader therefore does not see — and says so in its GoDoc — is a key merged in through<<whose value is anchored; that is #395's to close.The model's field list is hand-written and held to
core.PathItem's own key tags by a test, which answers the concern that set raw reading aside in #377: the vocabulary tracks the library, not the specification by hand.Found by the mechanism sweep, not fixed here: the same library skip drops an anchored declared entry — a whole path item under
paths, a response underresponses, a callback expression, orget: &g {...}on a path item — with no diagnostic. That is a different loss (an entry to lower, not a key to preserve) and gets its own issue.Test plan
path-item-anchored-key, declared anchored-key-first (the order that was wrong): pins both keys kept underUnmodeledwith their values and oneunknown-object-keywarning per key at the key's pointer. The harness's order-invariance oracle does permute this fixture (an anchor without an alias survives reversal), and reportsok.TestPathItemFields_MatchTheLibraryModelholds the hand-written field list tocore.PathItem;TestPathItemDeclares_AnchoredDeclaredKeysAreNotUndeclaredis the false-positive control (every declared class anchored, onlybogusreported); the every-route test gains an anchored twin on all three path-item parents.make gatepasses: lint 0 issues, coverage at 100%, fuzz, bench-smoke.Closes #412
🤖 Generated with Claude Code
https://claude.ai/code/session_01TJZJ8HaugGZTjzVueafLAT