Skip to content

Commit

Permalink
[Core] Improve performance: remove unnecessary loop on SimpleCallable…
Browse files Browse the repository at this point in the history
…NodeTraverser (#3053)
  • Loading branch information
samsonasik committed Nov 11, 2022
1 parent e28e7a1 commit 21b1ff9
Showing 1 changed file with 17 additions and 39 deletions.
56 changes: 17 additions & 39 deletions packages/PhpDocParser/NodeTraverser/SimpleCallableNodeTraverser.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
namespace Rector\PhpDocParser\NodeTraverser;

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrowFunction;
use PhpParser\Node\Stmt\Return_;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitor\ParentConnectingVisitor;
use Rector\NodeTypeResolver\Node\AttributeKey;
Expand All @@ -20,60 +17,41 @@ final class SimpleCallableNodeTraverser
{
/**
* @param callable(Node $node): (int|Node|null) $callable
* @param Node|Node[]|null $nodes
* @param Node|Node[]|null $node
*/
public function traverseNodesWithCallable(Node | array | null $nodes, callable $callable): void
public function traverseNodesWithCallable(Node | array | null $node, callable $callable): void
{
if ($nodes === null) {
if ($node === null) {
return;
}

if ($nodes === []) {
if ($node === []) {
return;
}

if (! is_array($nodes)) {
$nodes = [$nodes];
}

$nodeTraverser = new NodeTraverser();
$callableNodeVisitor = new CallableNodeVisitor($callable);
$nodeTraverser->addVisitor($callableNodeVisitor);
$this->mirrorParentReturnArrowFunction($nodes);
$nodeTraverser->addVisitor(new ParentConnectingVisitor());

if ($this->shouldConnectParent($node)) {
$nodeTraverser->addVisitor(new ParentConnectingVisitor());
}

$nodes = $node instanceof Node ? [$node] : $node;
$nodeTraverser->traverse($nodes);
}

/**
* The ArrowFunction when call ->getStmts(), it returns
*
* return [new Node\Stmt\Return_($this->expr)]
*
* The $expr property has parent Node ArrowFunction, but not the Return_ stmt,
* so need to mirror $expr parent Node into Return_ stmt
*
* @param Node[] $nodes
* @param Node|Node[] $node
*/
private function mirrorParentReturnArrowFunction(array $nodes): void
private function shouldConnectParent(Node | array $node): bool
{
foreach ($nodes as $node) {
if (! $node instanceof Return_) {
continue;
}

if (! $node->expr instanceof Expr) {
continue;
}

if ($node instanceof Node) {
$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
if ($parentNode instanceof Node) {
continue;
}

$exprParent = $node->expr->getAttribute(AttributeKey::PARENT_NODE);
if ($exprParent instanceof ArrowFunction) {
$node->setAttribute(AttributeKey::PARENT_NODE, $exprParent);
}
return $parentNode instanceof Node;
}

// usage mostly by pass $node->stmts which parent node is the node
return true;
}
}

0 comments on commit 21b1ff9

Please sign in to comment.