diff --git a/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocTagRemover.php b/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocTagRemover.php index 617cf86ba7d..dc30d22f725 100644 --- a/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocTagRemover.php +++ b/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocTagRemover.php @@ -15,7 +15,6 @@ final class PhpDocTagRemover public function removeByName(PhpDocInfo $phpDocInfo, string $name): bool { $hasChanged = false; - $phpDocNode = $phpDocInfo->getPhpDocNode(); foreach ($phpDocNode->children as $key => $phpDocChildNode) { @@ -26,7 +25,6 @@ public function removeByName(PhpDocInfo $phpDocInfo, string $name): bool if ($this->areAnnotationNamesEqual($name, $phpDocChildNode->name)) { unset($phpDocNode->children[$key]); $hasChanged = true; - $phpDocInfo->markAsChanged(); } if ($phpDocChildNode->value instanceof DoctrineAnnotationTagValueNode && $phpDocChildNode->value->hasClassName( @@ -34,24 +32,24 @@ public function removeByName(PhpDocInfo $phpDocInfo, string $name): bool )) { unset($phpDocNode->children[$key]); $hasChanged = true; - $phpDocInfo->markAsChanged(); } } return $hasChanged; } - public function removeTagValueFromNode(PhpDocInfo $phpDocInfo, Node $desiredNode): void + public function removeTagValueFromNode(PhpDocInfo $phpDocInfo, Node $desiredNode): bool { $phpDocNode = $phpDocInfo->getPhpDocNode(); + $hasChanged = false; $phpDocNodeTraverser = new PhpDocNodeTraverser(); $phpDocNodeTraverser->traverseWithCallable($phpDocNode, '', static function (Node $node) use ( $desiredNode, - $phpDocInfo + &$hasChanged ): ?int { if ($node instanceof PhpDocTagNode && $node->value === $desiredNode) { - $phpDocInfo->markAsChanged(); + $hasChanged = true; return PhpDocNodeTraverser::NODE_REMOVE; } @@ -59,10 +57,11 @@ public function removeTagValueFromNode(PhpDocInfo $phpDocInfo, Node $desiredNode return null; } - $phpDocInfo->markAsChanged(); - + $hasChanged = true; return PhpDocNodeTraverser::NODE_REMOVE; }); + + return $hasChanged; } private function areAnnotationNamesEqual(string $firstAnnotationName, string $secondAnnotationName): bool diff --git a/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocTypeChanger.php b/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocTypeChanger.php index 69c356dd961..edc7e25ecf2 100644 --- a/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocTypeChanger.php +++ b/packages/BetterPhpDocParser/PhpDocManipulator/PhpDocTypeChanger.php @@ -95,7 +95,6 @@ public function changeVarType(Stmt $stmt, PhpDocInfo $phpDocInfo, Type $newType) if ($currentVarTagValueNode instanceof VarTagValueNode) { // only change type $currentVarTagValueNode->type = $newPHPStanPhpDocTypeNode; - $phpDocInfo->markAsChanged(); } else { // add completely new one $varTagValueNode = new VarTagValueNode($newPHPStanPhpDocTypeNode, '', ''); diff --git a/packages/Comments/NodeDocBlock/DocBlockUpdater.php b/packages/Comments/NodeDocBlock/DocBlockUpdater.php index 7ce8b5bebc8..526d27d9faf 100644 --- a/packages/Comments/NodeDocBlock/DocBlockUpdater.php +++ b/packages/Comments/NodeDocBlock/DocBlockUpdater.php @@ -42,7 +42,7 @@ public function updateNodeWithPhpDocInfo(Node $node): void public function updateRefactoredNodeWithPhpDocInfo(Node $node): void { // nothing to change? don't save it - $phpDocInfo = $this->resolveChangedPhpDocInfo($node); + $phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO); if (! $phpDocInfo instanceof PhpDocInfo) { return; } @@ -53,7 +53,9 @@ public function updateRefactoredNodeWithPhpDocInfo(Node $node): void return; } - $node->setDocComment(new Doc((string) $phpDocNode)); + $printedPhpDoc = $this->printPhpDocInfoToString($phpDocInfo); + $node->setDocComment(new Doc($printedPhpDoc)); + // $node->setDocComment(new Doc((string) $phpDocNode)); } private function setCommentsAttribute(Node $node): void diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/multi_properties.php b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/multi_properties.php new file mode 100644 index 00000000000..83b8866ed14 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineConstructorDefaultToPropertyRector/Fixture/multi_properties.php @@ -0,0 +1,17 @@ +thing1 = 1; + $this->thing2 = 2; + $this->thing3 = 3; + } +} + +?> diff --git a/rules/DeadCode/Rector/ClassLike/RemoveAnnotationRector.php b/rules/DeadCode/Rector/ClassLike/RemoveAnnotationRector.php index eac0c3f4493..a37748fe712 100644 --- a/rules/DeadCode/Rector/ClassLike/RemoveAnnotationRector.php +++ b/rules/DeadCode/Rector/ClassLike/RemoveAnnotationRector.php @@ -12,6 +12,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover; +use Rector\Comments\NodeDocBlock\DocBlockUpdater; use Rector\Core\Contract\Rector\ConfigurableRectorInterface; use Rector\Core\Rector\AbstractRector; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; @@ -29,7 +30,8 @@ final class RemoveAnnotationRector extends AbstractRector implements Configurabl private array $annotationsToRemove = []; public function __construct( - private readonly PhpDocTagRemover $phpDocTagRemover + private readonly PhpDocTagRemover $phpDocTagRemover, + private readonly DocBlockUpdater $docBlockUpdater, ) { } @@ -96,6 +98,8 @@ public function refactor(Node $node): ?Node } if ($hasChanged) { + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); + return $node; } diff --git a/rules/DeadCode/Rector/ClassMethod/RemoveUnusedPrivateMethodParameterRector.php b/rules/DeadCode/Rector/ClassMethod/RemoveUnusedPrivateMethodParameterRector.php index e9826a3e485..88f4ab08cad 100644 --- a/rules/DeadCode/Rector/ClassMethod/RemoveUnusedPrivateMethodParameterRector.php +++ b/rules/DeadCode/Rector/ClassMethod/RemoveUnusedPrivateMethodParameterRector.php @@ -12,6 +12,7 @@ use PhpParser\Node\Stmt\ClassMethod; use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode; use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover; +use Rector\Comments\NodeDocBlock\DocBlockUpdater; use Rector\Core\Rector\AbstractRector; use Rector\DeadCode\NodeCollector\UnusedParameterResolver; use Rector\DeadCode\NodeManipulator\VariadicFunctionLikeDetector; @@ -26,7 +27,8 @@ final class RemoveUnusedPrivateMethodParameterRector extends AbstractRector public function __construct( private readonly VariadicFunctionLikeDetector $variadicFunctionLikeDetector, private readonly UnusedParameterResolver $unusedParameterResolver, - private readonly PhpDocTagRemover $phpDocTagRemover + private readonly PhpDocTagRemover $phpDocTagRemover, + private readonly DocBlockUpdater $docBlockUpdater, ) { } @@ -201,6 +203,7 @@ private function shouldSkipClassMethod(ClassMethod $classMethod): bool private function clearPhpDocInfo(ClassMethod $classMethod, array $unusedParameters): void { $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod); + $hasChanged = false; foreach ($unusedParameters as $unusedParameter) { $parameterName = $this->getName($unusedParameter->var); @@ -217,7 +220,11 @@ private function clearPhpDocInfo(ClassMethod $classMethod, array $unusedParamete continue; } - $this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $paramTagValueNode); + $hasChanged = $this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $paramTagValueNode); + } + + if ($hasChanged) { + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($classMethod); } } } diff --git a/rules/Php80/Rector/Class_/AnnotationToAttributeRector.php b/rules/Php80/Rector/Class_/AnnotationToAttributeRector.php index 027125c4028..4352c319dbe 100644 --- a/rules/Php80/Rector/Class_/AnnotationToAttributeRector.php +++ b/rules/Php80/Rector/Class_/AnnotationToAttributeRector.php @@ -21,6 +21,7 @@ use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover; +use Rector\Comments\NodeDocBlock\DocBlockUpdater; use Rector\Core\Contract\Rector\ConfigurableRectorInterface; use Rector\Core\Rector\AbstractRector; use Rector\Core\ValueObject\PhpVersionFeature; @@ -58,7 +59,8 @@ public function __construct( private readonly PhpDocTagRemover $phpDocTagRemover, private readonly AttributeGroupNamedArgumentManipulator $attributeGroupNamedArgumentManipulator, private readonly UseImportsResolver $useImportsResolver, - private readonly PhpAttributeAnalyzer $phpAttributeAnalyzer + private readonly PhpAttributeAnalyzer $phpAttributeAnalyzer, + private readonly DocBlockUpdater $docBlockUpdater, ) { } @@ -141,6 +143,9 @@ public function refactor(Node $node): ?Node return null; } + // 3. Reprint docblock + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); + $this->attributeGroupNamedArgumentManipulator->decorate($attributeGroups); $node->attrGroups = array_merge($node->attrGroups, $attributeGroups); diff --git a/rules/Php80/Rector/Property/NestedAnnotationToAttributeRector.php b/rules/Php80/Rector/Property/NestedAnnotationToAttributeRector.php index 3afaa11f707..d1ebdc2445f 100644 --- a/rules/Php80/Rector/Property/NestedAnnotationToAttributeRector.php +++ b/rules/Php80/Rector/Property/NestedAnnotationToAttributeRector.php @@ -14,6 +14,7 @@ use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover; use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey; +use Rector\Comments\NodeDocBlock\DocBlockUpdater; use Rector\Core\Contract\Rector\ConfigurableRectorInterface; use Rector\Core\Rector\AbstractRector; use Rector\Core\ValueObject\PhpVersion; @@ -46,7 +47,8 @@ public function __construct( private readonly UseImportsResolver $useImportsResolver, private readonly PhpDocTagRemover $phpDocTagRemover, private readonly NestedAttrGroupsFactory $nestedAttrGroupsFactory, - private readonly UseNodesToAddCollector $useNodesToAddCollector + private readonly UseNodesToAddCollector $useNodesToAddCollector, + private readonly DocBlockUpdater $docBlockUpdater, ) { } @@ -121,6 +123,9 @@ public function refactor(Node $node): ?Node return null; } + // 3. Reprint docblock + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); + $node->attrGroups = array_merge($node->attrGroups, $attributeGroups); $this->completeExtraUseImports($attributeGroups); diff --git a/src/ValueObject/PhpVersionFeature.php b/src/ValueObject/PhpVersionFeature.php index 2ec25a5ec58..c9048315e8b 100644 --- a/src/ValueObject/PhpVersionFeature.php +++ b/src/ValueObject/PhpVersionFeature.php @@ -70,10 +70,6 @@ final class PhpVersionFeature */ public const CLASSNAME_CONSTANT = PhpVersion::PHP_55; - /* - * @var int - */ - /** * @var int */