Remove uses nodes attribute - part #1 (#2155)

Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Tomas Votruba 2022-04-25 09:03:59 +02:00 committed by GitHub
parent f0223b6329
commit 90dae505af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 109 additions and 17 deletions

View File

@ -50,7 +50,6 @@ expectedArguments(
\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::NEXT_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::PREVIOUS_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::USE_NODES,
\Rector\NodeTypeResolver\Node\AttributeKey::START_TOKEN_POSITION,
\Rector\NodeTypeResolver\Node\AttributeKey::ORIGINAL_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::IS_UNREACHABLE,
@ -71,7 +70,6 @@ expectedArguments(
\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::NEXT_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::PREVIOUS_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::USE_NODES,
\Rector\NodeTypeResolver\Node\AttributeKey::START_TOKEN_POSITION,
\Rector\NodeTypeResolver\Node\AttributeKey::ORIGINAL_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::IS_UNREACHABLE,

View File

@ -10,6 +10,7 @@ use PhpParser\Node\Stmt\Use_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use Rector\CodingStyle\NodeAnalyzer\UseImportNameMatcher;
use Rector\Naming\Naming\UseImportsResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
@ -24,6 +25,7 @@ final class ClassAnnotationMatcher
public function __construct(
private readonly UseImportNameMatcher $useImportNameMatcher,
private readonly UseImportsResolver $useImportsResolver,
private readonly ReflectionProvider $reflectionProvider
) {
}
@ -37,8 +39,7 @@ final class ClassAnnotationMatcher
$tag = ltrim($tag, '@');
/** @var Use_[] $uses */
$uses = (array) $node->getAttribute(AttributeKey::USE_NODES);
$uses = $this->useImportsResolver->resolveForNode($node);
$fullyQualifiedClass = $this->resolveFullyQualifiedClass($uses, $node, $tag);
$this->fullyQualifiedNameByHash[$uniqueHash] = $fullyQualifiedClass;

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Rector\FileSystemRector\Parser;
use PhpParser\Node;
use Rector\Core\PhpParser\NodeTraverser\FileWithoutNamespaceNodeTraverser;
use Rector\Core\PhpParser\Parser\RectorParser;
use Rector\Core\ValueObject\Application\File;
use Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator;
@ -14,6 +15,7 @@ final class FileInfoParser
{
public function __construct(
private readonly NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator,
private readonly FileWithoutNamespaceNodeTraverser $fileWithoutNamespaceNodeTraverser,
private readonly RectorParser $rectorParser
) {
}
@ -24,6 +26,8 @@ final class FileInfoParser
public function parseFileInfoToNodesAndDecorate(SmartFileInfo $smartFileInfo): array
{
$stmts = $this->rectorParser->parseFile($smartFileInfo);
$stmts = $this->fileWithoutNamespaceNodeTraverser->traverse($stmts);
$file = new File($smartFileInfo, $smartFileInfo->getContents());
return $this->nodeScopeAndMetadataDecorator->decorateNodesFromFile($file, $stmts);

View File

@ -589,3 +589,6 @@ parameters:
-
message: '#Access to an undefined property PhpParser\\Node\:\:\$stmts#'
path: src/PhpParser/Node/BetterNodeFinder.php
# empty parent construct
- '#Rector\\Core\\PhpParser\\NodeTraverser\\FileWithoutNamespaceNodeTraverser\:\:__construct\(\) does not call parent constructor from PhpParser\\NodeTraverser#'

View File

@ -11,7 +11,7 @@ use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Use_;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Naming\Naming\UseImportsResolver;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -22,6 +22,11 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
*/
final class DowngradeUseFunctionRector extends AbstractRector
{
public function __construct(
private readonly UseImportsResolver $useImportsResolver,
) {
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
@ -64,7 +69,9 @@ CODE_SAMPLE
return null;
}
$name = $this->getFullyQualifiedName($node->getAttribute(AttributeKey::USE_NODES), $node);
$uses = $this->useImportsResolver->resolveForNode($node);
$name = $this->getFullyQualifiedName($uses, $node);
if ($name === null) {
return null;
}

View File

@ -6,25 +6,23 @@ namespace Rector\Naming\Naming;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Use_;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class AliasNameResolver
{
public function __construct(
private readonly NodeNameResolver $nodeNameResolver
private readonly NodeNameResolver $nodeNameResolver,
private readonly UseImportsResolver $useImportsResolver,
) {
}
public function resolveByName(Name $name): ?string
{
/** @var Use_[] $useNodes */
$useNodes = $name->getAttribute(AttributeKey::USE_NODES);
$uses = $this->useImportsResolver->resolveForNode($name);
$nameString = $name->toString();
foreach ($useNodes as $useNode) {
$useUses = $useNode->uses;
foreach ($uses as $use) {
$useUses = $use->uses;
if (count($useUses) > 1) {
continue;
}

View File

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace Rector\Naming\Naming;
use PhpParser\Node;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\Node\Stmt\Use_;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
final class UseImportsResolver
{
public function __construct(
private readonly BetterNodeFinder $betterNodeFinder
) {
}
/**
* @return Use_[]
*/
public function resolveForNode(Node $node): array
{
$namespace = $this->betterNodeFinder->findParentByTypes(
$node,
[Namespace_::class, FileWithoutNamespace::class]
);
if (! $namespace instanceof Node) {
return [];
}
return $this->betterNodeFinder->findInstanceOf($namespace, Use_::class);
}
}

View File

@ -5,12 +5,11 @@ declare(strict_types=1);
namespace Rector\Core\PhpParser\Node\CustomNode;
use PhpParser\Node\Stmt;
use PhpParser\NodeAbstract;
/**
* Inspired by https://github.com/phpstan/phpstan-src/commit/ed81c3ad0b9877e6122c79b4afda9d10f3994092
*/
final class FileWithoutNamespace extends NodeAbstract
final class FileWithoutNamespace extends Stmt
{
/**
* @param Stmt[] $stmts

View File

@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace Rector\Core\PhpParser\NodeTraverser;
use PhpParser\Node;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\NodeFinder;
use PhpParser\NodeTraverser;
use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class FileWithoutNamespaceNodeTraverser extends NodeTraverser
{
public function __construct(
private readonly NodeFinder $nodeFinder,
) {
}
/**
* @template TNode as Node
* @param TNode[] $nodes
* @return TNode[]|FileWithoutNamespace[]
*/
public function traverse(array $nodes): array
{
$hasNamespace = (bool) $this->nodeFinder->findFirstInstanceOf($nodes, Namespace_::class);
if (! $hasNamespace && $nodes !== []) {
$fileWithoutNamespace = new FileWithoutNamespace($nodes);
foreach ($nodes as $node) {
$node->setAttribute(AttributeKey::PARENT_NODE, $fileWithoutNamespace);
}
return [$fileWithoutNamespace];
}
return $nodes;
}
}

View File

@ -10,6 +10,7 @@ use PhpParser\NodeFinder;
use PhpParser\NodeTraverser;
use Rector\Core\Contract\Rector\PhpRectorInterface;
use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\VersionBonding\PhpVersionedFilter;
final class RectorNodeTraverser extends NodeTraverser
@ -38,10 +39,16 @@ final class RectorNodeTraverser extends NodeTraverser
$hasNamespace = (bool) $this->nodeFinder->findFirstInstanceOf($nodes, Namespace_::class);
if (! $hasNamespace && $nodes !== []) {
$fileWithoutNamespace = new FileWithoutNamespace($nodes);
return parent::traverse([$fileWithoutNamespace]);
foreach ($nodes as $node) {
$node->setAttribute(AttributeKey::PARENT_NODE, $fileWithoutNamespace);
}
$nodesToTraverse = [$fileWithoutNamespace];
} else {
$nodesToTraverse = $nodes;
}
return parent::traverse($nodes);
return parent::traverse($nodesToTraverse);
}
/**