From 83fdfb3648e0c1a636ef0589e261cc48ea921456 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 15 Aug 2023 22:16:05 +0700 Subject: [PATCH] [DeadCode] Handle duplicated annotation on space before close parentheses on RemoveUselessParamTagRector (#4795) * Create do_not_duplicate_annotations.php.inc https://github.com/rectorphp/rector/issues/8101 * Fixes #4641 Closes https://github.com/rectorphp/rector/issues/8101 * Fixed :tada: * fix * ensure bracket compared * cs fix * cs fix --------- Co-authored-by: mkrauss --- .../DoctrineAnnotationDecorator.php | 31 +++++++++---- .../do_not_duplicate_annotations.php.inc | 45 +++++++++++++++++++ 2 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 rules-tests/DeadCode/Rector/ClassMethod/RemoveUselessParamTagRector/Fixture/do_not_duplicate_annotations.php.inc diff --git a/packages/BetterPhpDocParser/PhpDocParser/DoctrineAnnotationDecorator.php b/packages/BetterPhpDocParser/PhpDocParser/DoctrineAnnotationDecorator.php index 5a841356328..f460096fbe2 100644 --- a/packages/BetterPhpDocParser/PhpDocParser/DoctrineAnnotationDecorator.php +++ b/packages/BetterPhpDocParser/PhpDocParser/DoctrineAnnotationDecorator.php @@ -115,7 +115,9 @@ private function mergeNestedDoctrineAnnotations(PhpDocNode $phpDocNode): void continue; } - if ($this->isClosedContent($genericTagValueNode->value)) { + $isNewLinedGenericTagValueNode = str_starts_with($genericTagValueNode->value, '(') + && ! str_ends_with($genericTagValueNode->value, ')'); + if ($this->isClosedContent($genericTagValueNode->value, $isNewLinedGenericTagValueNode)) { break; } @@ -204,7 +206,7 @@ private function transformGenericTagValueNodesToDoctrineAnnotationTagValueNodes( * This is closed block, e.g. {( ... )}, * false on: {( ... ) */ - private function isClosedContent(string $composedContent): bool + private function isClosedContent(string $composedContent, bool $isNewLined): bool { $composedTokenIterator = $this->tokenIteratorFactory->create($composedContent); $tokenCount = $composedTokenIterator->count(); @@ -216,13 +218,6 @@ private function isClosedContent(string $composedContent): bool } do { - if ($composedTokenIterator->isCurrentTokenType( - Lexer::TOKEN_OPEN_CURLY_BRACKET, - Lexer::TOKEN_OPEN_PARENTHESES - ) || \str_contains($composedTokenIterator->currentTokenValue(), '(')) { - ++$openBracketCount; - } - if ( $composedTokenIterator->isCurrentTokenType( Lexer::TOKEN_CLOSE_CURLY_BRACKET, @@ -232,6 +227,24 @@ private function isClosedContent(string $composedContent): bool ++$closeBracketCount; } + if ($composedTokenIterator->isCurrentTokenType( + Lexer::TOKEN_OPEN_CURLY_BRACKET, + Lexer::TOKEN_OPEN_PARENTHESES + ) || \str_contains($composedTokenIterator->currentTokenValue(), '(')) { + ++$openBracketCount; + } + + if ($composedTokenIterator->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL) + && $composedTokenIterator->getContentBetween( + $composedTokenIterator->currentPosition() - 1, + $composedTokenIterator->currentPosition() + ) === '(' + && $isNewLined + && $openBracketCount > $closeBracketCount + ) { + --$openBracketCount; + } + $composedTokenIterator->next(); } while ($composedTokenIterator->currentPosition() < ($tokenCount - 1)); diff --git a/rules-tests/DeadCode/Rector/ClassMethod/RemoveUselessParamTagRector/Fixture/do_not_duplicate_annotations.php.inc b/rules-tests/DeadCode/Rector/ClassMethod/RemoveUselessParamTagRector/Fixture/do_not_duplicate_annotations.php.inc new file mode 100644 index 00000000000..50edb248db6 --- /dev/null +++ b/rules-tests/DeadCode/Rector/ClassMethod/RemoveUselessParamTagRector/Fixture/do_not_duplicate_annotations.php.inc @@ -0,0 +1,45 @@ + +----- +