From 71824ab33c83ba0261c2731af794e37cca2e0f18 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 7 Nov 2018 18:04:38 +0100 Subject: [PATCH] make use of BinaryOpMaintainer --- .../Identical/GetClassToInstanceOfRector.php | 40 ++++++++++----- .../Identical/SimplifyArraySearchRector.php | 50 +++++++++---------- .../Identical/SimplifyConditionsRector.php | 33 ++++++++---- packages/Php/src/DualCheckToAble.php | 41 +++++++-------- 4 files changed, 97 insertions(+), 67 deletions(-) diff --git a/packages/CodeQuality/src/Rector/Identical/GetClassToInstanceOfRector.php b/packages/CodeQuality/src/Rector/Identical/GetClassToInstanceOfRector.php index 7f26bbb4c5a..69053301e55 100644 --- a/packages/CodeQuality/src/Rector/Identical/GetClassToInstanceOfRector.php +++ b/packages/CodeQuality/src/Rector/Identical/GetClassToInstanceOfRector.php @@ -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); diff --git a/packages/CodeQuality/src/Rector/Identical/SimplifyArraySearchRector.php b/packages/CodeQuality/src/Rector/Identical/SimplifyArraySearchRector.php index de4d6b8b739..ea46a990545 100644 --- a/packages/CodeQuality/src/Rector/Identical/SimplifyArraySearchRector.php +++ b/packages/CodeQuality/src/Rector/Identical/SimplifyArraySearchRector.php @@ -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) { diff --git a/packages/CodeQuality/src/Rector/Identical/SimplifyConditionsRector.php b/packages/CodeQuality/src/Rector/Identical/SimplifyConditionsRector.php index ef3e93d6cc2..2e1e10d6108 100644 --- a/packages/CodeQuality/src/Rector/Identical/SimplifyConditionsRector.php +++ b/packages/CodeQuality/src/Rector/Identical/SimplifyConditionsRector.php @@ -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); } diff --git a/packages/Php/src/DualCheckToAble.php b/packages/Php/src/DualCheckToAble.php index d61cfc97b86..ce856a48309 100644 --- a/packages/Php/src/DualCheckToAble.php +++ b/packages/Php/src/DualCheckToAble.php @@ -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; - } }