diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/fixture.php.inc b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/fixture.php.inc deleted file mode 100644 index 824862b427c..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/fixture.php.inc +++ /dev/null @@ -1,33 +0,0 @@ - $value) { - $items[$key] = null; - } - } -} - -?> ------ - diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/remove_both_item_from_value_use.php.inc b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/remove_both_item_from_value_use.php.inc deleted file mode 100644 index a90104e2007..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/remove_both_item_from_value_use.php.inc +++ /dev/null @@ -1,31 +0,0 @@ - [$domElement, $file]) { - echo $id; - } - } -} - -?> ------ - diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/remove_single_item_from_value_use.php.inc b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/remove_single_item_from_value_use.php.inc deleted file mode 100644 index 2aa4386f479..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/remove_single_item_from_value_use.php.inc +++ /dev/null @@ -1,35 +0,0 @@ - [$domElement, $file]) { - if ($domElement) { - return true; - } - } - } -} - -?> ------ - [$domElement]) { - if ($domElement) { - return true; - } - } - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_array_access_object.php.inc b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_array_access_object.php.inc deleted file mode 100644 index 442faa18a7f..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_array_access_object.php.inc +++ /dev/null @@ -1,22 +0,0 @@ - $tokens - */ - public function run(Tokens $tokens) - { - $indexes = []; - foreach ($tokens as $index => $token) { - $indexes[] = $index; - } - - return $indexes; - } -} diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_foreach_destruct_keys.php.inc b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_foreach_destruct_keys.php.inc deleted file mode 100644 index 4de013bb955..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_foreach_destruct_keys.php.inc +++ /dev/null @@ -1,15 +0,0 @@ - [$domElement, $file]) { - if ($file) { - return $file; - } - } - } -} diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_list_value_use.php.inc b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_list_value_use.php.inc deleted file mode 100644 index 7d650df7f7a..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_list_value_use.php.inc +++ /dev/null @@ -1,14 +0,0 @@ - [$domElement, $file]) { - if ($domElement && $file) { - } - } - } -} diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_no_key.php.inc b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_no_key.php.inc deleted file mode 100644 index 577524738b8..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_no_key.php.inc +++ /dev/null @@ -1,14 +0,0 @@ - $label) { - $query = $this->find(); - $amount = $query->where([$this->aliasField($field) => $userId])->count(); - $items[$field] = compact('label', 'amount'); - } - } -} \ No newline at end of file diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_used_in_next_stmt.php.inc b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_used_in_next_stmt.php.inc deleted file mode 100644 index 0889db446d9..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_used_in_next_stmt.php.inc +++ /dev/null @@ -1,19 +0,0 @@ - $regRule) { - if (strpos($dateTimeFormat, $supportedFormat, 0) !== false) { - $isSupportedFormatFound = true; - break; - } - } - - $regex = array_shift($regRule); - $mask = array_shift($regRule); - } -} \ No newline at end of file diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_used_in_throw_stmts_in_catch.php.inc b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_used_in_throw_stmts_in_catch.php.inc deleted file mode 100644 index 1ff2c4f8a9e..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_used_in_throw_stmts_in_catch.php.inc +++ /dev/null @@ -1,20 +0,0 @@ - $val) { - throw new \Exception('test'); - } - } catch (\Throwable) { - echo 'Failed at value '.$val; - } - } -} diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_value_used.php.inc b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_value_used.php.inc deleted file mode 100644 index 7da684a841d..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_value_used.php.inc +++ /dev/null @@ -1,18 +0,0 @@ - $value) { - $items[$key] = null; - - if (true) { - return $value; - } - } - } -} diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_values_is_object.php.inc b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_values_is_object.php.inc deleted file mode 100644 index 4e2e4ec1884..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Fixture/skip_values_is_object.php.inc +++ /dev/null @@ -1,18 +0,0 @@ - $value) { - $collection[$key] = null; - } - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Source/Collection.php b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Source/Collection.php deleted file mode 100644 index db70272a89e..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/Source/Collection.php +++ /dev/null @@ -1,12 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule.php'; - } -} diff --git a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/config/configured_rule.php b/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/config/configured_rule.php deleted file mode 100644 index 80f0518a685..00000000000 --- a/rules-tests/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector/config/configured_rule.php +++ /dev/null @@ -1,9 +0,0 @@ -withRules([UnusedForeachValueToArrayKeysRector::class]); diff --git a/rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php b/rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php index 51b3d304f29..c70ef3ae2ed 100644 --- a/rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php +++ b/rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php @@ -5,31 +5,18 @@ namespace Rector\CodeQuality\Rector\Foreach_; use PhpParser\Node; -use PhpParser\Node\ArrayItem; -use PhpParser\Node\Expr; -use PhpParser\Node\Expr\List_; -use PhpParser\Node\Expr\Variable; -use PhpParser\Node\Stmt\Foreach_; -use Rector\DeadCode\NodeAnalyzer\ExprUsedInNodeAnalyzer; -use Rector\NodeManipulator\StmtsManipulator; +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; +use Rector\Exception\ShouldNotHappenException; use Rector\PhpParser\Enum\NodeGroup; -use Rector\PhpParser\Node\BetterNodeFinder; use Rector\Rector\AbstractRector; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** - * @see \Rector\Tests\CodeQuality\Rector\Foreach_\UnusedForeachValueToArrayKeysRector\UnusedForeachValueToArrayKeysRectorTest + * @deprecated This rule is deprecated, as it is a personal preference. The array_keys() wrap makes the foreach harder to read and harder to extend, once the value is needed again. */ -final class UnusedForeachValueToArrayKeysRector extends AbstractRector +final class UnusedForeachValueToArrayKeysRector extends AbstractRector implements DeprecatedInterface { - public function __construct( - private readonly ExprUsedInNodeAnalyzer $exprUsedInNodeAnalyzer, - private readonly BetterNodeFinder $betterNodeFinder, - private readonly StmtsManipulator $stmtsManipulator - ) { - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( @@ -79,141 +66,9 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - $stmts = $node->stmts; - - if ($stmts === null) { - return null; - } - - $hasChanged = false; - foreach ($stmts as $key => $stmt) { - if (! $stmt instanceof Foreach_) { - continue; - } - - if (! $stmt->keyVar instanceof Expr) { - continue; - } - - if (! $this->nodeTypeResolver->getNativeType($stmt->expr)->isArray()->yes()) { - continue; - } - - // special case of nested array items - if ($stmt->valueVar instanceof List_) { - $valueArray = $this->refactorArrayForeachValue($stmt->valueVar, $stmt); - if (! $valueArray instanceof List_) { - continue; - } - - $stmt->valueVar = $valueArray; - - // not sure what does this mean :) - if ($valueArray->items !== []) { - continue; - } - - $hasChanged = true; - $this->removeForeachValueAndUseArrayKeys($stmt, $stmt->keyVar); - continue; - } - - if (! $stmt->valueVar instanceof Variable) { - continue; - } - - if ($this->isVariableUsedInForeach($stmt->valueVar, $stmt)) { - continue; - } - - if ($this->stmtsManipulator->isVariableUsedInNextStmt( - $node, - $key + 1, - (string) $this->getName($stmt->valueVar) - )) { - continue; - } - - $hasChanged = true; - $this->removeForeachValueAndUseArrayKeys($stmt, $stmt->keyVar); - } - - if (! $hasChanged) { - return null; - } - - return $node; - } - - /** - * @param int[] $removedKeys - */ - private function isArrayItemsRemovalWithoutChangingOrder(List_ $list, array $removedKeys): bool - { - $hasRemovingStarted = false; - - foreach (array_keys($list->items) as $key) { - if (in_array($key, $removedKeys, true)) { - $hasRemovingStarted = true; - } elseif ($hasRemovingStarted) { - // we cannot remove the previous item, and not remove the next one, because that would change the order - return false; - } - } - - return true; - } - - private function refactorArrayForeachValue(List_ $list, Foreach_ $foreach): ?List_ - { - // only last items can be removed, without changing the order - $removedKeys = []; - - foreach ($list->items as $key => $arrayItem) { - if (! $arrayItem instanceof ArrayItem) { - // only known values can be processes - return null; - } - - $value = $arrayItem->value; - if (! $value instanceof Variable) { - // only variables can be processed - return null; - } - - if ($this->isVariableUsedInForeach($value, $foreach)) { - continue; - } - - $removedKeys[] = $key; - } - - if (! $this->isArrayItemsRemovalWithoutChangingOrder($list, $removedKeys)) { - return null; - } - - // clear removed items - foreach ($removedKeys as $removedKey) { - unset($list->items[$removedKey]); - } - - return $list; - } - - private function isVariableUsedInForeach(Variable $variable, Foreach_ $foreach): bool - { - return (bool) $this->betterNodeFinder->findFirst( - $foreach->stmts, - fn (Node $node): bool => $this->exprUsedInNodeAnalyzer->isUsed($node, $variable) - ); - } - - private function removeForeachValueAndUseArrayKeys(Foreach_ $foreach, Expr $keyVarExpr): void - { - // remove key value - $foreach->valueVar = $keyVarExpr; - $foreach->keyVar = null; - - $foreach->expr = $this->nodeFactory->createFuncCall('array_keys', [$foreach->expr]); + throw new ShouldNotHappenException(sprintf( + '"%s" rule is deprecated, as it is a personal preference that makes foreach harder to read and extend', + self::class + )); } } diff --git a/src/Config/Level/CodeQualityLevel.php b/src/Config/Level/CodeQualityLevel.php index 183585058b8..3265c4da8d4 100644 --- a/src/Config/Level/CodeQualityLevel.php +++ b/src/Config/Level/CodeQualityLevel.php @@ -32,7 +32,6 @@ use Rector\CodeQuality\Rector\Foreach_\ForeachItemsAssignToEmptyArrayToAssignRector; use Rector\CodeQuality\Rector\Foreach_\ForeachToInArrayRector; use Rector\CodeQuality\Rector\Foreach_\SimplifyForeachToCoalescingRector; -use Rector\CodeQuality\Rector\Foreach_\UnusedForeachValueToArrayKeysRector; use Rector\CodeQuality\Rector\FuncCall\ArrayMergeOfNonArraysToSimpleArrayRector; use Rector\CodeQuality\Rector\FuncCall\CallUserFuncWithArrowFunctionToInlineRector; use Rector\CodeQuality\Rector\FuncCall\ChangeArrayPushToArrayAssignRector; @@ -148,7 +147,6 @@ final class CodeQualityLevel ChangeArrayPushToArrayAssignRector::class, ForRepeatedCountToOwnVariableRector::class, ForeachItemsAssignToEmptyArrayToAssignRector::class, - UnusedForeachValueToArrayKeysRector::class, CommonNotEqualRector::class, SetTypeToCastRector::class, LogicalToBooleanRector::class,