Repository navigation
Add enum constants for field options in generated block types - #8
Merged
Merged
Conversation
Every content and config field of a block whose type is a union of literals, a select field's `value` included, gets one constant per option, named `<CONTENT|CONFIG>_<FIELD>_<OPTION>`: `CONTENT_SIZE_SMALL = 'small'`, `CONFIG_SIZE_SMALL = 'small'`. The values are the strings TypeMapper writes into the field's type, so comparing a field with a constant type-checks wherever comparing it with the literal does. A name that would stand for two different options is not generated, with a warning, rather than numbered: a number would silently move to another option once one is added. Only flyo-generate-types generates them. The deprecated flyo-generate-blocks keeps producing byte-identical files. An enum member containing `*/` closed the docblock its type is rendered into, so the generated file did not parse. Such an enum now falls back to `string`, like one with a newline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SjJHX6UBVjHdxaoMgHLZYC
A types/enums fixture with select and plain enum fields in content and config, its golden file, and level 9 PHPStan assertions: a match over a field with its constants as arms is only exhaustive when the constants cover exactly the literals of the field's type. Unit tests for EnumConstants (detection, naming, collisions, fields that get none), Naming::constantSegment(), TypeMapper::enumMembers(), hostile option values, and that the deprecated command generates no enum constants. README and UPGRADE describe the constants and the `*/` fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SjJHX6UBVjHdxaoMgHLZYC
…e constants The remaining files of the previous commit: TypeMapperTest gains the `*/` case and a direct test of enumMembers(), DegenerateSchemaTest checks that quotes, backslashes, `?>`, `$`, tabs and umlauts in options still render valid constants, and that an option with `*/` falls back to `string` without constants. README and UPGRADE describe both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SjJHX6UBVjHdxaoMgHLZYC
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SjJHX6UBVjHdxaoMgHLZYC
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
This change adds automatic generation of PHP constants for every fixed option in content and config fields of block classes. Each option becomes a class constant named
<CONTENT|CONFIG>_<FIELD>_<OPTION>with the option value, enabling type-safe matching against field values.Key Changes
New
EnumConstantsclass (lib/Generator/EnumConstants.php): Analyzes block schemas to identify fields with fixed option sets (both directenumfields and select fields) and generatesConstantDefobjects for each option. Handles collision detection when multiple options would generate the same constant name, emitting warnings instead of silently numbering them.Updated
TypeMapper: Extracted enum member processing into a public staticenumMembers()method to support both type generation and constant naming. Added validation to reject enums containing*/(which would break docblocks) or newlines, falling back to plainstringtype.Modified
BlockKind: Added optional$enumConstantsparameter (defaults totrue) to control constant generation. The deprecatedflyo-generate-blockscommand disables it to maintain backward compatibility, whileflyo-generate-typesenables it.Enhanced
Renderer: Updated constant rendering to group related constants (e.g., all options of one field) without blank lines between them, with blank lines separating different fields.Updated
Naming: AddedconstantSegment()method to convert field names and option values to upper snake case suitable for constant names, handling kebab-case, camelCase, and special characters.Comprehensive test coverage: Added
EnumConstantsTestwith 20+ test cases covering select fields, collision detection, invalid options, and edge cases. Added fixture with OpenAPI schema and expected output demonstrating the feature.Notable Implementation Details
contentandconfigobject properties, not nested structuresvalueproperty) have constants named after the field, not thevalueproperty'2'not2)content.size "small_wide"andcontent.size_small "wide"both wantCONTENT_SIZE_SMALL_WIDE)flyo-generate-blockscommand output remains unchanged for backward compatibilityhttps://claude.ai/code/session_01SjJHX6UBVjHdxaoMgHLZYC