From f6de34b24a6f5f2413cfaa0e64fa315c89c6ea86 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 28 Dec 2025 23:22:39 +0700 Subject: [PATCH 1/3] [DeadCode] Handle multi vars on RemoveNonExistingVarAnnotationRector --- .../RemoveNonExistingVarAnnotationRector.php | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/rules/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector.php b/rules/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector.php index 55193a04a9b..f851d97f64e 100644 --- a/rules/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector.php +++ b/rules/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector.php @@ -146,38 +146,46 @@ public function refactor(Node $node): ?Node $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($stmt); - $varTagValueNode = $phpDocInfo->getVarTagValueNode(); - if (! $varTagValueNode instanceof VarTagValueNode) { - continue; - } + $varTagValueNodes = $phpDocInfo->getPhpDocNode() + ->getVarTagValues(); - if ($this->isObjectShapePseudoType($varTagValueNode)) { - continue; - } + foreach ($varTagValueNodes as $varTagValueNode) { + if ($this->isObjectShapePseudoType($varTagValueNode)) { + continue; + } - $variableName = ltrim($varTagValueNode->variableName, '$'); + $variableName = ltrim($varTagValueNode->variableName, '$'); - if ($variableName === '' && $this->isAllowedEmptyVariableName($stmt)) { - continue; - } + if ($variableName === '' && $this->isAllowedEmptyVariableName($stmt)) { + continue; + } - if ($this->hasVariableName($stmt, $variableName)) { - continue; - } + if ($this->hasVariableName($stmt, $variableName)) { + continue; + } - $comments = $node->getComments(); - if (isset($comments[1])) { - // skip edge case with double comment, as impossible to resolve by PHPStan doc parser - continue; - } + $comments = $node->getComments(); + if (isset($comments[1])) { + // skip edge case with double comment, as impossible to resolve by PHPStan doc parser + continue; + } - if ($this->stmtsManipulator->isVariableUsedInNextStmt($node, $key + 1, $variableName)) { - continue; + if ($this->stmtsManipulator->isVariableUsedInNextStmt($node, $key + 1, $variableName)) { + continue; + } + + if ($variableName === '') { + $phpDocInfo->removeByType(VarTagValueNode::class); + } else { + $phpDocInfo->removeByType(VarTagValueNode::class, $variableName); + } + + $hasChanged = true; } - $phpDocInfo->removeByType(VarTagValueNode::class); - $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($stmt); - $hasChanged = true; + if ($hasChanged) { + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($stmt); + } } if ($hasChanged) { From 20e0d9c89292ee003b6d2ab596a84bdf3f940b8f Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 28 Dec 2025 23:22:43 +0700 Subject: [PATCH 2/3] [DeadCode] Handle multi vars on RemoveNonExistingVarAnnotationRector --- .../Fixture/multi_vars.php.inc | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 rules-tests/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector/Fixture/multi_vars.php.inc diff --git a/rules-tests/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector/Fixture/multi_vars.php.inc b/rules-tests/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector/Fixture/multi_vars.php.inc new file mode 100644 index 00000000000..34d655a3b12 --- /dev/null +++ b/rules-tests/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector/Fixture/multi_vars.php.inc @@ -0,0 +1,22 @@ + $sickDays + */ +foreach ($sickDays as $vacation) { + +} + +?> +----- + $sickDays + */ +foreach ($sickDays as $vacation) { + +} + +?> From 6bdccb579d9513021a8268655a639f45ee5586fe Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sun, 28 Dec 2025 23:26:55 +0700 Subject: [PATCH 3/3] ensure update docblock only on has changed inside loop --- .../Rector/Node/RemoveNonExistingVarAnnotationRector.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rules/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector.php b/rules/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector.php index f851d97f64e..ab5d807e861 100644 --- a/rules/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector.php +++ b/rules/DeadCode/Rector/Node/RemoveNonExistingVarAnnotationRector.php @@ -114,6 +114,7 @@ public function refactor(Node $node): ?Node $extractValues = []; foreach ($node->stmts as $key => $stmt) { + $hasChangedStmt = false; if ($stmt instanceof Expression && $stmt->expr instanceof FuncCall && $this->isName( $stmt->expr, 'extract' @@ -180,11 +181,12 @@ public function refactor(Node $node): ?Node $phpDocInfo->removeByType(VarTagValueNode::class, $variableName); } - $hasChanged = true; + $hasChangedStmt = true; } - if ($hasChanged) { + if ($hasChangedStmt) { $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($stmt); + $hasChanged = true; } }