mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-18 14:03:41 +01:00
Merge pull request #928 from rectorphp/code-style
[CodingStyle] Add SetTypeToCastRector
This commit is contained in:
commit
392d444862
@ -4,3 +4,5 @@ services:
|
||||
Rector\CodingStyle\Rector\FuncCall\SimpleArrayCallableToStringRector: ~
|
||||
Rector\CodingStyle\Rector\Identical\IdenticalFalseToBooleanNotRector: ~
|
||||
Rector\CodingStyle\Rector\Switch_\BinarySwitchToIfElseRector: ~
|
||||
Rector\CodingStyle\Rector\FuncCall\ConsistentImplodeRector: ~
|
||||
Rector\CodingStyle\Rector\FuncCall\SetTypeToCastRector: ~
|
||||
|
124
packages/CodingStyle/src/Rector/FuncCall/SetTypeToCastRector.php
Normal file
124
packages/CodingStyle/src/Rector/FuncCall/SetTypeToCastRector.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\CodingStyle\Rector\FuncCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\Cast\Array_;
|
||||
use PhpParser\Node\Expr\Cast\Bool_;
|
||||
use PhpParser\Node\Expr\Cast\Double;
|
||||
use PhpParser\Node\Expr\Cast\Int_;
|
||||
use PhpParser\Node\Expr\Cast\Object_;
|
||||
use PhpParser\Node\Expr\Cast\String_;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use Rector\NodeTypeResolver\Node\Attribute;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
|
||||
/**
|
||||
* @see https://stackoverflow.com/questions/5577003/using-settype-in-php-instead-of-typecasting-using-brackets-what-is-the-differen/5577068#5577068
|
||||
* @see https://github.com/FriendsOfPHP/PHP-CS-Fixer/pull/3709
|
||||
*/
|
||||
final class SetTypeToCastRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private const TYPE_TO_CAST = [
|
||||
'array' => Array_::class,
|
||||
'bool' => Bool_::class,
|
||||
'boolean' => Bool_::class,
|
||||
'double' => Double::class,
|
||||
'float' => Double::class,
|
||||
'int' => Int_::class,
|
||||
'integer' => Int_::class,
|
||||
'object' => Object_::class,
|
||||
'string' => String_::class,
|
||||
];
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Changes settype() to (type) where possible', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run($foo)
|
||||
{
|
||||
settype($foo, 'string');
|
||||
|
||||
return settype($foo, 'integer');
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run(array $items)
|
||||
{
|
||||
$foo = (string) $foo;
|
||||
|
||||
return (int) $foo;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [FuncCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FuncCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->isName($node, 'settype')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$typeNode = $this->getValue($node->args[1]->value);
|
||||
if ($typeNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$typeNode = strtolower($typeNode);
|
||||
|
||||
$varNode = $node->args[0]->value;
|
||||
$parentNode = $node->getAttribute(Attribute::PARENT_NODE);
|
||||
|
||||
// result of function or probably used
|
||||
if ($parentNode instanceof Expr || $parentNode instanceof Arg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isset(self::TYPE_TO_CAST[$typeNode])) {
|
||||
$castClass = self::TYPE_TO_CAST[$typeNode];
|
||||
$castNode = new $castClass($varNode);
|
||||
|
||||
if ($parentNode instanceof Expression) {
|
||||
// bare expression? → assign
|
||||
return new Assign($varNode, $castNode);
|
||||
}
|
||||
|
||||
return $castNode;
|
||||
}
|
||||
|
||||
if ($typeNode === 'null') {
|
||||
return new Assign($varNode, $this->createNull());
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\CodingStyle\Tests\Rector\FuncCall\SetTypeToCastRector\Fixture;
|
||||
|
||||
class Assin
|
||||
{
|
||||
public function run($foo)
|
||||
{
|
||||
$result = settype($foo, 'string');
|
||||
|
||||
is_bool(settype($foo, 'string'));
|
||||
|
||||
$result = [settype($foo, 'string')];
|
||||
|
||||
$result = [0 => settype($foo, 'string')];
|
||||
|
||||
settype($foo, settype($foo, 'string'));
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\CodingStyle\Tests\Rector\FuncCall\SetTypeToCastRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run($foo)
|
||||
{
|
||||
settype($foo, 'string');
|
||||
settype($foo, 'array');
|
||||
settype($foo, 'INT');
|
||||
settype($foo, 'float');
|
||||
settype($foo, 'double');
|
||||
settype($foo, 'bool');
|
||||
settype($foo, 'boolean');
|
||||
|
||||
return settype($foo, 'integer');
|
||||
}
|
||||
|
||||
public function null()
|
||||
{
|
||||
settype($foo, 'null');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\CodingStyle\Tests\Rector\FuncCall\SetTypeToCastRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run($foo)
|
||||
{
|
||||
$foo = (string) $foo;
|
||||
$foo = (array) $foo;
|
||||
$foo = (int) $foo;
|
||||
$foo = (double) $foo;
|
||||
$foo = (double) $foo;
|
||||
$foo = (bool) $foo;
|
||||
$foo = (bool) $foo;
|
||||
|
||||
return (int) $foo;
|
||||
}
|
||||
|
||||
public function null()
|
||||
{
|
||||
$foo = null;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,19 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\CodingStyle\Tests\Rector\FuncCall\SetTypeToCastRector;
|
||||
|
||||
use Rector\CodingStyle\Rector\FuncCall\SetTypeToCastRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
|
||||
final class SetTypeToCastRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
public function test(): void
|
||||
{
|
||||
$this->doTestFiles([__DIR__ . '/Fixture/fixture.php.inc', __DIR__ . '/Fixture/assign.php.inc']);
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return SetTypeToCastRector::class;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user