mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-01 08:50:50 +00:00
[Renaming] Apply rename fully qualified namespace docblock on RenameNamespaceRector (#1917)
This commit is contained in:
parent
84f7ebde04
commit
888f483102
|
@ -18,7 +18,7 @@
|
|||
"helmich/typo3-typoscript-parser": "^2.4.1",
|
||||
"idiosyncratic/editorconfig": "^0.1.3",
|
||||
"myclabs/php-enum": "^1.8",
|
||||
"nette/neon": "^3.3.2",
|
||||
"nette/neon": "3.3.2",
|
||||
"nette/utils": "^3.2.7",
|
||||
"nikic/php-parser": "^4.13.2",
|
||||
"ondram/ci-detector": "^4.1",
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDoc\VariadicAwareParamTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode;
|
||||
use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
|
||||
use Rector\Naming\NamespaceMatcher;
|
||||
use Rector\Renaming\ValueObject\RenamedNamespace;
|
||||
|
||||
final class DocBlockNamespaceRenamer
|
||||
{
|
||||
/**
|
||||
* @var array<class-string<PhpDocTagValueNode>>
|
||||
*/
|
||||
private const TO_BE_CHANGED = [
|
||||
ReturnTagValueNode::class,
|
||||
VariadicAwareParamTagValueNode::class,
|
||||
VarTagValueNode::class,
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
private readonly NamespaceMatcher $namespaceMatcher,
|
||||
private readonly PhpDocInfoFactory $phpDocInfoFactory
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $oldToNewNamespaces
|
||||
*/
|
||||
public function renameFullyQualifiedNamespace(
|
||||
Property|ClassMethod|Function_|Expression|ClassLike|FileWithoutNamespace $node,
|
||||
array $oldToNewNamespaces
|
||||
): ?Node {
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||
$phpDocNode = $phpDocInfo->getPhpDocNode();
|
||||
$children = $phpDocNode->children;
|
||||
|
||||
foreach ($children as $child) {
|
||||
if (! $child instanceof PhpDocTagNode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $child->value;
|
||||
if (! in_array($value::class, self::TO_BE_CHANGED, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/** @var ReturnTagValueNode|VariadicAwareParamTagValueNode|VarTagValueNode $value */
|
||||
$this->refactorDocblock($value, $oldToNewNamespaces);
|
||||
}
|
||||
|
||||
if (! $phpDocInfo->hasChanged()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $oldToNewNamespaces
|
||||
*/
|
||||
private function refactorDocblock(
|
||||
ReturnTagValueNode|VariadicAwareParamTagValueNode|VarTagValueNode $value,
|
||||
array $oldToNewNamespaces
|
||||
): void {
|
||||
/** @var ReturnTagValueNode|VariadicAwareParamTagValueNode|VarTagValueNode $value */
|
||||
$types = $value->type instanceof BracketsAwareUnionTypeNode
|
||||
? $value->type->types
|
||||
: [$value->type];
|
||||
|
||||
foreach ($types as $key => $type) {
|
||||
if (! $type instanceof IdentifierTypeNode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = $type->name;
|
||||
$trimmedName = ltrim($type->name, '\\');
|
||||
|
||||
if ($name === $trimmedName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$renamedNamespaceValueObject = $this->namespaceMatcher->matchRenamedNamespace(
|
||||
$trimmedName,
|
||||
$oldToNewNamespaces
|
||||
);
|
||||
if (! $renamedNamespaceValueObject instanceof RenamedNamespace) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newType = new IdentifierTypeNode('\\' . $renamedNamespaceValueObject->getNameInNewNamespace());
|
||||
|
||||
if ($value->type instanceof BracketsAwareUnionTypeNode) {
|
||||
$types[$key] = $newType;
|
||||
} else {
|
||||
$value->type = $newType;
|
||||
}
|
||||
}
|
||||
|
||||
if ($value->type instanceof BracketsAwareUnionTypeNode) {
|
||||
$value->type->types = $types;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace OldNamespace\SubNamespace;
|
||||
|
||||
use OldNamespace;
|
||||
|
||||
class RenameNamespaceDocblockParam
|
||||
{
|
||||
/**
|
||||
* @param \OldNamespace\SubNamespace\RenameNamespaceDocblockParam $argument
|
||||
*/
|
||||
public function run(\OldNamespace\SubNamespace\RenameNamespaceDocblockParam $argument)
|
||||
{
|
||||
return $argument;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace NewNamespace\SubNamespace;
|
||||
|
||||
use NewNamespace;
|
||||
|
||||
class RenameNamespaceDocblockParam
|
||||
{
|
||||
/**
|
||||
* @param \NewNamespace\SubNamespace\RenameNamespaceDocblockParam $argument
|
||||
*/
|
||||
public function run(\NewNamespace\SubNamespace\RenameNamespaceDocblockParam $argument)
|
||||
{
|
||||
return $argument;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace OldNamespace\SubNamespace;
|
||||
|
||||
use OldNamespace;
|
||||
|
||||
class RenameNamespaceDocblockReturn
|
||||
{
|
||||
/**
|
||||
* @return \OldNamespace\SubNamespace\RenameNamespaceDocblockReturn
|
||||
*/
|
||||
public function run(\OldNamespace\SubNamespace\RenameNamespaceDocblockReturn $argument)
|
||||
{
|
||||
return $argument;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace NewNamespace\SubNamespace;
|
||||
|
||||
use NewNamespace;
|
||||
|
||||
class RenameNamespaceDocblockReturn
|
||||
{
|
||||
/**
|
||||
* @return \NewNamespace\SubNamespace\RenameNamespaceDocblockReturn
|
||||
*/
|
||||
public function run(\NewNamespace\SubNamespace\RenameNamespaceDocblockReturn $argument)
|
||||
{
|
||||
return $argument;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace OldNamespace\SubNamespace;
|
||||
|
||||
use OldNamespace;
|
||||
|
||||
class RenameNamespaceDocblockUnion
|
||||
{
|
||||
public function run(?\OldNamespace\SubNamespace\RenameNamespaceDocblockUnion $argument)
|
||||
{
|
||||
/**
|
||||
* @var \OldNamespace\SubNamespace\RenameNamespaceDocblockUnion|null $argument
|
||||
*/
|
||||
$var = $argument;
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace NewNamespace\SubNamespace;
|
||||
|
||||
use NewNamespace;
|
||||
|
||||
class RenameNamespaceDocblockUnion
|
||||
{
|
||||
public function run(?\NewNamespace\SubNamespace\RenameNamespaceDocblockUnion $argument)
|
||||
{
|
||||
/**
|
||||
* @var \NewNamespace\SubNamespace\RenameNamespaceDocblockUnion|null $argument
|
||||
*/
|
||||
$var = $argument;
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace OldNamespace\SubNamespace;
|
||||
|
||||
use OldNamespace;
|
||||
|
||||
class RenameNamespaceDocblockVar
|
||||
{
|
||||
public function run(\OldNamespace\SubNamespace\RenameNamespaceDocblockVar $argument)
|
||||
{
|
||||
/**
|
||||
* @var \OldNamespace\SubNamespace\RenameNamespaceDocblockVar $argument
|
||||
*/
|
||||
$var = $argument;
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace NewNamespace\SubNamespace;
|
||||
|
||||
use NewNamespace;
|
||||
|
||||
class RenameNamespaceDocblockVar
|
||||
{
|
||||
public function run(\NewNamespace\SubNamespace\RenameNamespaceDocblockVar $argument)
|
||||
{
|
||||
/**
|
||||
* @var \NewNamespace\SubNamespace\RenameNamespaceDocblockVar $argument
|
||||
*/
|
||||
$var = $argument;
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -8,13 +8,20 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\Node\Stmt\Namespace_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\Stmt\Use_;
|
||||
use PhpParser\Node\Stmt\UseUse;
|
||||
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||
use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Naming\NamespaceMatcher;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockNamespaceRenamer;
|
||||
use Rector\Renaming\ValueObject\RenamedNamespace;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
@ -25,6 +32,18 @@ use Webmozart\Assert\Assert;
|
|||
*/
|
||||
final class RenameNamespaceRector extends AbstractRector implements ConfigurableRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var array<class-string<Node>>
|
||||
*/
|
||||
private const ONLY_CHANGE_DOCBLOCK_NODE = [
|
||||
Property::class,
|
||||
ClassMethod::class,
|
||||
Function_::class,
|
||||
Expression::class,
|
||||
ClassLike::class,
|
||||
FileWithoutNamespace::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
|
@ -36,7 +55,8 @@ final class RenameNamespaceRector extends AbstractRector implements Configurable
|
|||
private array $isChangedInNamespaces = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly NamespaceMatcher $namespaceMatcher
|
||||
private readonly NamespaceMatcher $namespaceMatcher,
|
||||
private readonly DocBlockNamespaceRenamer $docBlockNamespaceRenamer
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -58,14 +78,20 @@ final class RenameNamespaceRector extends AbstractRector implements Configurable
|
|||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Namespace_::class, Use_::class, Name::class];
|
||||
return [Namespace_::class, Use_::class, Name::class, ...self::ONLY_CHANGE_DOCBLOCK_NODE];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Namespace_|Use_|Name $node
|
||||
* @param Namespace_|Use_|Name|Property|ClassMethod|Function_|Expression|ClassLike|FileWithoutNamespace $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (in_array($node::class, self::ONLY_CHANGE_DOCBLOCK_NODE, true)) {
|
||||
/** @var Property|ClassMethod|Function_|Expression|ClassLike|FileWithoutNamespace $node */
|
||||
return $this->docBlockNamespaceRenamer->renameFullyQualifiedNamespace($node, $this->oldToNewNamespaces);
|
||||
}
|
||||
|
||||
/** @var Namespace_|Use_|Name $node */
|
||||
$name = $this->getName($node);
|
||||
if ($name === null) {
|
||||
return null;
|
||||
|
|
Loading…
Reference in New Issue
Block a user