Repository navigation
[Capability] Map PHPDoc pseudo-types to the JSON Schema type of their base type - #643
sarankumar1325 wants to merge 3 commits into
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved schema-generation defects produce invalid nested-array schemas, mishandle quoted literals and associative key types, and drop shape fields, potentially causing clients to reject schemas or valid inputs.
4 open issues
What changed in this PR
This PR addresses #641 by extending PHPDoc-to-JSON Schema mapping so supported pseudo-types and literals use their base types rather than defaulting to object.
Changes:
- Adds shared mappings for string and integer pseudo-types, literals, and non-empty collections.
- Expands array-shape handling for generic collections, string-keyed maps, and
mixedvalues. - Adds regression coverage and documents the behavior in the changelog.
| File | Description |
|---|---|
| tests/Unit/Capability/Discovery/SchemaGeneratorTest.php | Adds assertions for pseudo-types and collection types within shapes. |
| tests/Unit/Capability/Discovery/SchemaGeneratorFixture.php | Adds a PHPDoc fixture covering the new mappings. |
| src/Capability/Discovery/SchemaGenerator.php | Implements pseudo-type mappings and expands generic and shape parsing. |
| CHANGELOG.md | Documents the schema-generation fixes under 0.10.0. |
Review effort: Balanced
| if (preg_match('/^(\'[^\']*\'|"[^"]*")$/', $type)) { | ||
| return ['string']; |
| if (!isset($itemSchema['type'])) { | ||
| return 'any'; | ||
| } |
| if ('{' === $char || '<' === $char) { | ||
| ++$depth; | ||
| $buffer .= $char; | ||
| } elseif ('}' === $char) { | ||
| } elseif ('}' === $char || '>' === $char) { |
| if (preg_match('/^(?:non-empty-)?array\s*<\s*(?:string|non-empty-string|class-string)\s*,\s*(.+?)\s*>$/is', $type, $matches)) { | ||
| return ['type' => 'object', 'additionalProperties' => $this->mapTypeToSchema($matches[1]) ?: true]; | ||
| } |

Fixes #641
PHPStan/Psalm pseudo-types and literal types in a tool's DocBlock fell through to the
default => 'object'branch of the type mapping, so a tool taking e.g.@param non-empty-string $nameadvertised{"type": "object"}and rejected a valid string argument with-32602.This change maps them to their base type, both for parameters and for keys of an array shape:
non-empty-string,numeric-string,class-string,lowercase-string, …objectstringpositive-int,non-negative-int,negative-int, …objectintegerarray-keyobject["integer", "string"]'asc'|'desc'/1|2/trueobjectstring/integer/booleannon-empty-list<T>,non-empty-array<T>objectarraywithitemsofTInside an array shape:
list<T>,non-empty-list<T>andarray<int, T>keys become arrays. The comma ofarray<int, T>no longer splits the shape key in two, becauseparseObjectLikeArray()now tracks<>depth as well as{}.array<string, T>keys become objects withadditionalProperties.mixedkeys get the empty schema{}, so they accept any value.The existing
int<min, max>handling moved into the same helper.Tests: added
testMapsPhpStanAndPsalmPseudoTypesToTheirBaseTypewith apseudoTypesfixture. It fails before this change and passes after.vendor/bin/phpunit --testsuite unit(2696 tests) passes, as dophp-cs-fixer fix --dry-runandphpstan. I also added a CHANGELOG entry under 0.10.0.I used an AI assistant to help write this change. I reviewed and tested it.