Skip to content

Move union dedup and array printing to type mappers - #8858

Merged
TomasVotruba merged 1 commit into
rectorphp:mainfrom
ondrejmirtes:phpdoc-type-mappers-print-rules
Oct 27, 2026
Merged

TomasVotruba merged 1 commit into
rectorphp:mainfrom
ondrejmirtes:phpdoc-type-mappers-print-rules

Conversation

@ondrejmirtes

Copy link
Copy Markdown
Contributor

BracketsAwareUnionTypeNode::__toString() and SpacingAwareArrayTypeNode::__toString() changed the meaning of the type when it was printed. They removed duplicate union members, changed (A|B)[] to A[]|B[] or array<int, A<X>|A<Y>>, and changed array<string, (A|B)[]> to array<string, array<A|B>>.

This PR moves these rules to UnionTypeMapper and ArrayTypeMapper. The mappers now create the final node tree. __toString() prints the nodes as they are. This is necessary to use the format-preserving printer of phpstan/phpdoc-parser, which prints the node tree and does not call __toString().

  • ArrayTypeMapper changes an array of union item type to a union of arrays, or to array<int, ...> when all items are generics of the same type.
  • UnionTypeMapper merges nested unions and removes duplicates.
  • The HAS_GENERIC_TYPE_PARENT attribute is removed.

Types that Rector creates do not change. When Rector reprints a type from the original docblock, it keeps duplicate union members (int|int stays int|int), and (A|B)[][] is printed correctly. Before, it was printed as (A[]|B)[][].

More PRs coming after this one ;) They will remove a lot of code and make things faster.

@TomasVotruba

Copy link
Copy Markdown
Member

Thanks, good improvement 👌

@TomasVotruba
TomasVotruba merged commit b48dbfd into rectorphp:main Oct 27, 2026
50 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants