From 6336ffc41dfb99a08a6229768634312866ee2bf4 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 12 Jun 2025 16:25:45 +0200 Subject: [PATCH] [typed-collections] Add RemoveIfCollectionIdenticalToNullRector --- config/sets/typed-collections.php | 2 + .../Fixture/skip_and.php.inc | 19 ++++ .../Fixture/some_if.php.inc | 43 +++++++ ...eIfCollectionIdenticalToNullRectorTest.php | 28 +++++ .../config/configured_rule.php | 10 ++ ...emoveIfCollectionIdenticalToNullRector.php | 106 ++++++++++++++++++ 6 files changed, 208 insertions(+) create mode 100644 rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/Fixture/skip_and.php.inc create mode 100644 rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/Fixture/some_if.php.inc create mode 100644 rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/RemoveIfCollectionIdenticalToNullRectorTest.php create mode 100644 rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/config/configured_rule.php create mode 100644 rules/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector.php diff --git a/config/sets/typed-collections.php b/config/sets/typed-collections.php index f89eb7bf..970de922 100644 --- a/config/sets/typed-collections.php +++ b/config/sets/typed-collections.php @@ -26,6 +26,7 @@ use Rector\Doctrine\TypedCollections\Rector\FuncCall\ArrayMapOnCollectionToArrayRector; use Rector\Doctrine\TypedCollections\Rector\FuncCall\ArrayMergeOnCollectionToArrayRector; use Rector\Doctrine\TypedCollections\Rector\FuncCall\InArrayOnCollectionToContainsCallRector; +use Rector\Doctrine\TypedCollections\Rector\If_\RemoveIfCollectionIdenticalToNullRector; use Rector\Doctrine\TypedCollections\Rector\If_\RemoveIfInstanceofCollectionRector; use Rector\Doctrine\TypedCollections\Rector\If_\RemoveIsArrayOnCollectionRector; use Rector\Doctrine\TypedCollections\Rector\MethodCall\AssertNullOnCollectionToAssertEmptyRector; @@ -45,6 +46,7 @@ RemoveCoalesceAssignOnCollectionRector::class, RemoveIfInstanceofCollectionRector::class, RemoveIsArrayOnCollectionRector::class, + RemoveIfCollectionIdenticalToNullRector::class, // collection method calls ArrayDimFetchAssignToAddCollectionCallRector::class, diff --git a/rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/Fixture/skip_and.php.inc b/rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/Fixture/skip_and.php.inc new file mode 100644 index 00000000..4eb05330 --- /dev/null +++ b/rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/Fixture/skip_and.php.inc @@ -0,0 +1,19 @@ +items === null && $this->items->isEmpty()) { + return true; + } + + return false; + } +} diff --git a/rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/Fixture/some_if.php.inc b/rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/Fixture/some_if.php.inc new file mode 100644 index 00000000..85820ebe --- /dev/null +++ b/rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/Fixture/some_if.php.inc @@ -0,0 +1,43 @@ +items === null || $this->items->isEmpty()) { + return true; + } + + return false; + } +} + +?> +----- +items->isEmpty()) { + return true; + } + + return false; + } +} + +?> diff --git a/rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/RemoveIfCollectionIdenticalToNullRectorTest.php b/rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/RemoveIfCollectionIdenticalToNullRectorTest.php new file mode 100644 index 00000000..c71565ea --- /dev/null +++ b/rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/RemoveIfCollectionIdenticalToNullRectorTest.php @@ -0,0 +1,28 @@ +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/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/config/configured_rule.php b/rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/config/configured_rule.php new file mode 100644 index 00000000..d952c056 --- /dev/null +++ b/rules-tests/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(RemoveIfCollectionIdenticalToNullRector::class); +}; diff --git a/rules/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector.php b/rules/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector.php new file mode 100644 index 00000000..9d74a591 --- /dev/null +++ b/rules/TypedCollections/Rector/If_/RemoveIfCollectionIdenticalToNullRector.php @@ -0,0 +1,106 @@ +cond instanceof BooleanOr) { + return null; + } + + $leftCondition = $node->cond->left; + if (! $leftCondition instanceof Identical) { + return null; + } + + if (! $leftCondition->right instanceof ConstFetch || ! $this->isName( + $leftCondition->right->name, + 'null' + )) { + return null; + } + + if (! $this->collectionTypeDetector->isCollectionType($leftCondition->left)) { + return null; + } + + $rightCondition = $node->cond->right; + + $node->cond = $rightCondition; + + return $node; + } + + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition('Remove collection identical to null from if || condition', [ + new CodeSample( + <<<'CODE_SAMPLE' +use Doctrine\Common\Collections\Collection; + +final class SomeClass +{ + private Collection $collection; + + public function someMethod() + { + if ($this->collection === null || $this->collection->isEmpty()) { + return true; + } + + return false; + } +} +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +use Doctrine\Common\Collections\Collection; + +final class SomeClass +{ + private Collection $collection; + + public function someMethod() + { + if ($this->collection->isEmpty()) { + return true; + } + + return false; + } +} +CODE_SAMPLE + )]); + } +}