diff --git a/packages/Php/src/Rector/FuncCall/CountOnNullRector.php b/packages/Php/src/Rector/FuncCall/CountOnNullRector.php index 6db49edffde4..78d58986a336 100644 --- a/packages/Php/src/Rector/FuncCall/CountOnNullRector.php +++ b/packages/Php/src/Rector/FuncCall/CountOnNullRector.php @@ -57,17 +57,7 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - if (! $this->isName($node, 'count')) { - return null; - } - - // check if it has some condition before already, if so, probably it's already handled - if ($node->getAttribute(self::ALREADY_CHANGED_ON_COUNT)) { - return null; - } - - $parentNode = $node->getAttribute(AttributeKey::PARENT_NODE); - if ($parentNode instanceof Ternary) { + if ($this->shouldSkip($node)) { return null; } @@ -82,14 +72,16 @@ public function refactor(Node $node): ?Node if ($this->isNullType($countedNode)) { $identicalNode = new Identical($countedNode, $this->createNull()); - $node->setAttribute(self::ALREADY_CHANGED_ON_COUNT, true); - $ternaryNode = new Ternary($identicalNode, new LNumber(0), $node); } else { - $conditionNode = new BooleanOr( - $this->createFunction('is_array', [new Arg($countedNode)]), - new Instanceof_($countedNode, new FullyQualified('Countable')) - ); + if ($this->isAtLeastPhpVersion('7.3')) { + $conditionNode = new FuncCall(new Node\Name('is_countable'), [new Arg($countedNode)]); + } else { + $conditionNode = new BooleanOr( + $this->createFunction('is_array', [new Arg($countedNode)]), + new Instanceof_($countedNode, new FullyQualified('Countable')) + ); + } $ternaryNode = new Ternary($conditionNode, $node, new LNumber(0)); } @@ -99,4 +91,20 @@ public function refactor(Node $node): ?Node return $ternaryNode; } + + private function shouldSkip(FuncCall $funcCall): bool + { + if (! $this->isName($funcCall, 'count')) { + return true; + } + + // check if it has some condition before already, if so, probably it's already handled + if ($funcCall->getAttribute(self::ALREADY_CHANGED_ON_COUNT)) { + return true; + } + + $parentNode = $funcCall->getAttribute(AttributeKey::PARENT_NODE); + + return $parentNode instanceof Ternary; + } } diff --git a/packages/Php/tests/Rector/FuncCall/CountOnNullRector/CountOnNullRectorTest.php b/packages/Php/tests/Rector/FuncCall/CountOnNullRector/CountOnNullRectorTest.php index 5ca4bcd3b8ea..b711160db2ef 100644 --- a/packages/Php/tests/Rector/FuncCall/CountOnNullRector/CountOnNullRectorTest.php +++ b/packages/Php/tests/Rector/FuncCall/CountOnNullRector/CountOnNullRectorTest.php @@ -2,9 +2,11 @@ namespace Rector\Php\Tests\Rector\FuncCall\CountOnNullRector; -use Rector\Php\Rector\FuncCall\CountOnNullRector; use Rector\Testing\PHPUnit\AbstractRectorTestCase; +/** + * @covers \Rector\Php\Rector\FuncCall\CountOnNullRector + */ final class CountOnNullRectorTest extends AbstractRectorTestCase { public function test(): void @@ -21,8 +23,8 @@ public function test(): void ]); } - protected function getRectorClass(): string + protected function provideConfig(): string { - return CountOnNullRector::class; + return __DIR__ . '/rector_with_php71.yaml'; } } diff --git a/packages/Php/tests/Rector/FuncCall/CountOnNullRector/CountOnNullRectorWithPHP73Test.php b/packages/Php/tests/Rector/FuncCall/CountOnNullRector/CountOnNullRectorWithPHP73Test.php new file mode 100644 index 000000000000..113b32478a0f --- /dev/null +++ b/packages/Php/tests/Rector/FuncCall/CountOnNullRector/CountOnNullRectorWithPHP73Test.php @@ -0,0 +1,21 @@ +doTestFiles([__DIR__ . '/Fixture/is_countable.php.inc']); + } + + protected function provideConfig(): string + { + return __DIR__ . '/rector_with_php73.yaml'; + } +} diff --git a/packages/Php/tests/Rector/FuncCall/CountOnNullRector/Fixture/is_countable.php.inc b/packages/Php/tests/Rector/FuncCall/CountOnNullRector/Fixture/is_countable.php.inc new file mode 100644 index 000000000000..dcc07fdcc691 --- /dev/null +++ b/packages/Php/tests/Rector/FuncCall/CountOnNullRector/Fixture/is_countable.php.inc @@ -0,0 +1,27 @@ + +----- + diff --git a/packages/Php/tests/Rector/FuncCall/CountOnNullRector/rector_with_php71.yaml b/packages/Php/tests/Rector/FuncCall/CountOnNullRector/rector_with_php71.yaml new file mode 100644 index 000000000000..a836ab78c154 --- /dev/null +++ b/packages/Php/tests/Rector/FuncCall/CountOnNullRector/rector_with_php71.yaml @@ -0,0 +1,5 @@ +parameters: + php_version_features: '7.1' + +services: + Rector\Php\Rector\FuncCall\CountOnNullRector: ~ diff --git a/packages/Php/tests/Rector/FuncCall/CountOnNullRector/rector_with_php73.yaml b/packages/Php/tests/Rector/FuncCall/CountOnNullRector/rector_with_php73.yaml new file mode 100644 index 000000000000..0487ae1e8a04 --- /dev/null +++ b/packages/Php/tests/Rector/FuncCall/CountOnNullRector/rector_with_php73.yaml @@ -0,0 +1,5 @@ +parameters: + php_version_features: '7.3' + +services: + Rector\Php\Rector\FuncCall\CountOnNullRector: ~ diff --git a/src/Php/PhpVersionProvider.php b/src/Php/PhpVersionProvider.php index 332d41722bbc..f28ff7f1969a 100644 --- a/src/Php/PhpVersionProvider.php +++ b/src/Php/PhpVersionProvider.php @@ -16,15 +16,15 @@ public function __construct(?string $phpVersionFeatures) public function provide(): string { + if ($this->phpVersionFeatures) { + return $this->phpVersionFeatures; + } + // for tests if (defined('PHPUNIT_COMPOSER_INSTALL') || defined('__PHPUNIT_PHAR__')) { return '7.5'; } - if ($this->phpVersionFeatures) { - return $this->phpVersionFeatures; - } - return PHP_VERSION; }