Add NodeRemovingCommander

This commit is contained in:
Tomas Votruba 2018-11-07 21:26:48 +01:00
parent bf37049776
commit b62c31bcad
8 changed files with 87 additions and 120 deletions

View File

@ -52,7 +52,6 @@ final class SimplifyStrposLowerRector extends AbstractRector
// pop 1 level up
$node->args[0] = $innerFuncCall->args[0];
$node->name = new Name('stripos');
return $node;

View File

@ -82,7 +82,7 @@ CODE_SAMPLE
return $node;
}
return $node;
return null;
}
private function matchUselessClosureFuncCallName(Closure $closureNode): ?string

View File

@ -3,7 +3,6 @@
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_;
@ -79,9 +78,6 @@ final class DualCheckToAble
return null;
}
$funcCallNode = new FuncCall(new Name($newMethodName));
$funcCallNode->args[0] = new Arg($firstVarNode);
return $funcCallNode;
return new FuncCall(new Name($newMethodName), [$firstVarNode]);
}
}

View File

@ -78,7 +78,6 @@ CODE_SAMPLE
/** @var FuncCall $eachFuncCall */
$eachFuncCall = $assignNode->expr;
$eachFuncCall->args[0];
/** @var List_ $listNode */
$listNode = $assignNode->var;

View File

@ -0,0 +1,75 @@
<?php declare(strict_types=1);
namespace Rector\PhpParser\Node\Commander;
use PhpParser\Node;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;
use Rector\NodeTypeResolver\Node\Attribute;
final class NodeRemovingCommander
{
/**
* @var Stmt[]
*/
private $nodesToRemove = [];
public function addNode(Node $node): void
{
if (! $node instanceof Expression && ($node->getAttribute(Attribute::PARENT_NODE) instanceof Expression)) {
// only expressions can be removed
$node = $node->getAttribute(Attribute::PARENT_NODE);
}
$this->nodesToRemove[] = $node;
}
/**
* @param Node[] $nodes
* @return Node[]
*/
public function traverseNodes(array $nodes): array
{
if ($this->nodesToRemove === []) {
return $nodes;
}
$nodeTraverser = new NodeTraverser();
$nodeTraverser->addVisitor(new class($this->nodesToRemove) extends NodeVisitorAbstract {
/**
* @var Stmt[]
*/
private $nodesToRemove = [];
/**
* @param Stmt[]
*/
public function __construct(array $nodesToRemove)
{
$this->nodesToRemove = $nodesToRemove;
}
/**
* @return int|Node|Node[]|null
*/
public function leaveNode(Node $node)
{
foreach ($this->nodesToRemove as $key => $nodeToRemove) {
if ($node === $nodeToRemove) {
unset($this->nodesToRemove[$key]);
return NodeTraverser::REMOVE_NODE;
}
}
return $node;
}
});
// new nodes to remove are always per traverse
$this->nodesToRemove = [];
return $nodeTraverser->traverse($nodes);
}
}

View File

@ -1,40 +0,0 @@
<?php declare(strict_types=1);
namespace Rector\PhpParser\NodeVisitor;
use PhpParser\Node;
final class RemovedNodesCollector
{
/**
* @var Node[]
*/
private $nodes = [];
public function addNode(Node $node): void
{
$this->nodes[] = $node;
}
public function removeNode(Node $nodeToRemove): void
{
foreach ($this->nodes as $key => $node) {
if ($node !== $nodeToRemove) {
continue;
}
unset($this->nodes[$key]);
return;
}
}
public function getNodesCount(): int
{
return count($this->nodes);
}
public function hasNode(Node $node): bool
{
return in_array($node, $this->nodes, true);
}
}

View File

@ -1,44 +0,0 @@
<?php declare(strict_types=1);
namespace Rector\PhpParser\NodeVisitor;
use PhpParser\Node;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;
final class RemovingNodeVisitor extends NodeVisitorAbstract
{
/**
* @var RemovedNodesCollector
*/
private $removedNodesCollector;
public function __construct(RemovedNodesCollector $removedNodesCollector)
{
$this->removedNodesCollector = $removedNodesCollector;
}
/**
* @param Node[] $nodes
*/
public function beforeTraverse(array $nodes): void
{
// to improve performance
if (! $this->removedNodesCollector->getNodesCount()) {
return;
}
}
/**
* @return int|Node|Node[]|null
*/
public function leaveNode(Node $node)
{
if (! $this->removedNodesCollector->hasNode($node)) {
return $node;
}
$this->removedNodesCollector->removeNode($node);
return NodeTraverser::REMOVE_NODE;
}
}

View File

@ -3,11 +3,7 @@
namespace Rector\Rector;
use PhpParser\Node;
use PhpParser\Node\Stmt\Expression;
use PhpParser\NodeTraverser;
use Rector\NodeTypeResolver\Node\Attribute;
use Rector\PhpParser\NodeVisitor\RemovedNodesCollector;
use Rector\PhpParser\NodeVisitor\RemovingNodeVisitor;
use Rector\PhpParser\Node\Commander\NodeRemovingCommander;
/**
* This could be part of @see AbstractRector, but decopuling to trait
@ -16,43 +12,29 @@ use Rector\PhpParser\NodeVisitor\RemovingNodeVisitor;
trait RemovingTrait
{
/**
* @var RemovedNodesCollector
* @var NodeRemovingCommander
*/
private $removedNodesCollector;
/**
* @var NodeTraverser
*/
private $removingNodeTraverser;
private $nodeRemovingCommander;
/**
* @required
*/
public function setRemovingTraitDependencies(
RemovedNodesCollector $removedNodesCollector,
RemovingNodeVisitor $removingNodeVisitor
): void {
$this->removedNodesCollector = $removedNodesCollector;
$this->removingNodeTraverser = new NodeTraverser();
$this->removingNodeTraverser->addVisitor($removingNodeVisitor);
public function setNodeRemovingCommander(NodeRemovingCommander $nodeRemovingCommander): void
{
$this->nodeRemovingCommander = $nodeRemovingCommander;
}
public function removeNode(Node $node): void
protected function removeNode(Node $node): void
{
if (! $node instanceof Expression && $node->getAttribute(Attribute::PARENT_NODE) instanceof Expression) {
$node = $node->getAttribute(Attribute::PARENT_NODE);
}
$this->removedNodesCollector->addNode($node);
$this->nodeRemovingCommander->addNode($node);
}
/**
* @param Node[] $nodes
* @return Node[]
*/
public function removeFromNodes(array $nodes): array
protected function removeFromNodes(array $nodes): array
{
return $this->removingNodeTraverser->traverse($nodes);
return $this->nodeRemovingCommander->traverseNodes($nodes);
}
}