make use of BinaryOpMaintainer

This commit is contained in:
Tomas Votruba 2018-11-07 18:04:38 +01:00
parent dbdf01bf0d
commit 71824ab33c
4 changed files with 97 additions and 67 deletions

View File

@ -11,12 +11,23 @@ use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Instanceof_;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\String_;
use Rector\PhpParser\Node\Maintainer\BinaryOpMaintainer;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
final class GetClassToInstanceOfRector extends AbstractRector
{
/**
* @var BinaryOpMaintainer
*/
private $binaryOpMaintainer;
public function __construct(BinaryOpMaintainer $binaryOpMaintainer)
{
$this->binaryOpMaintainer = $binaryOpMaintainer;
}
public function getDefinition(): RectorDefinition
{
return new RectorDefinition(
@ -43,22 +54,27 @@ final class GetClassToInstanceOfRector extends AbstractRector
*/
public function refactor(Node $node): ?Node
{
if ($this->isClassReference($node->left) && $this->isGetClassFuncCallNode($node->right)) {
/** @var FuncCall $funcCallNode */
$funcCallNode = $node->right;
$varNode = $funcCallNode->args[0]->value;
$matchedNodes = $this->binaryOpMaintainer->matchFirstAndSecondConditionNode(
$node,
function (Node $node) {
return $this->isClassReference($node);
},
function (Node $node) {
return $this->isGetClassFuncCallNode($node);
}
);
$className = $this->matchClassName($node->left);
} elseif ($this->isClassReference($node->right) && $this->isGetClassFuncCallNode($node->left)) {
/** @var FuncCall $funcCallNode */
$funcCallNode = $node->left;
$varNode = $funcCallNode->args[0]->value;
$className = $this->matchClassName($node->right);
} else {
if ($matchedNodes === null) {
return null;
}
/** @var ClassConstFetch $classReferenceNode */
/** @var FuncCall $funcCallNode */
[$classReferenceNode, $funcCallNode] = $matchedNodes;
$varNode = $funcCallNode->args[0]->value;
$className = $this->matchClassName($classReferenceNode);
$instanceOfNode = new Instanceof_($varNode, new FullyQualified($className));
if ($node instanceof NotIdentical) {
return new BooleanNot($instanceOfNode);

View File

@ -9,12 +9,23 @@ use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\FuncCall;
use Rector\PhpParser\Node\Maintainer\BinaryOpMaintainer;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
final class SimplifyArraySearchRector extends AbstractRector
{
/**
* @var BinaryOpMaintainer
*/
private $binaryOpMaintainer;
public function __construct(BinaryOpMaintainer $binaryOpMaintainer)
{
$this->binaryOpMaintainer = $binaryOpMaintainer;
}
public function getDefinition(): RectorDefinition
{
return new RectorDefinition(
@ -41,12 +52,23 @@ final class SimplifyArraySearchRector extends AbstractRector
*/
public function refactor(Node $node): ?Node
{
$match = $this->matchArraySearchFuncCallAndBoolConstFetch($node);
if ($match === null) {
$matchedNodes = $this->binaryOpMaintainer->matchFirstAndSecondConditionNode(
$node,
function (Node $node) {
return $node instanceof FuncCall && $this->isName($node, 'array_search');
},
function (Node $node) {
return $this->isBool($node);
}
);
if ($matchedNodes === null) {
return null;
}
[$arraySearchFuncCallNode, $boolConstFetchNode] = $match;
/** @var FuncCall $arraySearchFuncCallNode */
/** @var ConstFetch $boolConstFetchNode */
[$arraySearchFuncCallNode, $boolConstFetchNode] = $matchedNodes;
$inArrayFuncCall = $this->createFunction('in_array', [
$arraySearchFuncCallNode->args[0],
@ -60,28 +82,6 @@ final class SimplifyArraySearchRector extends AbstractRector
return $inArrayFuncCall;
}
/**
* @return ConstFetch[]|FuncCall[]
*/
private function matchArraySearchFuncCallAndBoolConstFetch(BinaryOp $binaryOpNode): ?array
{
if ($this->isName($binaryOpNode->left, 'array_search') &&
$this->isBool($binaryOpNode->right)
) {
$arraySearchFuncCallNode = $binaryOpNode->left;
$boolConstFetchNode = $binaryOpNode->right;
} elseif ($this->isBool($binaryOpNode->left) &&
$this->isName($binaryOpNode->right, 'array_search')
) {
$arraySearchFuncCallNode = $binaryOpNode->right;
$boolConstFetchNode = $binaryOpNode->left;
} else {
return null;
}
return [$arraySearchFuncCallNode, $boolConstFetchNode];
}
private function resolveIsNot(BinaryOp $node, ConstFetch $boolConstFetchNode): bool
{
if ($node instanceof Identical) {

View File

@ -9,6 +9,7 @@ use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\BooleanNot;
use Rector\PhpParser\Node\AssignAndBinaryMap;
use Rector\PhpParser\Node\Maintainer\BinaryOpMaintainer;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
@ -20,9 +21,15 @@ final class SimplifyConditionsRector extends AbstractRector
*/
private $assignAndBinaryMap;
public function __construct(AssignAndBinaryMap $assignAndBinaryMap)
/**
* @var BinaryOpMaintainer
*/
private $binaryOpMaintainer;
public function __construct(AssignAndBinaryMap $assignAndBinaryMap, BinaryOpMaintainer $binaryOpMaintainer)
{
$this->assignAndBinaryMap = $assignAndBinaryMap;
$this->binaryOpMaintainer = $binaryOpMaintainer;
}
public function getDefinition(): RectorDefinition
@ -72,17 +79,23 @@ final class SimplifyConditionsRector extends AbstractRector
private function processIdenticalAndNotIdentical(BinaryOp $node): ?Node
{
if ($node->left instanceof Identical || $node->left instanceof NotIdentical) {
$subBinaryOpNode = $node->left;
$shouldInverse = $this->isFalse($node->right);
} elseif ($node->right instanceof Identical || $node->right instanceof NotIdentical) {
$subBinaryOpNode = $node->right;
$shouldInverse = $this->isFalse($node->left);
} else {
return null;
$matchedNodes = $this->binaryOpMaintainer->matchFirstAndSecondConditionNode(
$node,
function (Node $node) {
return $node instanceof Identical || $node instanceof NotIdentical;
},
function (Node $node) {
return $node;
}
);
if ($matchedNodes === null) {
return $matchedNodes;
}
if ($shouldInverse) {
/** @var Identical|NotIdentical $subBinaryOpNode */
[$subBinaryOpNode, $otherNode] = $matchedNodes;
if ($this->isFalse($otherNode)) {
return $this->createInversedBooleanOp($subBinaryOpNode);
}

View File

@ -2,12 +2,14 @@
namespace Rector\Php;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Instanceof_;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name;
use Rector\PhpParser\Node\Maintainer\BinaryOpMaintainer;
use Rector\PhpParser\Node\Resolver\NameResolver;
final class DualCheckToAble
@ -17,19 +19,34 @@ final class DualCheckToAble
*/
private $nameResolver;
public function __construct(NameResolver $nameResolver)
/**
* @var BinaryOpMaintainer
*/
private $binaryOpMaintainer;
public function __construct(NameResolver $nameResolver, BinaryOpMaintainer $binaryOpMaintainer)
{
$this->nameResolver = $nameResolver;
$this->binaryOpMaintainer = $binaryOpMaintainer;
}
public function processBooleanOr(BooleanOr $booleanOrNode, string $type, string $newMethodName): ?FuncCall
{
$split = $this->splitToInstanceOfAndFuncCall($booleanOrNode);
if ($split === null) {
$matchedNodes = $this->binaryOpMaintainer->matchFirstAndSecondConditionNode(
$booleanOrNode,
function (Node $node) {
return $node instanceof Instanceof_;
},
function (Node $node) {
return $node instanceof FuncCall;
}
);
if ($matchedNodes === null) {
return null;
}
[$instanceOfNode, $funcCallNode] = $split;
[$instanceOfNode, $funcCallNode] = $matchedNodes;
/** @var Instanceof_ $instanceOfNode */
if ((string) $instanceOfNode->class !== $type) {
@ -66,20 +83,4 @@ final class DualCheckToAble
return $funcCallNode;
}
/**
* @return Instanceof_[]|FuncCall[]
*/
private function splitToInstanceOfAndFuncCall(BooleanOr $booleanOrNode): ?array
{
if ($booleanOrNode->left instanceof Instanceof_ && $booleanOrNode->right instanceof FuncCall) {
return [$booleanOrNode->left, $booleanOrNode->right];
}
if ($booleanOrNode->right instanceof Instanceof_ && $booleanOrNode->left instanceof FuncCall) {
return [$booleanOrNode->right, $booleanOrNode->left];
}
return null;
}
}