Add new option for auto importing names (#764)

* Add new option for auto importing names

- In order to apply the Option::AUTO_IMPORT_NAMES only on those files which are really changed by a rector we introduce this new option

* [ci-review] Rector Rectify

* Update packages/PostRector/Rector/NameImportingPostRector.php

Co-authored-by: Abdul Malik Ikhsan <samsonasik@gmail.com>

* [ci-review] Rector Rectify

Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Abdul Malik Ikhsan <samsonasik@gmail.com>
This commit is contained in:
Sebastian Schreiber 2021-09-16 23:45:44 +02:00 committed by GitHub
parent e22645de4f
commit 0315a82d57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 157 additions and 2 deletions

View File

@ -1,6 +1,6 @@
# Auto Import Names
Rector works with all class names as fully qualified by default, so it know the exact types. In most coding standard, that's not desired behavior, because short version with `use` statement is preferred:
Rector works with all class names as fully qualified by default, so it knows the exact types. In most coding standard, that's not desired behavior, because short version with `use` statement is preferred:
```diff
-$object = new \App\Some\Namespace\SomeClass();
@ -48,6 +48,16 @@ Do you want to keep those?
$parameters->set(Option::IMPORT_SHORT_CLASSES, false);
```
<br>
If you have set Option::AUTO_IMPORT_NAMES to true, rector is applying this to every analyzed file, even if no real change by a rector was applied to the file.
The reason is that a so-called post rector is responsible for this, namely the NameImportingPostRector.
If you like to apply the Option::AUTO_IMPORT_NAMES only for real changed files, you can configure this.
```php
$parameters->set(Option::APPLY_AUTO_IMPORT_NAMES_ON_CHANGED_FILES_ONLY, true);
```
## How to Remove Unused Imports?
To remove imports, use [ECS](github.com/symplify/easy-coding-standard) with [`NoUnusedImportsFixer`](https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/2.18/doc/rules/import/no_unused_imports.rst) rule:

View File

@ -40,12 +40,17 @@ final class NameImportingPostRector extends AbstractPostRector
return null;
}
$file = $this->currentFileProvider->getFile();
if ($node instanceof Name) {
$file = $this->currentFileProvider->getFile();
if (! $file instanceof File) {
return null;
}
if (! $this->shouldApply($file)) {
return null;
}
return $this->processNodeName($node, $file);
}
@ -53,6 +58,10 @@ final class NameImportingPostRector extends AbstractPostRector
return null;
}
if ($file instanceof File && ! $this->shouldApply($file)) {
return null;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$this->docBlockNameImporter->importNames($phpDocInfo->getPhpDocNode(), $node);
@ -128,4 +137,13 @@ CODE_SAMPLE
return $this->reflectionProvider->hasFunction(new Name($name->getLast()), null);
}
private function shouldApply(File $file): bool
{
if (! $this->parameterProvider->provideBoolParameter(Option::APPLY_AUTO_IMPORT_NAMES_ON_CHANGED_FILES_ONLY)) {
return true;
}
return $file->hasContentChanged();
}
}

View File

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
/**
* @see \Rector\PostRector\Rector\NameImportingPostRector
*/
final class AutoImportNamesOnlyOnChangedFilesTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/FixtureNameImportingOnChangedFiles');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/import_only_on_changed_files_config.php';
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector\FixtureNameImportingOnChangedFiles;
class AutoImportNamesOnChangedFile
{
/**
* @var \Rector\Tests\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector\Source\NormalParamClass
*/
private $some;
public function __construct(\Rector\Tests\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector\Source\NormalParamClass $some)
{
$this->some = $some;
}
}
?>
-----
<?php
namespace Rector\Tests\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector\FixtureNameImportingOnChangedFiles;
use Rector\Tests\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector\Source\NormalReturnClass;
class AutoImportNamesOnChangedFile
{
/**
* @var NormalReturnClass
*/
private $some;
public function __construct(NormalReturnClass $some)
{
$this->some = $some;
}
}
?>

View File

@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector\FixtureNameImportingOnChangedFiles;
class SkipAutoImportNameNoChange
{
/**
* @var \SomeAnother\AnotherClass
*/
public $some;
public function __construct(\SomeAnother\AnotherClass $some)
{
$this->some = $some;
}
}
?>

View File

@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Rector\Renaming\Rector\Name\RenameClassRector;
use Rector\Tests\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector\Source\NormalParamClass;
use Rector\Tests\CodingStyle\Rector\Namespace_\ImportFullyQualifiedNamesRector\Source\NormalReturnClass;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::AUTO_IMPORT_NAMES, true);
$parameters->set(Option::IMPORT_DOC_BLOCKS, true);
$parameters->set(Option::APPLY_AUTO_IMPORT_NAMES_ON_CHANGED_FILES_ONLY, true);
$services = $containerConfigurator->services();
$services->set(RenameClassRector::class)
->call('configure', [[
RenameClassRector::OLD_TO_NEW_CLASSES => [
NormalParamClass::class => NormalReturnClass::class,
],
]]);
};

View File

@ -170,4 +170,9 @@ final class Option
* @var string
*/
public const OUTPUT_FORMAT_SHORT = 'o';
/**
* @var string
*/
public const APPLY_AUTO_IMPORT_NAMES_ON_CHANGED_FILES_ONLY = 'apply_auto_import_names_on_changed_files_only';
}

View File

@ -73,6 +73,11 @@ final class File
$this->hasChanged = true;
}
public function hasContentChanged(): bool
{
return $this->fileContent !== $this->originalFileContent;
}
public function getOriginalFileContent(): string
{
return $this->originalFileContent;