Repository navigation
fix(generator): keep the literals of a nullable enum, type empty lists - #7
Merged
Merged
Conversation
The SDK regeneration from spec 2.49 made Block::getSlots() non-nullable, so PHPStan's level 9 run over the generated fixtures reports the `getSlots() ?? []` in two assertion files as a left side that is never null, which has failed the phpstan job on main since then. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UGTdQLpEoYyXhbJV1znWEW
A select field's `value` lists `null` among its enum members, which is
how OpenAPI 3.0 lets a nullable enum hold null. TypeMapper treated any
non-scalar member as unsafe and dropped the whole enum, so the value was
typed `string|null` instead of its literal union. A `null` member now
becomes a trailing `null` in the union.
An array schema with `maxItems: 0` can only ever be empty, so it maps to
`array{}`. That makes a select field's `options`, a map of value =>
label or `[]` when nothing is selected, `\stdClass|array{}`.
This changes the output of both generator commands for every schema with
a select field, including the deprecated flyo-generate-blocks; UPGRADE.md
says so.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UGTdQLpEoYyXhbJV1znWEW
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.
Problem
A select field's
valueis a nullable enum, and the schema listsnullamong its members. That is correct OpenAPI 3.0.3:nullable: truealone does not allownullunless the enum lists it.TypeMapper::literalUnion()drops an enum it thinks is unsafe, and its check is!is_scalar($value). Sinceis_scalar(null)isfalse, a singlenullmember threw away the whole enum, so the generated type fell back to plainstring:size: object{ value: string|null, // enum ["small", "medium", "large", null] options: \stdClass|array<int, mixed>, label: string|null }|null,Change
nullmember no longer disqualifies the enum. It becomes a trailingnull, the same position the rest of the generator puts it in.enum: [null]maps tonull, and arrays or objects inside an enum still fall back tostringas before.maxItems: 0can only ever be empty, so it maps toarray{}. That makesoptions(a map of value => label, or[]when nothing is selected)\stdClass|array{}.size: object{ value: 'small'|'medium'|'large'|null, options: \stdClass|array{}, label: string|null }|null,Tests
TypeMapperTest: nullable enum,nulllisted first, enum of onlynull, enum with an object member,maxItems: 0, a positivemaxItems, the map-or-empty-listoneOf, and no double|null.types/sitefixture:categorynow has the real select-field shape (nullin the enum,oneOfoptions). Itsmatchassertion only stays exhaustive because of the fix.blocks/fullfixture: newnullable_enumandempty_listfields with PHPStan assertions.TypesAccessPatternTest: at runtime, a selected option'soptionsis a\stdClass, and an unselected one decodes to[].TypeMapperchange reverted, 10 PHPUnit cases and 4 level-9 PHPStan assertions fail.Worth a look
flyo-generate-blocksoutput changes too.Profilepromises byte-identical output for it. I applied the fix to both commands anyway: holding it back would keep the bug there, would need a flag passed throughKind::plan(), and would break the "a block class is the same under both commands" invariant thatGoldenTestchecks.UPGRADE.mdgets a "From 3.6 to 3.7" note saying--checkreports drift until the first regeneration. Adjust the version heading if the next release is numbered differently.main. The regeneration from spec 2.49 (9d53bb5) madeBlock::getSlots()non-nullable. Since then thephpstanjob onmainfails ongetSlots() ?? []in two fixture assertions. The first commit removes the?? []so this PR (andmain, once merged) is green again.Verification
vendor/bin/phpunit: 298 tests OKphpstan.neon,phpstan-generator.neon,phpstan-generated.neon: no errors--checksmoke tests from the workflow pass🤖 Generated with Claude Code
https://claude.ai/code/session_01UGTdQLpEoYyXhbJV1znWEW
Generated by Claude Code