diff --git a/config/set/code-quality/code-quality.yaml b/config/set/code-quality/code-quality.yaml index 732250cb5b27..89e90c7da5e4 100644 --- a/config/set/code-quality/code-quality.yaml +++ b/config/set/code-quality/code-quality.yaml @@ -54,3 +54,4 @@ services: Rector\CodeQuality\Rector\Foreach_\ForeachItemsAssignToEmptyArrayToAssignRector: null Rector\CodeQuality\Rector\BinaryOp\InlineIfToExplicitIfRector: null Rector\CodeQuality\Rector\FuncCall\ArrayKeysAndInArrayToArrayKeyExistsRector: null + Rector\CodeQuality\Rector\Assign\SplitListAssignToSeparateLineRector: null diff --git a/docs/AllRectorsOverview.md b/docs/AllRectorsOverview.md index 95139bed5a01..5372c597c076 100644 --- a/docs/AllRectorsOverview.md +++ b/docs/AllRectorsOverview.md @@ -1,4 +1,4 @@ -# All 497 Rectors Overview +# All 498 Rectors Overview - [Projects](#projects) - [General](#general) @@ -1726,6 +1726,27 @@ Changes in_array() with single element to ===
+### `SplitListAssignToSeparateLineRector` + +- class: [`Rector\CodeQuality\Rector\Assign\SplitListAssignToSeparateLineRector`](/../master/rules/code-quality/src/Rector/Assign/SplitListAssignToSeparateLineRector.php) +- [test fixtures](/../master/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/Fixture) + +Splits [$a, $b] = [5, 10] scalar assign to standalone lines + +```diff + final class SomeClass + { + public function run(): void + { +- [$a, $b] = [1, 2]; ++ $a = 1; ++ $b = 2; + } + } +``` + +
+ ### `StrlenZeroToIdenticalEmptyStringRector` - class: [`Rector\CodeQuality\Rector\FuncCall\StrlenZeroToIdenticalEmptyStringRector`](/../master/rules/code-quality/src/Rector/FuncCall/StrlenZeroToIdenticalEmptyStringRector.php) diff --git a/rules/code-quality/src/Rector/Assign/SplitListAssignToSeparateLineRector.php b/rules/code-quality/src/Rector/Assign/SplitListAssignToSeparateLineRector.php new file mode 100644 index 000000000000..ee30aff1348e --- /dev/null +++ b/rules/code-quality/src/Rector/Assign/SplitListAssignToSeparateLineRector.php @@ -0,0 +1,146 @@ +shouldSkip($node)) { + return null; + } + + /** @var Array_|List_ $leftArray */ + $leftArray = $node->var; + + /** @var Array_ $rightArray */ + $rightArray = $node->expr; + + $standaloneAssigns = $this->createStandaloneAssigns($leftArray, $rightArray); + foreach ($standaloneAssigns as $standaloneAssign) { + $this->addNodeAfterNode($standaloneAssign, $node); + } + + $this->removeNode($node); + + return $node; + } + + private function shouldSkip($node): bool + { + if (! $node->var instanceof Array_ && ! $node->var instanceof List_) { + return true; + } + + if (! $node->expr instanceof Array_) { + return true; + } + + if (count($node->var->items) !== count($node->expr->items)) { + return true; + } + + // is value swap + return $this->isValueSwap($node->var, $node->expr); + } + + /** + * @param Array_|List_ $node + * @return Assign[] + */ + private function createStandaloneAssigns(Node $node, Array_ $rightArray): array + { + $standaloneAssigns = []; + foreach ($node->items as $key => $leftArrayItem) { + $rightArrayItem = $rightArray->items[$key]; + + $standaloneAssigns[] = new Assign($leftArrayItem->value, $rightArrayItem); + } + + return $standaloneAssigns; + } + + /** + * @param Array_|List_ $node + */ + private function getArrayItemsHash(Node $node): string + { + $arrayItemsHashes = []; + foreach ($node->items as $arrayItem) { + $arrayItemsHashes[] = $this->printWithoutComments($arrayItem); + } + + sort($arrayItemsHashes); + + $arrayItemsHash = implode('', $arrayItemsHashes); + + return sha1($arrayItemsHash); + } + + /** + * @param Array_|List_ $firstArray + * @param Array_|List_ $secondArray + */ + private function isValueSwap($firstArray, $secondArray): bool + { + $firstArrayItemsHash = $this->getArrayItemsHash($firstArray); + $secondArrayItemsHash = $this->getArrayItemsHash($secondArray); + + return $firstArrayItemsHash === $secondArrayItemsHash; + } +} diff --git a/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/Fixture/fixture.php.inc b/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/Fixture/fixture.php.inc new file mode 100644 index 000000000000..eacf359dd112 --- /dev/null +++ b/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/Fixture/fixture.php.inc @@ -0,0 +1,28 @@ + +----- + diff --git a/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/Fixture/not_scalar.php.inc b/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/Fixture/not_scalar.php.inc new file mode 100644 index 000000000000..47b18d22c046 --- /dev/null +++ b/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/Fixture/not_scalar.php.inc @@ -0,0 +1,30 @@ + +----- + diff --git a/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/Fixture/skip_split_of_array.php.inc b/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/Fixture/skip_split_of_array.php.inc new file mode 100644 index 000000000000..6eeec1052ed8 --- /dev/null +++ b/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/Fixture/skip_split_of_array.php.inc @@ -0,0 +1,12 @@ + +----- + diff --git a/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/SplitListAssignToSeparateLineRectorTest.php b/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/SplitListAssignToSeparateLineRectorTest.php new file mode 100644 index 000000000000..aa4245ca1f7e --- /dev/null +++ b/rules/code-quality/tests/Rector/Assign/SplitListAssignToSeparateLineRector/SplitListAssignToSeparateLineRectorTest.php @@ -0,0 +1,30 @@ +doTestFile($file); + } + + public function provideData(): Iterator + { + return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + protected function getRectorClass(): string + { + return SplitListAssignToSeparateLineRector::class; + } +} diff --git a/rules/php70/src/Rector/Ternary/TernaryToNullCoalescingRector.php b/rules/php70/src/Rector/Ternary/TernaryToNullCoalescingRector.php index a5c2f37082f7..e566ae699d75 100644 --- a/rules/php70/src/Rector/Ternary/TernaryToNullCoalescingRector.php +++ b/rules/php70/src/Rector/Ternary/TernaryToNullCoalescingRector.php @@ -53,9 +53,11 @@ public function refactor(Node $node): ?Node } if ($node->cond instanceof Identical) { - [$checkedNode, $fallbackNode] = [$node->else, $node->if]; + $checkedNode = $node->else; + $fallbackNode = $node->if; } elseif ($node->cond instanceof NotIdentical) { - [$checkedNode, $fallbackNode] = [$node->if, $node->else]; + $checkedNode = $node->if; + $fallbackNode = $node->else; } else { // not a match return null;