mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-28 23:10:51 +00:00
[Renaming] Add generic rename annotation to RenameAnnotationRector (#1341)
This commit is contained in:
parent
c19a849702
commit
a30b2ef8d1
|
@ -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'),
|
||||
]),
|
||||
]]);
|
||||
};
|
||||
|
|
|
@ -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#'
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -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';
|
||||
}
|
||||
}
|
|
@ -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')]);
|
||||
};
|
||||
|
|
|
@ -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')]);
|
||||
};
|
12
rules/Renaming/Contract/RenameAnnotationInterface.php
Normal file
12
rules/Renaming/Contract/RenameAnnotationInterface.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Renaming\Contract;
|
||||
|
||||
interface RenameAnnotationInterface
|
||||
{
|
||||
public function getOldAnnotation(): string;
|
||||
|
||||
public function getNewAnnotation(): string;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
35
rules/Renaming/ValueObject/RenameAnnotationByType.php
Normal file
35
rules/Renaming/ValueObject/RenameAnnotationByType.php
Normal 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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user