Skip to content

Commit

Permalink
Remove uses nodes attribute - part #1 (#2155)
Browse files Browse the repository at this point in the history
Co-authored-by: GitHub Action <action@github.com>
  • Loading branch information
TomasVotruba and actions-user committed Apr 25, 2022
1 parent f0223b6 commit 90dae50
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 17 deletions.
2 changes: 0 additions & 2 deletions .phpstorm.meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
\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,
Expand All @@ -71,7 +70,6 @@
\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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use Rector\CodingStyle\NodeAnalyzer\UseImportNameMatcher;
use Rector\Naming\Naming\UseImportsResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;

/**
Expand All @@ -24,6 +25,7 @@ final class ClassAnnotationMatcher

public function __construct(
private readonly UseImportNameMatcher $useImportNameMatcher,
private readonly UseImportsResolver $useImportsResolver,
private readonly ReflectionProvider $reflectionProvider
) {
}
Expand All @@ -37,8 +39,7 @@ public function resolveTagFullyQualifiedName(string $tag, Node $node): string

$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;
Expand Down
4 changes: 4 additions & 0 deletions packages/FileSystemRector/Parser/FileInfoParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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;
Expand All @@ -14,6 +15,7 @@ final class FileInfoParser
{
public function __construct(
private readonly NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator,
private readonly FileWithoutNamespaceNodeTraverser $fileWithoutNamespaceNodeTraverser,
private readonly RectorParser $rectorParser
) {
}
Expand All @@ -24,6 +26,8 @@ public function __construct(
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);
Expand Down
3 changes: 3 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -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#'
11 changes: 9 additions & 2 deletions rules/DowngradePhp56/Rector/Use_/DowngradeUseFunctionRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
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;

Expand All @@ -22,6 +22,11 @@
*/
final class DowngradeUseFunctionRector extends AbstractRector
{
public function __construct(
private readonly UseImportsResolver $useImportsResolver,
) {
}

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
Expand Down Expand Up @@ -64,7 +69,9 @@ public function refactor(Node $node): ?Node
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;
}
Expand Down
12 changes: 5 additions & 7 deletions rules/Naming/Naming/AliasNameResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,23 @@

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;
}
Expand Down
35 changes: 35 additions & 0 deletions rules/Naming/Naming/UseImportsResolver.php
Original file line number Diff line number Diff line change
@@ -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);
}
}
3 changes: 1 addition & 2 deletions src/PhpParser/Node/CustomNode/FileWithoutNamespace.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
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
Expand Down
40 changes: 40 additions & 0 deletions src/PhpParser/NodeTraverser/FileWithoutNamespaceNodeTraverser.php
Original file line number Diff line number Diff line change
@@ -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;
}
}
11 changes: 9 additions & 2 deletions src/PhpParser/NodeTraverser/RectorNodeTraverser.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
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
Expand Down Expand Up @@ -38,10 +39,16 @@ public function traverse(array $nodes): array
$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);
}

/**
Expand Down

0 comments on commit 90dae50

Please sign in to comment.