Skip to content

[TypeDeclaration] Skip already documented generic type in AddParamTypeSplFixedArrayRector - #8730

Merged
TomasVotruba merged 1 commit into
rectorphp:mainfrom
kenny-ish:skip-documented-spl-fixed-array-generic
Oct 20, 2026
Merged

TomasVotruba merged 1 commit into
rectorphp:mainfrom
kenny-ish:skip-documented-spl-fixed-array-generic

Conversation

@kenny-ish

Copy link
Copy Markdown

Fixes rectorphp/rector#9933

AddParamTypeSplFixedArrayRector rewrites an existing @param Tokens<Token> $tokens tag to @param \PhpCsFixer\Tokenizer\Tokens<\PhpCsFixer\Tokenizer\Token> $tokens as soon as one of the names is short, whether imported or in the same namespace. php-cs-fixer's fully_qualified_strict_types shortens it again, so the two tools flip the line on every run.

The rule hands its GenericObjectType to PhpDocTypeChanger::changeParamType(), which maps the existing tag to a PHPStan type and compares the two. Tokens is not a generic class, so PHPStan resolves Tokens<Token> to iterable<Token>&Tokens. That is never equal to Tokens<Token> as a GenericObjectType, so the tag is replaced. The fully qualified spelling goes through the same path; it just prints the same text again, which is why only the short form shows up as a change.

The rule now skips a param whose docblock already has a single-argument generic tag that resolves to the same fixed array class and the same item class. A plain @param Tokens $tokens is still upgraded.

Fixtures:

  • skip_short_named_generic_doc: imported Tokens<Token> is left alone (fails on main)
  • skip_same_namespace_generic_doc: same-namespace Tokens<Token> is left alone (fails on main)
  • plain_doc: @param Tokens $tokens still gets the generic type

The existing fixture only had the php-cs-fixer classes missing, where the comparison happens to pass, so stubs/PhpCsFixer/Tokenizer/Token.php and Tokens.php are added, guarded by class_exists() like the other stubs.

…eSplFixedArrayRector

The rule compares the existing @PARAM type with the GenericObjectType it
wants to add. Tokens is not a generic class, so an existing "Tokens<Token>"
tag resolves to "iterable<Token>&Tokens", which never equals the generic
object type, and the tag is rewritten with fully qualified names. With
php-cs-fixer's fully_qualified_strict_types shortening it back, the two
tools never settle.

Skip a param whose docblock already has a single-argument generic tag that
resolves to the same fixed array class and item class, whatever the
spelling of the names.

Fixes rectorphp/rector#9933
@TomasVotruba

Copy link
Copy Markdown
Member

LGTM, lets give it a go 👌

@TomasVotruba
TomasVotruba merged commit 4652e70 into rectorphp:main Oct 20, 2026
49 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.

AddParamTypeSplFixedArrayRector rewrites an existing Tokens<Token> tag that uses short names

2 participants