2019-10-13 05:59:52 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
2019-04-03 19:33:48 +00:00
|
|
|
|
|
|
|
namespace Rector\CodeQuality\Rector\Identical;
|
|
|
|
|
|
|
|
use PhpParser\Node;
|
|
|
|
use PhpParser\Node\Expr\BinaryOp\Identical;
|
2019-04-17 19:17:29 +00:00
|
|
|
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
|
|
|
|
use PhpParser\Node\Expr\BooleanNot;
|
2019-09-03 08:01:19 +00:00
|
|
|
use PHPStan\Type\BooleanType;
|
2020-02-06 21:48:18 +00:00
|
|
|
use Rector\Core\Rector\AbstractRector;
|
|
|
|
use Rector\Core\RectorDefinition\CodeSample;
|
|
|
|
use Rector\Core\RectorDefinition\RectorDefinition;
|
2019-04-03 19:33:48 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @see https://3v4l.org/GoEPq
|
2019-09-03 09:11:45 +00:00
|
|
|
* @see \Rector\CodeQuality\Tests\Rector\Identical\BooleanNotIdenticalToNotIdenticalRector\BooleanNotIdenticalToNotIdenticalRectorTest
|
2019-04-03 19:33:48 +00:00
|
|
|
*/
|
|
|
|
final class BooleanNotIdenticalToNotIdenticalRector extends AbstractRector
|
|
|
|
{
|
|
|
|
public function getDefinition(): RectorDefinition
|
|
|
|
{
|
|
|
|
return new RectorDefinition(
|
|
|
|
'Negated identical boolean compare to not identical compare (does not apply to non-bool values)',
|
|
|
|
[
|
|
|
|
new CodeSample(
|
2019-09-18 06:14:35 +00:00
|
|
|
<<<'PHP'
|
2019-04-03 19:33:48 +00:00
|
|
|
class SomeClass
|
|
|
|
{
|
|
|
|
public function run()
|
|
|
|
{
|
|
|
|
$a = true;
|
|
|
|
$b = false;
|
|
|
|
|
|
|
|
var_dump(! $a === $b); // true
|
|
|
|
var_dump(! ($a === $b)); // true
|
|
|
|
var_dump($a !== $b); // true
|
|
|
|
}
|
|
|
|
}
|
2019-09-18 06:14:35 +00:00
|
|
|
PHP
|
2019-04-03 19:33:48 +00:00
|
|
|
,
|
2019-09-18 06:14:35 +00:00
|
|
|
<<<'PHP'
|
2019-04-03 19:33:48 +00:00
|
|
|
class SomeClass
|
|
|
|
{
|
|
|
|
public function run()
|
|
|
|
{
|
|
|
|
$a = true;
|
|
|
|
$b = false;
|
|
|
|
|
|
|
|
var_dump($a !== $b); // true
|
|
|
|
var_dump($a !== $b); // true
|
|
|
|
var_dump($a !== $b); // true
|
|
|
|
}
|
|
|
|
}
|
2019-09-18 06:14:35 +00:00
|
|
|
PHP
|
2019-04-03 19:33:48 +00:00
|
|
|
),
|
|
|
|
]
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string[]
|
|
|
|
*/
|
|
|
|
public function getNodeTypes(): array
|
|
|
|
{
|
2019-04-17 19:17:29 +00:00
|
|
|
return [Identical::class, BooleanNot::class];
|
2019-04-03 19:33:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-04-30 22:49:59 +00:00
|
|
|
* @param Identical|BooleanNot $node
|
2019-04-03 19:33:48 +00:00
|
|
|
*/
|
|
|
|
public function refactor(Node $node): ?Node
|
|
|
|
{
|
|
|
|
if ($node instanceof Identical) {
|
|
|
|
return $this->processIdentical($node);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($node->expr instanceof Identical) {
|
|
|
|
$identical = $node->expr;
|
2019-09-03 08:01:19 +00:00
|
|
|
if (! $this->isStaticType($identical->left, BooleanType::class)) {
|
2019-04-03 19:33:48 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2019-09-03 08:01:19 +00:00
|
|
|
if (! $this->isStaticType($identical->right, BooleanType::class)) {
|
2019-04-03 19:33:48 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2019-04-17 19:17:29 +00:00
|
|
|
return new NotIdentical($identical->left, $identical->right);
|
2019-04-03 19:33:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2019-04-17 19:17:29 +00:00
|
|
|
private function processIdentical(Identical $identical): ?NotIdentical
|
2019-04-03 19:33:48 +00:00
|
|
|
{
|
2019-09-03 08:01:19 +00:00
|
|
|
if (! $this->isStaticType($identical->left, BooleanType::class)) {
|
2019-04-03 19:33:48 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2019-09-03 08:01:19 +00:00
|
|
|
if (! $this->isStaticType($identical->right, BooleanType::class)) {
|
2019-04-03 19:33:48 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2019-04-17 19:17:29 +00:00
|
|
|
if ($identical->left instanceof BooleanNot) {
|
|
|
|
return new NotIdentical($identical->left->expr, $identical->right);
|
2019-04-03 19:33:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|