mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-01 08:50:50 +00:00
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
parent
f0223b6329
commit
90dae505af
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
35
rules/Naming/Naming/UseImportsResolver.php
Normal file
35
rules/Naming/Naming/UseImportsResolver.php
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue
Block a user