Skip to content

fix: generation errors for PHP 8.1+ targets with enums - #162

Merged
tommey merged 1 commit into
masterfrom
feature/fix-php81-target-generation
Sep 28, 2026
Merged

tommey merged 1 commit into
masterfrom
feature/fix-php81-target-generation

Conversation

@tommey

@tommey tommey commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

With CLIENT_PHP_VERSION 8.1 or later the generator emits native PHP enums. Regenerating 42 real-world clients at 8.3 surfaced four bugs in that path. Each one either aborts generation or makes generated code throw at runtime. Targets below 8.1 generate string constants and are not affected. Their output is byte-identical except for the new test fixture.

# Bug Effect before Fix
1 Enum value starting with a digit, e.g. +7 days case 7_DAYS: invalid PHP, generation aborts EnumGenerator::getCaseName() prefixes V_ whenever the name starts with a digit, not only when it is entirely numeric → case V_7_DAYS
2 Optional/nullable array-of-enum request parameter left unset array_map() on null → TypeError when the request is sent $this->x === null ? null : array_map(...), the same null handling scalar enums get via ?->value
3 Enum header parameter The enum object reaches the PSR-7 message → InvalidArgumentException getHeaders() goes through the same field mapping as query/path/cookie parameters, so it sends ->value
4 Inline array-of-enum items All collapse into one Schema\Enum class with only one field's values; with differing value sets, requests type-hint the wrong enum Items are named {Operation}{Field}Item + Enum, exactly like inline array-of-object items in the same branch of FieldFactory

No working output changes: #1–#3 only change code that was already invalid or always threw. #4 renames a generated class, so it ships as 11.3.0 (CHANGELOG entry included). Any client that regenerates with an existing Schema\Enum gets the new per-operation names.

Tests

  • New unit test EnumGeneratorTest::testGetCaseName (8 cases: words, separators, integers, a leading digit, decimals, negatives, empty).
  • New fixture spec Request/getResourcesByStatuses.yaml, with a mandatory and an optional inline array-of-enum query parameter (one value starts with a digit). It has expected request classes for 7.4, 8.1 and 8.3 plus the expected item enum.
  • 4 existing fixtures updated. They had encoded bug API test stubs as part of generated client? #3 ('Accept' => $this->accept → $this->accept->value).
  • make test: OK, 461 tests. php-cs-fixer: 0 files. PHPStan: no errors.
  • End to end: two affected production specs (a subscription API with +7 days periods and two criterion_status_in filters with different value sets, and a story API) now generate at 8.3, lint clean on PHP 8.5, and get correct per-operation item enums.

🤖 Generated with Claude Code

- Enum case names that start with a digit (e.g. '+7 days') are prefixed
  with V_ like numeric values, instead of producing an invalid 'case 7_DAYS'
  that aborted the generation.
- Optional or nullable array-of-enum request parameters are only mapped to
  their values when set; an unset parameter threw a TypeError from
  array_map() on null.
- Enum header parameters are sent as their values, like query, path and
  cookie parameters; the enum object itself made PSR-7 throw.
- Inline array-of-enum items are named {Operation}{Field}ItemEnum, like
  inline array-of-object items, instead of all collapsing into one
  Schema\Enum class with the values of only one of them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tommey
tommey merged commit 6da7e52 into master Sep 28, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant