diff --git a/src/Parser/PhpDocParser.php b/src/Parser/PhpDocParser.php index f6734225..29fb4be9 100644 --- a/src/Parser/PhpDocParser.php +++ b/src/Parser/PhpDocParser.php @@ -149,11 +149,21 @@ private function parseChild(TokenIterator $tokens): Ast\PhpDoc\PhpDocChildNode $tagStartLine = $tokens->currentTokenLine(); $tagStartIndex = $tokens->currentTokenIndex(); + try { + $tokens->pushSavePoint(); + $tagValue = $this->parseDoctrineTagValue($tokens, $tag); + $tokens->dropSavePoint(); + + } catch (ParserException $e) { + $tokens->rollback(); + $tagValue = new Ast\PhpDoc\InvalidTagValueNode($this->parseOptionalDescription($tokens, false), $e); + } + return $this->enrichWithAttributes($tokens, new Ast\PhpDoc\PhpDocTagNode( $tag, $this->enrichWithAttributes( $tokens, - $this->parseDoctrineTagValue($tokens, $tag), + $tagValue, $tagStartLine, $tagStartIndex, ), diff --git a/tests/PHPStan/Parser/PhpDocParserTest.php b/tests/PHPStan/Parser/PhpDocParserTest.php index 238d4a38..95d045c5 100644 --- a/tests/PHPStan/Parser/PhpDocParserTest.php +++ b/tests/PHPStan/Parser/PhpDocParserTest.php @@ -6386,6 +6386,37 @@ public function provideTagsWithBackslash(): Iterator ), ]), ]; + + yield [ + 'Invalid Doctrine tag with backslash keeps the next tags', + "/**\n * @\\ORM\\Table('user')\n * @param int \$a\n */", + new PhpDocNode([ + new PhpDocTagNode( + '@\\ORM\\Table', + new InvalidTagValueNode( + "('user')", + new ParserException( + "'user'", + Lexer::TOKEN_SINGLE_QUOTED_STRING, + 19, + Lexer::TOKEN_DOUBLE_QUOTED_STRING, + null, + 2, + ), + ), + ), + new PhpDocTagNode( + '@param', + new ParamTagValueNode( + new IdentifierTypeNode('int'), + false, + '$a', + '', + false, + ), + ), + ]), + ]; } public function provideSelfOutTagsData(): Iterator