mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-23 03:02:33 +01:00
Merge pull request #804 from rectorphp/namespace-config
Make PseudoNamespaceToNamespaceRector config consistent with rest of Rectors
This commit is contained in:
commit
a2c213f9e2
@ -4,9 +4,7 @@ services:
|
||||
|
||||
# ref. https://github.com/sebastianbergmann/phpunit/compare/5.7.9...6.0.0
|
||||
Rector\Rector\Namespace_\PseudoNamespaceToNamespaceRector:
|
||||
$pseudoNamespacePrefixes:
|
||||
- 'PHPUnit_'
|
||||
$excludedClasses:
|
||||
PHPUnit_:
|
||||
# exclude this class, since it has no namespaced replacement
|
||||
- 'PHPUnit_Framework_MockObject_MockObject'
|
||||
|
||||
|
@ -154,4 +154,4 @@ services:
|
||||
'Twig_Extensions_Node_Trans': 'Twig\Extensions\Node\TransNode'
|
||||
|
||||
Rector\Rector\Namespace_\PseudoNamespaceToNamespaceRector:
|
||||
- 'Twig_'
|
||||
Twig_: ~
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
namespace Rector\Rector\Namespace_;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Namespace_;
|
||||
use Rector\Exception\ShouldNotHappenException;
|
||||
use Rector\NodeTypeResolver\Node\Attribute;
|
||||
use Rector\PhpParser\Node\Maintainer\ClassMaintainer;
|
||||
use Rector\Rector\AbstractRector;
|
||||
@ -23,14 +23,9 @@ final class PseudoNamespaceToNamespaceRector extends AbstractRector
|
||||
private $newNamespace;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @var string[][]|null[]
|
||||
*/
|
||||
private $pseudoNamespacePrefixes = [];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $excludedClasses = [];
|
||||
private $namespacePrefixWithExcludedClasses = [];
|
||||
|
||||
/**
|
||||
* @var ClassMaintainer
|
||||
@ -38,28 +33,37 @@ final class PseudoNamespaceToNamespaceRector extends AbstractRector
|
||||
private $classMaintainer;
|
||||
|
||||
/**
|
||||
* @param string[] $pseudoNamespacePrefixes
|
||||
* @param string[] $excludedClasses
|
||||
* @param string[][]|null[] $namespacePrefixesWithExcludedClasses
|
||||
*/
|
||||
public function __construct(
|
||||
ClassMaintainer $classMaintainer,
|
||||
array $pseudoNamespacePrefixes,
|
||||
array $excludedClasses = []
|
||||
) {
|
||||
public function __construct(ClassMaintainer $classMaintainer, array $namespacePrefixesWithExcludedClasses)
|
||||
{
|
||||
$this->classMaintainer = $classMaintainer;
|
||||
$this->pseudoNamespacePrefixes = $pseudoNamespacePrefixes;
|
||||
$this->excludedClasses = $excludedClasses;
|
||||
$this->namespacePrefixWithExcludedClasses = $namespacePrefixesWithExcludedClasses;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Replaces defined Pseudo_Namespaces by Namespace\Ones.', [
|
||||
new ConfiguredCodeSample(
|
||||
'$someService = Some_Object;',
|
||||
'$someService = Some\Object;',
|
||||
'$someService = new Some_Object;',
|
||||
'$someService = new Some\Object;',
|
||||
[
|
||||
'$pseudoNamespacePrefixes' => ['Some_'],
|
||||
'$excludedClasses' => [],
|
||||
['Some_' => []],
|
||||
]
|
||||
),
|
||||
new ConfiguredCodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
$someService = new Some_Object;
|
||||
$someClassToKeep = new Some_Class_To_Keep;
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
$someService = new Some\Object;
|
||||
$someClassToKeep = new Some_Class_To_Keep;
|
||||
CODE_SAMPLE
|
||||
,
|
||||
[
|
||||
['Some_' => ['Some_Class_To_Keep']],
|
||||
]
|
||||
),
|
||||
]);
|
||||
@ -78,40 +82,27 @@ final class PseudoNamespaceToNamespaceRector extends AbstractRector
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$name = $node->toString();
|
||||
if (! $name) {
|
||||
// no name → skip
|
||||
if (! $node->toString()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (in_array($name, $this->excludedClasses, true)) {
|
||||
return null;
|
||||
}
|
||||
foreach ($this->namespacePrefixWithExcludedClasses as $namespacePrefix => $excludedClasses) {
|
||||
if (! $this->nameStartsWith($node, $namespacePrefix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $this->isNamespaceMatch($name)) {
|
||||
return null;
|
||||
}
|
||||
if (is_array($excludedClasses) && $this->isNames($node, $excludedClasses)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$oldName = $node->toString();
|
||||
if ($node instanceof Name) {
|
||||
return $this->processName($node);
|
||||
}
|
||||
|
||||
$newNameParts = explode('_', $oldName);
|
||||
$parentNode = $node->getAttribute(Attribute::PARENT_NODE);
|
||||
$lastNewNamePart = $newNameParts[count($newNameParts) - 1];
|
||||
|
||||
if ($node instanceof Name) {
|
||||
$node->parts = $newNameParts;
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
if ($node instanceof Identifier && $parentNode instanceof Class_) {
|
||||
$namespaceParts = $newNameParts;
|
||||
array_pop($namespaceParts);
|
||||
|
||||
$this->newNamespace = implode('\\', $namespaceParts);
|
||||
|
||||
$node->name = $lastNewNamePart;
|
||||
|
||||
return $node;
|
||||
if ($node instanceof Identifier) {
|
||||
return $this->processIdentifier($node);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -123,15 +114,16 @@ final class PseudoNamespaceToNamespaceRector extends AbstractRector
|
||||
*/
|
||||
public function afterTraverse(array $nodes): array
|
||||
{
|
||||
if ($this->newNamespace) {
|
||||
$namespaceNode = new Namespace_(new Name($this->newNamespace));
|
||||
if ($this->newNamespace === null) {
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
foreach ($nodes as $key => $node) {
|
||||
if ($node instanceof Class_) {
|
||||
$nodes = $this->classMaintainer->insertBeforeAndFollowWithNewline($nodes, $namespaceNode, $key);
|
||||
$namespaceNode = new Namespace_(new Name($this->newNamespace));
|
||||
foreach ($nodes as $key => $node) {
|
||||
if ($node instanceof Class_) {
|
||||
$nodes = $this->classMaintainer->insertBeforeAndFollowWithNewline($nodes, $namespaceNode, $key);
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,14 +132,35 @@ final class PseudoNamespaceToNamespaceRector extends AbstractRector
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
private function isNamespaceMatch(string $name): bool
|
||||
private function processName(Name $nameNode): Name
|
||||
{
|
||||
foreach ($this->pseudoNamespacePrefixes as $pseudoNamespacePrefix) {
|
||||
if (Strings::startsWith($name, $pseudoNamespacePrefix)) {
|
||||
return true;
|
||||
}
|
||||
$nameNode->parts = explode('_', $this->getName($nameNode));
|
||||
|
||||
return $nameNode;
|
||||
}
|
||||
|
||||
private function processIdentifier(Identifier $identifierNode): ?Identifier
|
||||
{
|
||||
$parentNode = $identifierNode->getAttribute(Attribute::PARENT_NODE);
|
||||
if (! $parentNode instanceof Class_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return false;
|
||||
$newNameParts = explode('_', $this->getName($identifierNode));
|
||||
$lastNewNamePart = $newNameParts[count($newNameParts) - 1];
|
||||
|
||||
$namespaceParts = $newNameParts;
|
||||
array_pop($namespaceParts);
|
||||
|
||||
$newNamespace = implode('\\', $namespaceParts);
|
||||
if ($this->newNamespace !== null && $this->newNamespace !== $newNamespace) {
|
||||
throw new ShouldNotHappenException('There woulde are 2 different namespaces in one file');
|
||||
}
|
||||
|
||||
$this->newNamespace = $newNamespace;
|
||||
|
||||
$identifierNode->name = $lastNewNamePart;
|
||||
|
||||
return $identifierNode;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace ChangeMe\ToNamespaced;
|
||||
|
||||
use PHPUnit\TestCase;
|
||||
|
||||
class SomeTestCase
|
||||
{
|
||||
/**
|
||||
* @return \ChangeMe_AnotherNamespace
|
||||
*/
|
||||
public function someMethod(): \Keep_ThisThough
|
||||
{
|
||||
if ($this instanceof \PHPUnit\TestCase) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ final class PseudoNamespaceToNamespaceRectorTest extends AbstractRectorTestCase
|
||||
yield [__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/correct2.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/wrong3.php.inc', __DIR__ . '/Correct/correct3.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/wrong4.php.inc', __DIR__ . '/Correct/correct4.php.inc'];
|
||||
yield [__DIR__ . '/Wrong/wrong5.php.inc', __DIR__ . '/Correct/correct5.php.inc'];
|
||||
}
|
||||
|
||||
protected function provideConfig(): string
|
||||
|
@ -0,0 +1,18 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace ChangeMe_ToNamespaced;
|
||||
|
||||
use PHPUnit_TestCase;
|
||||
|
||||
class SomeTestCase
|
||||
{
|
||||
/**
|
||||
* @return \ChangeMe_AnotherNamespace
|
||||
*/
|
||||
public function someMethod(): \Keep_ThisThough
|
||||
{
|
||||
if ($this instanceof PHPUnit_TestCase) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
services:
|
||||
Rector\Rector\Namespace_\PseudoNamespaceToNamespaceRector:
|
||||
$pseudoNamespacePrefixes:
|
||||
- 'PHPUnit_'
|
||||
$excludedClasses:
|
||||
PHPUnit_:
|
||||
# excluded classes
|
||||
- 'PHPUnit_Framework_MockObject_MockObject'
|
||||
ChangeMe_:
|
||||
- 'KeepMe_'
|
||||
|
Loading…
x
Reference in New Issue
Block a user