diff --git a/rules/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector.php b/rules/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector.php index fc30e99f85d..a03d3995f1a 100644 --- a/rules/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector.php +++ b/rules/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector.php @@ -16,6 +16,10 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; */ final class RemoveDuplicatedCaseInSwitchRector extends AbstractRector { + /** + * @var bool + */ + private $hasChanged = \false; public function getRuleDefinition() : RuleDefinition { return new RuleDefinition('2 following switch keys with identical will be reduced to one result', [new CodeSample(<<<'CODE_SAMPLE' @@ -70,24 +74,71 @@ CODE_SAMPLE if (\count($node->cases) < 2) { return null; } - /** @var Case_|null $previousCase */ - $previousCase = null; - $hasChanged = \false; - foreach ($node->cases as $case) { - if ($previousCase instanceof Case_ && $this->areSwitchStmtsEqualsAndWithBreak($case, $previousCase)) { - $previousCase->stmts = []; - $hasChanged = \true; - } - $previousCase = $case; - } - if (!$hasChanged) { + $this->hasChanged = \false; + $insertByKeys = $this->resolveInsertedByKeys($node); + $this->insertCaseByKeys($node, $insertByKeys); + $this->cleanUpEqualCaseStmts($node); + if (!$this->hasChanged) { return null; } return $node; } - private function areSwitchStmtsEqualsAndWithBreak(Case_ $currentCase, Case_ $previousCase) : bool + /** + * @return array> + */ + private function resolveInsertedByKeys(Switch_ $switch) : array { - if (!$this->nodeComparator->areNodesEqual($currentCase->stmts, $previousCase->stmts)) { + $totalKeys = \count($switch->cases); + $insertByKeys = []; + foreach ($switch->cases as $key => $case) { + if ($case->stmts === []) { + continue; + } + $nextKey = $key + 1; + for ($jumpToKey = $key + 1; $jumpToKey < $totalKeys; ++$jumpToKey) { + if (!isset($switch->cases[$jumpToKey])) { + continue; + } + if (!$this->areSwitchStmtsEqualsAndWithBreak($case, $switch->cases[$jumpToKey])) { + continue; + } + if ($nextKey === $jumpToKey) { + continue 2; + } + $nextCase = $switch->cases[$jumpToKey]; + unset($switch->cases[$jumpToKey]); + $insertByKeys[$key][] = $nextCase; + $this->hasChanged = \true; + } + } + return $insertByKeys; + } + /** + * @param array> $insertByKeys + */ + private function insertCaseByKeys(Switch_ $switch, array $insertByKeys) : void + { + foreach ($insertByKeys as $key => $insertByKey) { + $switch->cases[$key]->stmts = []; + $nextKey = $key + 1; + \array_splice($switch->cases, $nextKey, 0, $insertByKey); + } + } + private function cleanUpEqualCaseStmts(Switch_ $switch) : void + { + /** @var Case_|null $previousCase */ + $previousCase = null; + foreach ($switch->cases as $case) { + if ($previousCase instanceof Case_ && $this->areSwitchStmtsEqualsAndWithBreak($case, $previousCase)) { + $previousCase->stmts = []; + $this->hasChanged = \true; + } + $previousCase = $case; + } + } + private function areSwitchStmtsEqualsAndWithBreak(Case_ $currentCase, Case_ $nextCase) : bool + { + if (!$this->nodeComparator->areNodesEqual($currentCase->stmts, $nextCase->stmts)) { return \false; } foreach ($currentCase->stmts as $stmt) { diff --git a/rules/Php74/Rector/Property/RestoreDefaultNullToNullableTypePropertyRector.php b/rules/Php74/Rector/Property/RestoreDefaultNullToNullableTypePropertyRector.php index 899f98a86d6..5f9e7405c6f 100644 --- a/rules/Php74/Rector/Property/RestoreDefaultNullToNullableTypePropertyRector.php +++ b/rules/Php74/Rector/Property/RestoreDefaultNullToNullableTypePropertyRector.php @@ -3,6 +3,7 @@ declare (strict_types=1); namespace Rector\Php74\Rector\Property; +use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\Node\Stmt\Class_; @@ -23,9 +24,15 @@ final class RestoreDefaultNullToNullableTypePropertyRector extends AbstractRecto * @var \Rector\TypeDeclaration\AlreadyAssignDetector\ConstructorAssignDetector */ private $constructorAssignDetector; - public function __construct(ConstructorAssignDetector $constructorAssignDetector) + /** + * @readonly + * @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory + */ + private $phpDocInfoFactory; + public function __construct(ConstructorAssignDetector $constructorAssignDetector, PhpDocInfoFactory $phpDocInfoFactory) { $this->constructorAssignDetector = $constructorAssignDetector; + $this->phpDocInfoFactory = $phpDocInfoFactory; } public function getRuleDefinition() : RuleDefinition { diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index 19aa34b5f56..c5e1bb42f1f 100644 --- a/src/Application/VersionResolver.php +++ b/src/Application/VersionResolver.php @@ -19,12 +19,12 @@ final class VersionResolver * @api * @var string */ - public const PACKAGE_VERSION = '437f96a264be9b974d2c5abcc4f5097bfb57b20e'; + public const PACKAGE_VERSION = '3f2fb29fe87904d779fb2f8d3e59492aaa9249f4'; /** * @api * @var string */ - public const RELEASE_DATE = '2023-11-08 19:04:48'; + public const RELEASE_DATE = '2023-11-10 05:04:21'; /** * @var int */