mirror of
https://github.com/rectorphp/rector.git
synced 2025-03-14 12:29:43 +01:00
Merge pull request #672 from rectorphp/expression-attribute
Add ExpressionNodeVisitor
This commit is contained in:
commit
bc658bee39
@ -79,4 +79,14 @@ final class Attribute
|
||||
* @var string
|
||||
*/
|
||||
public const NEXT_NODE = 'nextNode';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const PREVIOUS_EXPRESSION = 'previousExpression';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const CURRENT_EXPRESSION = 'currentExpression';
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ use PhpParser\NodeTraverser;
|
||||
use PhpParser\NodeVisitor\CloningVisitor;
|
||||
use PhpParser\NodeVisitor\NameResolver;
|
||||
use Rector\NodeTypeResolver\NodeVisitor\ClassAndMethodNodeVisitor;
|
||||
use Rector\NodeTypeResolver\NodeVisitor\ExpressionNodeVisitor;
|
||||
use Rector\NodeTypeResolver\NodeVisitor\NamespaceNodeVisitor;
|
||||
use Rector\NodeTypeResolver\NodeVisitor\ParentAndNextNodeVisitor;
|
||||
use Rector\NodeTypeResolver\PHPStan\Scope\NodeScopeResolver;
|
||||
@ -38,18 +39,25 @@ final class NodeScopeAndMetadataDecorator
|
||||
*/
|
||||
private $namespaceNodeVisitor;
|
||||
|
||||
/**
|
||||
* @var ExpressionNodeVisitor
|
||||
*/
|
||||
private $expressionNodeVisitor;
|
||||
|
||||
public function __construct(
|
||||
NodeScopeResolver $nodeScopeResolver,
|
||||
ParentAndNextNodeVisitor $parentAndNextNodeVisitor,
|
||||
CloningVisitor $cloningVisitor,
|
||||
ClassAndMethodNodeVisitor $classAndMethodNodeVisitor,
|
||||
NamespaceNodeVisitor $namespaceNodeVisitor
|
||||
NamespaceNodeVisitor $namespaceNodeVisitor,
|
||||
ExpressionNodeVisitor $expressionNodeVisitor
|
||||
) {
|
||||
$this->nodeScopeResolver = $nodeScopeResolver;
|
||||
$this->parentAndNextNodeVisitor = $parentAndNextNodeVisitor;
|
||||
$this->cloningVisitor = $cloningVisitor;
|
||||
$this->classAndMethodNodeVisitor = $classAndMethodNodeVisitor;
|
||||
$this->namespaceNodeVisitor = $namespaceNodeVisitor;
|
||||
$this->expressionNodeVisitor = $expressionNodeVisitor;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,6 +85,7 @@ final class NodeScopeAndMetadataDecorator
|
||||
$nodeTraverser->addVisitor($this->parentAndNextNodeVisitor);
|
||||
$nodeTraverser->addVisitor($this->classAndMethodNodeVisitor);
|
||||
$nodeTraverser->addVisitor($this->namespaceNodeVisitor);
|
||||
$nodeTraverser->addVisitor($this->expressionNodeVisitor);
|
||||
|
||||
return $nodeTraverser->traverse($nodes);
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\NodeVisitor;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use Rector\NodeTypeResolver\Node\Attribute;
|
||||
|
||||
final class ExpressionNodeVisitor extends NodeVisitorAbstract
|
||||
{
|
||||
/**
|
||||
* @var Expression|null
|
||||
*/
|
||||
private $currentExpression;
|
||||
|
||||
/**
|
||||
* @var Expression|null
|
||||
*/
|
||||
private $previousExpression;
|
||||
|
||||
/**
|
||||
* @param Node[] $nodes
|
||||
*/
|
||||
public function beforeTraverse(array $nodes): void
|
||||
{
|
||||
$this->currentExpression = null;
|
||||
$this->previousExpression = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|Node|void|null
|
||||
*/
|
||||
public function enterNode(Node $node)
|
||||
{
|
||||
if ($node instanceof Expression && $this->currentExpression !== $node) {
|
||||
$this->previousExpression = $this->currentExpression;
|
||||
$this->currentExpression = $node;
|
||||
}
|
||||
|
||||
$node->setAttribute(Attribute::PREVIOUS_EXPRESSION, $this->previousExpression);
|
||||
$node->setAttribute(Attribute::CURRENT_EXPRESSION, $this->currentExpression);
|
||||
}
|
||||
}
|
@ -84,12 +84,7 @@ final class BetterNodeFinder
|
||||
|
||||
public function findFirstPrevious(Node $node, callable $filter): ?Node
|
||||
{
|
||||
if (! $node instanceof Expression) {
|
||||
$expression = $node->getAttribute(Attribute::PARENT_NODE);
|
||||
if ($expression instanceof Expression) {
|
||||
$node = $expression;
|
||||
}
|
||||
}
|
||||
$node = $node instanceof Expression ? $node : $node->getAttribute(Attribute::CURRENT_EXPRESSION);
|
||||
|
||||
$foundNode = $this->findFirst([$node], $filter);
|
||||
// we found what we need
|
||||
@ -98,32 +93,11 @@ final class BetterNodeFinder
|
||||
}
|
||||
|
||||
// move to next expression
|
||||
$previousExpression = $this->getPreviousExpression($node);
|
||||
$previousExpression = $node->getAttribute(Attribute::PREVIOUS_EXPRESSION);
|
||||
if ($previousExpression === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->findFirstPrevious($previousExpression, $filter);
|
||||
}
|
||||
|
||||
private function getPreviousExpression(Node $node): ?Expression
|
||||
{
|
||||
$previousExpression = $node->getAttribute(Attribute::PREVIOUS_NODE);
|
||||
|
||||
while (! $previousExpression instanceof Expression && $previousExpression !== null) {
|
||||
$previousExpression = $previousExpression->getAttribute(Attribute::PREVIOUS_NODE);
|
||||
if ($previousExpression instanceof Expression) {
|
||||
return $previousExpression;
|
||||
}
|
||||
|
||||
if ($previousExpression instanceof Node) {
|
||||
$previousExpression = $previousExpression->getAttribute(Attribute::PARENT_NODE);
|
||||
if ($previousExpression instanceof Expression) {
|
||||
return $previousExpression;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $previousExpression;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user