From 717507e2650e276a3f88453b82a4360b9ab8cd82 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 3 Apr 2024 05:38:25 +0000 Subject: [PATCH] Updated Rector to commit 717e3e00ca93c371f8633f6ea17ea1b5e686657a https://github.com/rectorphp/rector-src/commit/717e3e00ca93c371f8633f6ea17ea1b5e686657a [Php81] Remove @readonly doc on transformation to native readonly on ReadOnlyPropertyRector (#5789) --- .../Property/ReadOnlyPropertyRector.php | 39 ++++++++++++++++++- src/Application/VersionResolver.php | 4 +- .../PhpDocInfo/PhpDocInfo.php | 14 +++++++ 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/rules/Php81/Rector/Property/ReadOnlyPropertyRector.php b/rules/Php81/Rector/Property/ReadOnlyPropertyRector.php index d6c23356540..51c175fae08 100644 --- a/rules/Php81/Rector/Property/ReadOnlyPropertyRector.php +++ b/rules/Php81/Rector/Property/ReadOnlyPropertyRector.php @@ -15,6 +15,10 @@ use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Property; use PhpParser\NodeTraverser; use PHPStan\Analyser\Scope; +use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode; +use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; +use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; +use Rector\Comments\NodeDocBlock\DocBlockUpdater; use Rector\NodeAnalyzer\ParamAnalyzer; use Rector\NodeManipulator\PropertyFetchAssignManipulator; use Rector\NodeManipulator\PropertyManipulator; @@ -60,13 +64,25 @@ final class ReadOnlyPropertyRector extends AbstractScopeAwareRector implements M * @var \Rector\PhpParser\Node\BetterNodeFinder */ private $betterNodeFinder; - public function __construct(PropertyManipulator $propertyManipulator, PropertyFetchAssignManipulator $propertyFetchAssignManipulator, ParamAnalyzer $paramAnalyzer, VisibilityManipulator $visibilityManipulator, BetterNodeFinder $betterNodeFinder) + /** + * @readonly + * @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory + */ + private $phpDocInfoFactory; + /** + * @readonly + * @var \Rector\Comments\NodeDocBlock\DocBlockUpdater + */ + private $docBlockUpdater; + public function __construct(PropertyManipulator $propertyManipulator, PropertyFetchAssignManipulator $propertyFetchAssignManipulator, ParamAnalyzer $paramAnalyzer, VisibilityManipulator $visibilityManipulator, BetterNodeFinder $betterNodeFinder, PhpDocInfoFactory $phpDocInfoFactory, DocBlockUpdater $docBlockUpdater) { $this->propertyManipulator = $propertyManipulator; $this->propertyFetchAssignManipulator = $propertyFetchAssignManipulator; $this->paramAnalyzer = $paramAnalyzer; $this->visibilityManipulator = $visibilityManipulator; $this->betterNodeFinder = $betterNodeFinder; + $this->phpDocInfoFactory = $phpDocInfoFactory; + $this->docBlockUpdater = $docBlockUpdater; } public function getRuleDefinition() : RuleDefinition { @@ -170,8 +186,28 @@ CODE_SAMPLE if ($attributeGroups !== []) { $property->setAttribute(AttributeKey::ORIGINAL_NODE, null); } + $this->removeReadOnlyDoc($property); return $property; } + /** + * @param \PhpParser\Node\Stmt\Property|\PhpParser\Node\Param $node + */ + private function removeReadOnlyDoc($node) : void + { + $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); + $readonlyDoc = $phpDocInfo->getByName('readonly'); + if (!$readonlyDoc instanceof PhpDocTagNode) { + return; + } + if (!$readonlyDoc->value instanceof GenericTagValueNode) { + return; + } + if ($readonlyDoc->value->value !== '') { + return; + } + $phpDocInfo->removeByName('readonly'); + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); + } private function refactorParam(Class_ $class, ClassMethod $classMethod, Param $param, Scope $scope) : ?\PhpParser\Node\Param { if (!$this->visibilityManipulator->hasVisibility($param, Visibility::PRIVATE)) { @@ -197,6 +233,7 @@ CODE_SAMPLE $param->setAttribute(AttributeKey::ORIGINAL_NODE, null); } $this->visibilityManipulator->makeReadonly($param); + $this->removeReadOnlyDoc($param); return $param; } private function isPromotedPropertyAssigned(Class_ $class, Param $param) : bool diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index e03fd20035d..3581a2f1e83 100644 --- a/src/Application/VersionResolver.php +++ b/src/Application/VersionResolver.php @@ -19,12 +19,12 @@ final class VersionResolver * @api * @var string */ - public const PACKAGE_VERSION = '9b4ad93acd680c5da9a3bab4d5e1f46ad5905b7f'; + public const PACKAGE_VERSION = '717e3e00ca93c371f8633f6ea17ea1b5e686657a'; /** * @api * @var string */ - public const RELEASE_DATE = '2024-04-03 11:59:45'; + public const RELEASE_DATE = '2024-04-03 07:35:59'; /** * @var int */ diff --git a/src/BetterPhpDocParser/PhpDocInfo/PhpDocInfo.php b/src/BetterPhpDocParser/PhpDocInfo/PhpDocInfo.php index 1b2322b85f0..4e201eacad0 100644 --- a/src/BetterPhpDocParser/PhpDocInfo/PhpDocInfo.php +++ b/src/BetterPhpDocParser/PhpDocInfo/PhpDocInfo.php @@ -266,6 +266,20 @@ final class PhpDocInfo }); return $hasChanged; } + public function removeByName(string $tagName) : bool + { + $tagName = '@' . \ltrim($tagName, '@'); + $hasChanged = \false; + $phpDocNodeTraverser = new PhpDocNodeTraverser(); + $phpDocNodeTraverser->traverseWithCallable($this->phpDocNode, '', static function (Node $node) use($tagName, &$hasChanged) : ?int { + if ($node instanceof PhpDocTagNode && $node->name === $tagName) { + $hasChanged = \true; + return PhpDocNodeTraverser::NODE_REMOVE; + } + return null; + }); + return $hasChanged; + } public function addTagValueNode(PhpDocTagValueNode $phpDocTagValueNode) : void { if ($phpDocTagValueNode instanceof DoctrineAnnotationTagValueNode) {