Fix: Merge type selections for inline fragments with shared field names#126
Merged
spawnia merged 3 commits intospawnia:masterfrom Jan 21, 2026
Merged
Conversation
When multiple inline fragments selected the same field name with different concrete return types, only the first type class was generated. This caused missing class errors for subsequent fragments. The bug was in OperationStack::setSelection() using `??=` which ignored subsequent selections for the same namespace. Changed to conditionally merge new types while preserving existing ones to avoid reprocessing subtrees.
spawnia
reviewed
Jan 14, 2026
Added examples/inline-fragments/ to demonstrate the bug fix. The example has two inline fragments selecting a 'content' field with different return types (ArticleContent vs VideoContent). Without the fix, only the first type class gets generated. - Add examples/inline-fragments/ with schema and query - Update tests/Examples.php and Makefile - Remove tests/Unit/Codegen/OperationStackTest.php
Owner
|
Could you please merge the latest master into your branch? I tried to do it but don't have push access to your fork. |
Contributor
Author
|
Merged in the |
Owner
|
Thank you, released with https://github.com/spawnia/sailor/releases/tag/v1.1.2. Please consider sponsoring. |
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.
Changes
Fix codegen skipping type classes in inline fragments with shared field names
The codegen was only generating the first type class when multiple inline
fragments selected the same field name but returned different concrete types.
For example, given this query:
Where each
articlefield resolves to a different concrete type (Note, Update,InitiationCoverage), only the Note.php class would get generated. The other two
were skipped, even though the generated code still referenced them in the type
converters. This obviously broke static analysis and caused runtime errors.
The problem was in OperationStack::setSelection(). It used
??=which meant"only set if not already set":
So when processing the fragments:
so it gets ignored
Changed it to merge selections by adding only new types that haven't been
processed yet:
This selective merging ensures all types get generated while avoiding
reprocessing of types that were already handled (which would lose their
field selections).
This only affects schemas where you have inline fragments on interfaces with
fields that return different concrete types per implementation. Union types
already worked because they handle all possible types in a single pass.->
Breaking changes