mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-31 00:10:51 +00:00
[DX] Remove MoveServicesBySuffixToDirectoryRector, better handle by PHPStan + PHPStorm refacor (#1834)
This commit is contained in:
parent
323be2a5de
commit
a4eff1e0ad
File diff suppressed because it is too large
Load Diff
|
@ -114,7 +114,6 @@
|
|||
},
|
||||
"classmap": [
|
||||
"stubs",
|
||||
"rules-tests/Autodiscovery/Rector/Class_/MoveServicesBySuffixToDirectoryRector/Expected",
|
||||
"rules-tests/Autodiscovery/Rector/Interface_/MoveInterfacesToContractNamespaceDirectoryRector/Expected",
|
||||
"rules-tests/CodingStyle/Rector/Namespace_/ImportFullyQualifiedNamesRector/Source",
|
||||
"rules-tests/Renaming/Rector/Name/RenameClassRector/Source",
|
||||
|
|
|
@ -305,7 +305,11 @@ final class PhpDocInfo
|
|||
$typeToRemove
|
||||
): ?int {
|
||||
if ($node instanceof PhpDocTagNode && is_a($node->value, $typeToRemove, true)) {
|
||||
if (str_starts_with($node->name, '@psalm-') || str_starts_with($node->name, '@phpstan-')) {
|
||||
if (str_starts_with($node->name, '@psalm-')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (str_starts_with($node->name, '@phpstan-')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Command;
|
||||
|
||||
final class BananaCommand
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return new \Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller\Orange();
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller;
|
||||
|
||||
final class MissPlacedController
|
||||
{
|
||||
public function getSelf()
|
||||
{
|
||||
return new \Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller\MissPlacedController();
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Mapper\Nested;
|
||||
|
||||
abstract class AbstractBaseMapper
|
||||
{
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Mapper\Nested;
|
||||
|
||||
abstract class AbstractBaseWithSpaceMapper
|
||||
{
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Mapper;
|
||||
|
||||
use Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller\Nested\AbstractBaseMapper;
|
||||
final class UserMapper extends \Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller\Nested\AbstractBaseMapper
|
||||
{
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Mapper;
|
||||
|
||||
use Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Mapper\Nested\AbstractBaseWithSpaceMapper;
|
||||
final class UserWithSpaceMapper extends \Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Mapper\Nested\AbstractBaseWithSpaceMapper
|
||||
{
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Repository;
|
||||
|
||||
class AppleRepository
|
||||
{
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
services:
|
||||
Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Mapper\Nested\AbstractBaseMapper: null
|
|
@ -1,97 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\FileSystemRector\ValueObject\AddedFileWithContent;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
use Symplify\SmartFileSystem\SmartFileSystem;
|
||||
|
||||
final class MoveServicesBySuffixToDirectoryRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $originalFileInfo, AddedFileWithContent $expectedAddedFileWithContent): void
|
||||
{
|
||||
$this->doTestFileInfo($originalFileInfo);
|
||||
$this->assertFileWasAdded($expectedAddedFileWithContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo|AddedFileWithContent>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
$smartFileSystem = new SmartFileSystem();
|
||||
|
||||
yield [
|
||||
new SmartFileInfo(__DIR__ . '/Source/Entity/AppleRepository.php'),
|
||||
new AddedFileWithContent(
|
||||
$this->getFixtureTempDirectory() . '/Repository/AppleRepository.php',
|
||||
$smartFileSystem->readFile(__DIR__ . '/Expected/Repository/ExpectedAppleRepository.php')
|
||||
),
|
||||
];
|
||||
|
||||
yield [
|
||||
new SmartFileInfo(__DIR__ . '/Source/Controller/BananaCommand.php'),
|
||||
new AddedFileWithContent(
|
||||
$this->getFixtureTempDirectory() . '/Command/BananaCommand.php',
|
||||
$smartFileSystem->readFile(__DIR__ . '/Expected/Command/ExpectedBananaCommand.php')
|
||||
),
|
||||
];
|
||||
|
||||
yield [
|
||||
new SmartFileInfo(__DIR__ . '/Source/Command/MissPlacedController.php'),
|
||||
new AddedFileWithContent(
|
||||
$this->getFixtureTempDirectory() . '/Controller/MissPlacedController.php',
|
||||
$smartFileSystem->readFile(__DIR__ . '/Expected/Controller/MissPlacedController.php')
|
||||
),
|
||||
];
|
||||
|
||||
yield [
|
||||
new SmartFileInfo(__DIR__ . '/Source/Controller/Nested/AbstractBaseWithSpaceMapper.php'),
|
||||
new AddedFileWithContent(
|
||||
$this->getFixtureTempDirectory() . '/Mapper/AbstractBaseWithSpaceMapper.php',
|
||||
$smartFileSystem->readFile(__DIR__ . '/Expected/Mapper/Nested/AbstractBaseWithSpaceMapper.php.inc')
|
||||
),
|
||||
];
|
||||
|
||||
// inversed order, but should have the same effect
|
||||
yield [
|
||||
new SmartFileInfo(__DIR__ . '/Source/Entity/UserMapper.php'),
|
||||
new AddedFileWithContent(
|
||||
$this->getFixtureTempDirectory() . '/Mapper/UserMapper.php',
|
||||
$smartFileSystem->readFile(__DIR__ . '/Expected/Mapper/UserMapper.php.inc')
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideDataSkipped()
|
||||
*/
|
||||
public function testSkipped(SmartFileInfo $originalFileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($originalFileInfo);
|
||||
|
||||
// no change - file should have the original location
|
||||
$this->assertFileWasNotChanged($this->originalTempFileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideDataSkipped(): Iterator
|
||||
{
|
||||
// nothing changes
|
||||
yield [new SmartFileInfo(__DIR__ . '/Source/Mapper/SkipCorrectMapper.php'), null];
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/configured_rule.php';
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Command;
|
||||
|
||||
final class MissPlacedController
|
||||
{
|
||||
public function getSelf()
|
||||
{
|
||||
return new MissPlacedController;
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller;
|
||||
|
||||
final class BananaCommand
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return new Orange();
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller\Nested;
|
||||
|
||||
abstract class AbstractBaseMapper
|
||||
{
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller\Nested;
|
||||
|
||||
abstract class AbstractBaseWithSpaceMapper
|
||||
{
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller;
|
||||
|
||||
final class Orange
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Entity;
|
||||
|
||||
class AppleRepository
|
||||
{
|
||||
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Entity;
|
||||
|
||||
use Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller\Nested\AbstractBaseMapper;
|
||||
|
||||
final class UserMapper extends AbstractBaseMapper
|
||||
{
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Entity;
|
||||
|
||||
use Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller\Nested\AbstractBaseWithSpaceMapper;
|
||||
|
||||
final class UserWithSpaceMapper extends AbstractBaseWithSpaceMapper
|
||||
{
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\SkipAlreadyMoved\Source\Mapper;
|
||||
|
||||
final class SkipCorrectMapper
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Repository;
|
||||
|
||||
class AppleRepository
|
||||
{
|
||||
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
services:
|
||||
Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\Source\Controller\Nested\AbstractBaseMapper: null
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(MoveServicesBySuffixToDirectoryRector::class)
|
||||
->configure(['Repository', 'Command', 'Mapper', 'Controller']);
|
||||
};
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Autodiscovery\FileLocation;
|
||||
|
||||
final class ExpectedFileLocationResolver
|
||||
{
|
||||
/**
|
||||
* Resolves if is suffix in the same category, e.g. "Exception/SomeException.php"
|
||||
*/
|
||||
public function resolve(string $escapedGroupName, string $suffixPattern): string
|
||||
{
|
||||
$escapedGroupName = preg_quote($escapedGroupName, '#');
|
||||
$escapedSuffixPattern = preg_quote($suffixPattern, '#');
|
||||
|
||||
return sprintf('#\/%s\/.+%s#', $escapedGroupName, $escapedSuffixPattern);
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Autodiscovery\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Autodiscovery\FileLocation\ExpectedFileLocationResolver;
|
||||
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\Util\StringUtils;
|
||||
use Rector\Core\ValueObject\Application\File;
|
||||
use Rector\FileSystemRector\ValueObject\AddedFileWithNodes;
|
||||
use Rector\FileSystemRector\ValueObjectFactory\AddedFileWithNodesFactory;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
/**
|
||||
* Inspiration @see https://github.com/rectorphp/rector/pull/1865/files#diff-0d18e660cdb626958662641b491623f8
|
||||
*
|
||||
* @see \Rector\Tests\Autodiscovery\Rector\Class_\MoveServicesBySuffixToDirectoryRector\MoveServicesBySuffixToDirectoryRectorTest
|
||||
*/
|
||||
final class MoveServicesBySuffixToDirectoryRector extends AbstractRector implements ConfigurableRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private array $groupNamesBySuffix = [];
|
||||
|
||||
public function __construct(
|
||||
private readonly ExpectedFileLocationResolver $expectedFileLocationResolver,
|
||||
private readonly AddedFileWithNodesFactory $addedFileWithNodesFactory
|
||||
) {
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Move classes by their suffix to their own group/directory', [
|
||||
new ConfiguredCodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
// file: app/Entity/ProductRepository.php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
class ProductRepository
|
||||
{
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
// file: app/Repository/ProductRepository.php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
class ProductRepository
|
||||
{
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
['Repository']
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Class_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$this->processGroupNamesBySuffix($this->file->getSmartFileInfo(), $this->groupNamesBySuffix);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $configuration
|
||||
*/
|
||||
public function configure(array $configuration): void
|
||||
{
|
||||
Assert::allString($configuration);
|
||||
|
||||
$this->groupNamesBySuffix = $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* A. Match classes by suffix and move them to group namespace
|
||||
*
|
||||
* E.g. "App\Controller\SomeException"
|
||||
* ↓
|
||||
* "App\Exception\SomeException"
|
||||
*
|
||||
* @param string[] $groupNamesBySuffix
|
||||
*/
|
||||
private function processGroupNamesBySuffix(SmartFileInfo $smartFileInfo, array $groupNamesBySuffix): void
|
||||
{
|
||||
foreach ($groupNamesBySuffix as $groupNames) {
|
||||
// has class suffix
|
||||
$suffixPattern = '\w+' . $groupNames . '(Test)?\.php$';
|
||||
if (! StringUtils::isMatch($smartFileInfo->getRealPath(), '#' . $suffixPattern . '#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isLocatedInExpectedLocation($groupNames, $suffixPattern, $smartFileInfo)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// file is already in the group
|
||||
if (StringUtils::isMatch($smartFileInfo->getPath(), '#' . $groupNames . '$#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->moveFileToGroupName($smartFileInfo, $this->file, $groupNames);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private function isLocatedInExpectedLocation(
|
||||
string $groupName,
|
||||
string $suffixPattern,
|
||||
SmartFileInfo $smartFileInfo
|
||||
): bool {
|
||||
$expectedLocationFilePattern = $this->expectedFileLocationResolver->resolve($groupName, $suffixPattern);
|
||||
|
||||
return StringUtils::isMatch($smartFileInfo->getRealPath(), $expectedLocationFilePattern);
|
||||
}
|
||||
|
||||
private function moveFileToGroupName(SmartFileInfo $fileInfo, File $file, string $desiredGroupName): void
|
||||
{
|
||||
$addedFileWithNodes = $this->addedFileWithNodesFactory->createWithDesiredGroup(
|
||||
$fileInfo,
|
||||
$file,
|
||||
$desiredGroupName
|
||||
);
|
||||
|
||||
if (! $addedFileWithNodes instanceof AddedFileWithNodes) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->removedAndAddedFilesCollector->removeFile($fileInfo);
|
||||
$this->removedAndAddedFilesCollector->addAddedFile($addedFileWithNodes);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user