Merge pull request #672 from rectorphp/expression-attribute

Add ExpressionNodeVisitor
This commit is contained in:
Tomáš Votruba 2018-10-11 12:51:02 +08:00 committed by GitHub
commit bc658bee39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 29 deletions

View File

@ -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';
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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;
}
}