visibilityManipulator = $visibilityManipulator;
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->docBlockUpdater = $docBlockUpdater;
}
public function getRuleDefinition() : RuleDefinition
{
return new RuleDefinition('Remove useless @readonly annotation on native readonly type', [new CodeSample(<<<'CODE_SAMPLE'
final class SomeClass
{
/**
* @readonly
*/
private readonly string $name;
public function __construct(string $name)
{
$this->name = $name;
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
final class SomeClass
{
private readonly string $name;
public function __construct(string $name)
{
$this->name = $name;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array>
*/
public function getNodeTypes() : array
{
return [Class_::class, Property::class, Param::class];
}
/**
* @param Class_|Property|Param $node
*/
public function refactor(Node $node) : ?Node
{
// for param, only on property promotion
if ($node instanceof Param && $node->flags === 0) {
return null;
}
if (!$this->visibilityManipulator->isReadonly($node)) {
return null;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$readonlyDoc = $phpDocInfo->getByName('readonly');
if (!$readonlyDoc instanceof PhpDocTagNode) {
return null;
}
if (!$readonlyDoc->value instanceof GenericTagValueNode) {
return null;
}
if ($readonlyDoc->value->value !== '') {
return null;
}
$phpDocInfo->removeByName('readonly');
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node);
return $node;
}
public function provideMinPhpVersion() : int
{
return PhpVersionFeature::READONLY_PROPERTY;
}
}