decouple IsAbleRector for is_countable and is_iterable abstraction

This commit is contained in:
TomasVotruba 2020-05-05 13:36:06 +02:00
parent e8ac877527
commit ec3a84e8d3
6 changed files with 90 additions and 87 deletions

View File

@ -102,6 +102,7 @@
"Rector\\Php55\\": "rules/php55/src",
"Rector\\Php56\\": "rules/php56/src",
"Rector\\Php70\\": "rules/php70/src",
"Rector\\Php\\": "rules/php/src",
"Rector\\Php71\\": "rules/php71/src",
"Rector\\Php72\\": "rules/php72/src",
"Rector\\Php73\\": "rules/php73/src",

View File

@ -0,0 +1,62 @@
<?php
declare(strict_types=1);
namespace Rector\Php\Rector;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use Rector\Core\Rector\AbstractRector;
use Rector\Php71\IsArrayAndDualCheckToAble;
abstract class AbstractIsAbleRector extends AbstractRector
{
/**
* @var IsArrayAndDualCheckToAble
*/
private $isArrayAndDualCheckToAble;
public function __construct(IsArrayAndDualCheckToAble $isArrayAndDualCheckToAble)
{
$this->isArrayAndDualCheckToAble = $isArrayAndDualCheckToAble;
}
/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [BooleanOr::class];
}
/**
* @param BooleanOr $node
*/
public function refactor(Node $node): ?Node
{
if ($this->shouldSkip()) {
return null;
}
return $this->isArrayAndDualCheckToAble->processBooleanOr(
$node,
$this->getType(),
$this->getFuncName()
) ?: $node;
}
abstract protected function getFuncName(): string;
abstract protected function getPhpVersion(): string;
abstract protected function getType(): string;
private function shouldSkip(): bool
{
if (function_exists($this->getFuncName())) {
return false;
}
return $this->isAtLeastPhpVersion($this->getPhpVersion());
}
}

View File

@ -4,72 +4,35 @@ declare(strict_types=1);
namespace Rector\Php71\Rector\BinaryOp;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\Php71\IsArrayAndDualCheckToAble;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\Php\Rector\AbstractIsAbleRector;
/**
* @see \Rector\Php71\Tests\Rector\BinaryOp\IsIterableRector\IsIterableRectorTest
*/
final class IsIterableRector extends AbstractRector
final class IsIterableRector extends AbstractIsAbleRector
{
/**
* @var IsArrayAndDualCheckToAble
*/
private $isArrayAndDualCheckToAble;
public function __construct(IsArrayAndDualCheckToAble $isArrayAndDualCheckToAble)
{
$this->isArrayAndDualCheckToAble = $isArrayAndDualCheckToAble;
}
public function getDefinition(): RectorDefinition
{
return new RectorDefinition(
'Changes is_array + Traversable check to is_iterable',
[
new CodeSample(
<<<'PHP'
is_array($foo) || $foo instanceof Traversable;
PHP
,
<<<'PHP'
is_iterable($foo);
PHP
),
]
);
return new RectorDefinition('Changes is_array + Traversable check to is_iterable', [
new CodeSample('is_array($foo) || $foo instanceof Traversable;', 'is_iterable($foo);'),
]);
}
/**
* @return string[]
*/
public function getNodeTypes(): array
protected function getFuncName(): string
{
return [BooleanOr::class];
return 'is_iterable';
}
/**
* @param BooleanOr $node
*/
public function refactor(Node $node): ?Node
protected function getPhpVersion(): string
{
if ($this->shouldSkip()) {
return null;
}
return $this->isArrayAndDualCheckToAble->processBooleanOr($node, 'Traversable', 'is_iterable') ?: $node;
return PhpVersionFeature::IS_ITERABLE;
}
private function shouldSkip(): bool
protected function getType(): string
{
if (function_exists('is_iterable')) {
return false;
}
return $this->isAtLeastPhpVersion('7.1');
return 'Traversable';
}
}

View File

@ -4,28 +4,16 @@ declare(strict_types=1);
namespace Rector\Php73\Rector\BinaryOp;
use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\Php71\IsArrayAndDualCheckToAble;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\Php\Rector\AbstractIsAbleRector;
/**
* @see \Rector\Php73\Tests\Rector\BinaryOp\IsCountableRector\IsCountableRectorTest
*/
final class IsCountableRector extends AbstractRector
final class IsCountableRector extends AbstractIsAbleRector
{
/**
* @var IsArrayAndDualCheckToAble
*/
private $isArrayAndDualCheckToAble;
public function __construct(IsArrayAndDualCheckToAble $isArrayAndDualCheckToAble)
{
$this->isArrayAndDualCheckToAble = $isArrayAndDualCheckToAble;
}
public function getDefinition(): RectorDefinition
{
return new RectorDefinition(
@ -44,32 +32,18 @@ PHP
);
}
/**
* @return string[]
*/
public function getNodeTypes(): array
protected function getType(): string
{
return [BooleanOr::class];
return 'Countable';
}
/**
* @param BooleanOr $node
*/
public function refactor(Node $node): ?Node
protected function getFuncName(): string
{
if ($this->shouldSkip()) {
return null;
}
return $this->isArrayAndDualCheckToAble->processBooleanOr($node, 'Countable', 'is_countable') ?: $node;
return 'is_countable';
}
private function shouldSkip(): bool
protected function getPhpVersion(): string
{
if (function_exists('is_countable')) {
return false;
}
return $this->isAtLeastPhpVersion('7.3');
return PhpVersionFeature::IS_COUNTABLE;
}
}

View File

@ -105,9 +105,7 @@ PHP
$dataProviderTags = $phpDocInfo->getTagsByName('dataProvider');
dump($dataProviderTags);
die;
// @todo
if ($dataProviderTags === []) {
continue;
}

View File

@ -161,4 +161,9 @@ final class PhpVersionFeature
* @var string
*/
public const STATIC_RETURN_TYPE = '8.0';
/**
* @var string
*/
public const IS_ITERABLE = '7.1';
}