Skip to content

Use PhpDocParser from phpstan/phpdoc-parser without subclass - #8871

Merged
TomasVotruba merged 2 commits into
rectorphp:mainfrom
ondrejmirtes:phpdoc-parser-subclass
Oct 28, 2026
Merged

TomasVotruba merged 2 commits into
rectorphp:mainfrom
ondrejmirtes:phpdoc-parser-subclass

Conversation

@ondrejmirtes

@ondrejmirtes ondrejmirtes commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

BetterPhpDocParser does not extend PhpDocParser now. It calls PhpDocParser::parse(), then runs the node decorators. Before, it called the private parseChild() method with PrivatesAccessor.

  • Tag positions come from the START_INDEX and END_INDEX attributes of phpdoc-parser.
  • CloningPhpDocNodeVisitor is replaced with CloningVisitor from phpdoc-parser.

Fixed: tags after an inline tag were lost

Before, this docblock ended at @internal Use. The parser did not see @var string:

/**
 * @internal Use @see \Rector\Config\RectorConfig::paths() instead
 * @var string
 */

PhpDocParser::parse() continues after a generic tag value, so all tags are found now. Because of this, RemoveUselessVarTagRector now removes 24 @var string tags from typed constants in src/Configuration/Option.php. The new fixture after_inline_tag.php.inc covers this.

Invalid Doctrine annotation

For an invalid annotation such as @\Doctrine\ORM\Mapping\Table('user'), parse() throws ParserException. Rector then keeps the docblock as one text node and does not change it. phpstan/phpdoc-parser#335 fixes this in phpdoc-parser.

Fixed: crash on incomplete Doctrine annotation

@ORM\Table('user', indexes={ @ORM\Index(...) }) with a single-quoted argument gets InvalidTagValueNode. Its value ends before the nested @ORM\Index lines. NestedAnnotationToAttributeRector then threw ShouldNotHappenException.

Now DoctrineAnnotationDecorator keeps such annotation and the next children unchanged until the brackets close. The new fixture skip_single_quoted_alias.php.inc covers this.

This also makes phpstan/phpdoc-parser#335 pass with Rector.

BetterPhpDocParser now calls PhpDocParser::parse() and then runs the
decorators. Positions come from the START_INDEX and END_INDEX attributes.

Tags after an inline tag are now parsed. Before, "@internal Use @see Foo"
ended the docblock and the next tags were lost.

CloningPhpDocNodeVisitor is replaced with CloningVisitor.

Amp-Thread-ID: https://ampcode.com/threads/T-01a17930-0285-73c5-a957-4325c77aa1b2
@Orm\Table('user', indexes={...}) with a single-quoted argument gets
InvalidTagValueNode. Its value ends before the nested @Orm\Index lines.
NestedAnnotationToAttributeRector then threw ShouldNotHappenException.

The decorator now keeps such annotation and its next children unchanged.

Amp-Thread-ID: https://ampcode.com/threads/T-01a17930-0285-73c5-a957-4325c77aa1b2
@TomasVotruba
TomasVotruba merged commit be145d9 into rectorphp:main Oct 28, 2026
50 checks passed
@TomasVotruba

Copy link
Copy Markdown
Member

Thank you 👌

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