GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |
GeezerVison is showing github.com — fix: lower a v1 allOf of a non-object $ref to the member's type by mromaszewicz · Pull Request #2591 · oapi-codegen/oapi-codegen Conversation
|
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Under schema-merging-behavior v1, an allOf member that is a $ref is
embedded in a struct, whatever its type. encoding/json flattens only an
embedded struct, and encodes an embedded field of any other type under a
key named after the type. So when the member is untyped, a primitive,
an array or a map, the value went out as {"Name": "x"} instead of "x",
and decoding the value the spec describes failed, or for a map left it
empty (oapi-codegen#2590).
- An allOf of one such $ref, next to members that add no fields (the
"decorate a $ref" idiom, with a description or nullable: true), is
now the member's type, as under v2: `type Wrap = Name`, `One *Name`.
- An untyped member places no constraint and carries no value of its
own, so it never decides the composition's type: a primitive, array
or map member next to it is the composition's type, and a
composition of only untyped members is the first one's type.
Whenever another member adds fields or brings a type of its own, an
untyped member keeps its embedded field, so code that sets it still
compiles, but is tagged json:"-": it used to add an "Untyped" key to
every object.
A member is classified by the type the generator declares for the
schema it refers to. It is generated in a context of its own, whose
merge frames are copies, so that generating it can't tell a composition
in progress that something referred back to it, and each classification
is remembered in the context: a member that is itself an allOf of a
$ref would otherwise be generated twice per link, and a chain of such
compositions took time exponential in its length. A member whose type
may carry JSON methods the struct inherits (time.Time,
openapi_types.UUID, an x-go-type naming a type or an interface with
methods) is embedded as before, and so is a member whose type would
make a cycle of aliases (`type Root = Arr` with `type Arr = []Root`),
which Go rejects.
servers/strict/responsebody_v1 and the v1 case of
TestStrictServerComposedResponseReceiverCompatibility recorded the old
shape. Those allOf responses are now the untyped member's type, which a
strict response carries in a Body field (oapi-codegen#2514), as under v2 and v3,
and they send the value itself.
The aggregate matrix harness's echo now fills a Body-wrapped strict
envelope, so a shape with an interface-typed body runs at every
position. The matrix's allof_array, allof_default and
allof_unique_items shapes no longer mark v1 broken, since it now
round-trips them. New shapes cover a map member, an untyped member,
two untyped members, an untyped member next to a map, and an untyped
member next to properties. An allOf whose member is an inline array
(allof_recursive_array) is a different v1 bug, and stays marked.
Fixes oapi-codegen#2590
Co-Authored-By: Claude Fable 5.1 <[email protected]>
cdda436 to
3ae2d74
Compare
There was an error while loading. Please reload this page.
… grew (#2592) * refactor: read Go type expressions in one place Four functions parsed a Go type expression with go/parser, each in its own file and its own way: goTypeNeedsBodyWrapper and v1GoTypeKind look at the outermost node, and mentionsTypeName and qualifyExternalTypeNames walk the identifiers in type position, one with ast.Inspect and one with a hand-written switch over node kinds. gotype.go now holds parseGoType, unparen, typeIdents and isPredeclaredType, and the four use them. Generated output is the same for every committed spec. Two inputs no spec has are read differently: v1GoTypeKind sees through parentheses around a type, as goTypeNeedsBodyWrapper already did; and typeIdents reaches the types in an interface's type set (~int | Foo), which the hand-written walk did not, and leaves an array's length alone, which ast.Inspect did not. Co-Authored-By: Claude Fable 5.1 <[email protected]> * refactor: find the schema a type was lowered from in one place The strict-server response classification (operations.go) and v1's allOf member classification (merge_schemas_v1.go) each walked, in their own words, from a schema to the one its Go type came from: the $ref member a composition was lowered to, and the type x-go-type-name declares beside the schema. lowered.go now holds that walk, as loweredToMember and Schema.namedTypeDef, and the two classifications keep only what differs between them: how they generate a schema (a fresh context, and an isolated one with a memo), and what they ask of the type they reach. v1 used to match a composition's $ref member by the member's name, and now matches it by the type the member generates as, as the response classification does. The two differ only for a member whose $ref carries an x-go-type, which v1 keeps embedded either way. subschemaLists spells out a schema's allOf, anyOf and oneOf for the four places that walked all three. Co-Authored-By: Claude Fable 5.1 <[email protected]> * refactor: remove GenStructFromAllOf, which nothing calls The exported wrapper had no caller in the repository, and #2591 gave it a copy of mergeSchemasV1's classification of the members. Only genStructFromAllOf remains, which mergeSchemasV1 hands the context and the classification it already has. Co-Authored-By: Claude Fable 5.1 <[email protected]> * docs: say once why v2 unions nullability, and what v1 does with a sole member The rationale for unioning "null" across allOf members was written out twice in mergeOpenapiSchemas, at the type comparison and at the nullability merge; the type comparison now refers to the latter. The comment on the defensive clone of the merged extensions narrated hypothetical future changes; it now says what the clone is for. The comment on generateAllOfV2's pure-wrapper case said v1 never returns the referenced type unchanged; since #2591 it does so for a member that isn't an object. Co-Authored-By: Claude Fable 5.1 <[email protected]> --------- Co-authored-by: Claude Fable 5.1 <[email protected]>
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
schema-merging-behavior v1: an allOf of a non-object $ref serializes under the member's type name
There was an error while loading. Please reload this page.