[PSR-4] Add NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRector

This commit is contained in:
TomasVotruba 2020-05-14 01:34:05 +02:00
parent b651f80b2d
commit 8a28581ce1
7 changed files with 111 additions and 3 deletions

View File

@ -1,4 +1,4 @@
# All 482 Rectors Overview
# All 483 Rectors Overview
- [Projects](#projects)
- [General](#general)
@ -32,7 +32,7 @@
- [PHPStan](#phpstan) (3)
- [PHPUnit](#phpunit) (37)
- [PHPUnitSymfony](#phpunitsymfony) (1)
- [PSR4](#psr4) (2)
- [PSR4](#psr4) (3)
- [Performance](#performance) (1)
- [Phalcon](#phalcon) (4)
- [Php52](#php52) (2)
@ -6218,9 +6218,18 @@ Turns namespaced classes in one file to standalone PSR-4 classes.
<br>
### `NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRector`
- class: [`Rector\PSR4\Rector\FileSystem\NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRector`](/../master/rules/psr4/src/Rector/FileSystem/NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRector.php)
Adds namespace to namespace-less files to match PSR-4 in composer.json autoload section. Run with combination with Rector\PSR4\Rector\MultipleClassFileToPsr4ClassesRector
<br>
### `NormalizeNamespaceByPSR4ComposerAutoloadRector`
- class: [`Rector\PSR4\Rector\Namespace_\NormalizeNamespaceByPSR4ComposerAutoloadRector`](/../master/rules/psr4/src/Rector/Namespace_/NormalizeNamespaceByPSR4ComposerAutoloadRector.php)
- [test fixtures](/../master/rules/psr4/tests/Rector/Namespace_/NormalizeNamespaceByPSR4ComposerAutoloadRector/Fixture)
Changes namespace and class names to match PSR-4 in composer.json autoload section

View File

@ -307,3 +307,4 @@ parameters:
- '#Access to an undefined property PhpParser\\Node\\Expr\:\:\$class#'
- '#Method Rector\\BetterPhpDocParser\\Tests\\PhpDocParser\\AbstractPhpDocInfoTest\:\:parseFileAndGetFirstNodeOfType\(\) should return PhpParser\\Node but returns PhpParser\\Node\|null#'
- '#Method Rector\\Core\\Testing\\Finder\\RectorsFinder\:\:findInDirectories\(\) should return array<Rector\\Core\\Contract\\Rector\\RectorInterface\> but returns array<object\>#'
- '#Property PhpParser\\Node\\Stmt\\Namespace_\:\:\$stmts \(array<PhpParser\\Node\\Stmt\>\) does not accept array<PhpParser\\Node\>#'

View File

@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace Rector\PSR4\Rector\FileSystem;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Namespace_;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\FileSystemRector\Rector\AbstractFileSystemRector;
use Rector\PSR4\Contract\PSR4AutoloadNamespaceMatcherInterface;
use Rector\PSR4\Rector\MultipleClassFileToPsr4ClassesRector;
use Symplify\SmartFileSystem\SmartFileInfo;
/**
* @see \Rector\PSR4\Tests\Rector\FileSystem\NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRector\NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRectorTest
*/
final class NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRector extends AbstractFileSystemRector
{
/**
* @var PSR4AutoloadNamespaceMatcherInterface
*/
private $psr4AutoloadNamespaceMatcher;
public function __construct(PSR4AutoloadNamespaceMatcherInterface $psr4AutoloadNamespaceMatcher)
{
$this->psr4AutoloadNamespaceMatcher = $psr4AutoloadNamespaceMatcher;
}
public function getDefinition(): RectorDefinition
{
$description = sprintf(
'Adds namespace to namespace-less files to match PSR-4 in composer.json autoload section. Run with combination with %s',
MultipleClassFileToPsr4ClassesRector::class
);
return new RectorDefinition($description);
}
public function refactor(SmartFileInfo $smartFileInfo): void
{
$nodes = $this->parseFileInfoToNodes($smartFileInfo);
/** @var Namespace_|null $namespace */
$namespace = $this->betterNodeFinder->findFirstInstanceOf($nodes, Namespace_::class);
if ($namespace !== null) {
return;
}
$expectedNamespace = $this->psr4AutoloadNamespaceMatcher->getExpectedNamespace($nodes[0]);
if ($expectedNamespace === null) {
return;
}
$namespace = new Namespace_(new Name($expectedNamespace));
$namespace->stmts = $nodes;
$this->printNewNodesToFilePath([$namespace], $smartFileInfo->getRealPath());
}
}

View File

@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace Rector\PSR4\Tests\Rector\FileSystem\NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRector;
use Rector\Core\Testing\PHPUnit\AbstractFileSystemRectorTestCase;
use Rector\PSR4\Rector\FileSystem\NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRector;
final class NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRectorTest extends AbstractFileSystemRectorTestCase
{
public function test(): void
{
$this->doTestFile(__DIR__ . '/Source/namespace_less_class.php.inc');
$this->assertFileExists(__DIR__ . '/Fixture/namespace_less_class.php.inc');
$this->assertFileEquals(
__DIR__ . '/Source/ExpectedNamespaceLessClass.php',
__DIR__ . '/Fixture/namespace_less_class.php.inc'
);
}
protected function getRectorClass(): string
{
return NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRector::class;
}
}

View File

@ -0,0 +1,7 @@
<?php
namespace Rector\PSR4\Tests\Rector\FileSystem\NormalizeNamespaceByPSR4ComposerAutoloadFileSystemRector\Fixture;
class NamespaceLessClass
{
}

View File

@ -101,7 +101,6 @@ final class FileProcessor
$this->currentFileInfoProvider->setCurrentFileInfo($smartFileInfo);
[$newStmts, $oldStmts, $oldTokens] = $this->parseAndTraverseFileInfoToNodes($smartFileInfo);
if ($newStmts === null) {
throw new ShouldNotHappenException(sprintf(
'Parsing of file "%s" went wrong. Might be caused by inlinced html. Does it have full "<?php" openings? Try re-run with --debug option to find out more.',