[Renaming] Add generic rename annotation to RenameAnnotationRector (#1341)

This commit is contained in:
Tomas Votruba 2021-11-29 13:07:44 +03:00 committed by GitHub
parent c19a849702
commit a30b2ef8d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 167 additions and 41 deletions

View File

@ -9495,7 +9495,7 @@ Turns defined annotations above properties and methods to their new values.
```php
use Rector\Renaming\Rector\ClassMethod\RenameAnnotationRector;
use Rector\Renaming\ValueObject\RenameAnnotation;
use Rector\Renaming\ValueObject\RenameAnnotationByType;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\SymfonyPhpConfig\ValueObjectInliner;
@ -9504,8 +9504,8 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(RenameAnnotationRector::class)
->call('configure', [[
RenameAnnotationRector::RENAMED_ANNOTATIONS_IN_TYPES => ValueObjectInliner::inline([
new RenameAnnotation('PHPUnit\Framework\TestCase', 'test', 'scenario'),
RenameAnnotationRector::RENAMED_ANNOTATIONS => ValueObjectInliner::inline([
new RenameAnnotationByType('PHPUnit\Framework\TestCase', 'test', 'scenario'),
]),
]]);
};

View File

@ -607,3 +607,5 @@ parameters:
message: '#Class has a static method must so must contains "Static" in its name#'
path: src/Validation/RectorAssert.php
# fixed in symplify dev-main
- '#Parameter \#3 \$configuration of class Symplify\\RuleDocGenerator\\ValueObject\\CodeSample\\ConfiguredCodeSample constructor expects array<string, mixed\>, array<int, Rector\\Renaming\\ValueObject\\RenameAnnotationByType\> given#'

View File

@ -0,0 +1,35 @@
<?php
namespace Rector\Tests\Renaming\Rector\ClassMethod\RenameAnnotationRector\FixtureRenameEverywhere;
final class RenameEveryWhere
{
/**
* @psalm-ignore
*/
public function test()
{
/** @psalm-ignore */
$value = 1000;
}
}
?>
-----
<?php
namespace Rector\Tests\Renaming\Rector\ClassMethod\RenameAnnotationRector\FixtureRenameEverywhere;
final class RenameEveryWhere
{
/**
* @phpstan-ignore
*/
public function test()
{
/** @phpstan-ignore */
$value = 1000;
}
}
?>

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\Renaming\Rector\ClassMethod\RenameAnnotationRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class RenameAnnotationEverywhereRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/FixtureRenameEverywhere');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/rename_everywhere.php';
}
}

View File

@ -3,18 +3,11 @@
declare(strict_types=1);
use Rector\Renaming\Rector\ClassMethod\RenameAnnotationRector;
use Rector\Renaming\ValueObject\RenameAnnotation;
use Rector\Renaming\ValueObject\RenameAnnotationByType;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\SymfonyPhpConfig\ValueObjectInliner;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(RenameAnnotationRector::class)
->call('configure', [[
RenameAnnotationRector::RENAMED_ANNOTATIONS_IN_TYPES => ValueObjectInliner::inline([
new RenameAnnotation('PHPUnit\Framework\TestCase', 'scenario', 'test'),
]),
]]);
->configure([new RenameAnnotationByType('PHPUnit\Framework\TestCase', 'scenario', 'test')]);
};

View File

@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
use Rector\Renaming\Rector\ClassMethod\RenameAnnotationRector;
use Rector\Renaming\ValueObject\RenameAnnotation;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(RenameAnnotationRector::class)
->configure([new RenameAnnotation('psalm-ignore', 'phpstan-ignore')]);
};

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Rector\Renaming\Contract;
interface RenameAnnotationInterface
{
public function getOldAnnotation(): string;
public function getNewAnnotation(): string;
}

View File

@ -7,11 +7,13 @@ namespace Rector\Renaming\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Property;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockTagReplacer;
use Rector\Renaming\ValueObject\RenameAnnotation;
use Rector\Renaming\Contract\RenameAnnotationInterface;
use Rector\Renaming\ValueObject\RenameAnnotationByType;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use Webmozart\Assert\Assert;
@ -24,12 +26,12 @@ final class RenameAnnotationRector extends AbstractRector implements Configurabl
/**
* @var string
*/
public const RENAMED_ANNOTATIONS_IN_TYPES = 'renamed_annotations_in_types';
public const RENAMED_ANNOTATIONS = 'renamed_annotations';
/**
* @var RenameAnnotation[]
* @var RenameAnnotationInterface[]
*/
private array $renamedAnnotations = [];
private array $renameAnnotations = [];
public function __construct(
private DocBlockTagReplacer $docBlockTagReplacer
@ -43,7 +45,9 @@ final class RenameAnnotationRector extends AbstractRector implements Configurabl
[
new ConfiguredCodeSample(
<<<'CODE_SAMPLE'
class SomeTest extends PHPUnit\Framework\TestCase
use PHPUnit\Framework\TestCase;
final class SomeTest extends TestCase
{
/**
* @test
@ -55,7 +59,9 @@ class SomeTest extends PHPUnit\Framework\TestCase
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
class SomeTest extends PHPUnit\Framework\TestCase
use PHPUnit\Framework\TestCase;
final class SomeTest extends TestCase
{
/**
* @scenario
@ -66,11 +72,7 @@ class SomeTest extends PHPUnit\Framework\TestCase
}
CODE_SAMPLE
,
[
self::RENAMED_ANNOTATIONS_IN_TYPES => [
new RenameAnnotation('PHPUnit\Framework\TestCase', 'test', 'scenario'),
],
]
[new RenameAnnotationByType('PHPUnit\Framework\TestCase', 'test', 'scenario')]
),
]
);
@ -81,7 +83,7 @@ CODE_SAMPLE
*/
public function getNodeTypes(): array
{
return [ClassMethod::class, Property::class];
return [ClassMethod::class, Property::class, Expression::class];
}
/**
@ -96,15 +98,18 @@ CODE_SAMPLE
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
foreach ($this->renamedAnnotations as $renamedAnnotation) {
if (! $this->isObjectType($classLike, $renamedAnnotation->getObjectType())) {
foreach ($this->renameAnnotations as $renameAnnotation) {
if ($renameAnnotation instanceof RenameAnnotationByType && ! $this->isObjectType(
$classLike,
$renameAnnotation->getObjectType()
)) {
continue;
}
$this->docBlockTagReplacer->replaceTagByAnother(
$phpDocInfo,
$renamedAnnotation->getOldAnnotation(),
$renamedAnnotation->getNewAnnotation()
$renameAnnotation->getOldAnnotation(),
$renameAnnotation->getNewAnnotation()
);
}
@ -116,8 +121,11 @@ CODE_SAMPLE
*/
public function configure(array $configuration): void
{
$renamedAnnotationsInTypes = $configuration[self::RENAMED_ANNOTATIONS_IN_TYPES] ?? $configuration;
Assert::allIsAOf($renamedAnnotationsInTypes, RenameAnnotation::class);
$this->renamedAnnotations = $renamedAnnotationsInTypes;
$renamedAnnotations = $configuration[self::RENAMED_ANNOTATIONS] ?? $configuration;
Assert::isArray($renamedAnnotations);
Assert::allIsAOf($renamedAnnotations, RenameAnnotationInterface::class);
$this->renameAnnotations = $renamedAnnotations;
}
}

View File

@ -4,22 +4,17 @@ declare(strict_types=1);
namespace Rector\Renaming\ValueObject;
use PHPStan\Type\ObjectType;
use Rector\Core\Validation\RectorAssert;
use Rector\Renaming\Contract\RenameAnnotationInterface;
final class RenameAnnotation
/**
* @api
*/
final class RenameAnnotation implements RenameAnnotationInterface
{
public function __construct(
private string $type,
private string $oldAnnotation,
private string $newAnnotation
) {
RectorAssert::className($type);
}
public function getObjectType(): ObjectType
{
return new ObjectType($this->type);
}
public function getOldAnnotation(): string

View File

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace Rector\Renaming\ValueObject;
use PHPStan\Type\ObjectType;
use Rector\Core\Validation\RectorAssert;
use Rector\Renaming\Contract\RenameAnnotationInterface;
final class RenameAnnotationByType implements RenameAnnotationInterface
{
public function __construct(
private string $type,
private string $oldAnnotation,
private string $newAnnotation
) {
RectorAssert::className($type);
}
public function getObjectType(): ObjectType
{
return new ObjectType($this->type);
}
public function getOldAnnotation(): string
{
return $this->oldAnnotation;
}
public function getNewAnnotation(): string
{
return $this->newAnnotation;
}
}