From 1926083a7b9cae8ed6524397c16fd3b2c2e4d007 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Tue, 6 Jan 2026 14:22:30 +0100 Subject: [PATCH 1/3] [phpstan] enable deprecated rules --- composer.json | 1 + phpstan.neon | 6 ++++ src/Set/SymfonySetList.php | 33 ++++++++++++++++++-- src/ValueObjectFactory/ServiceMapFactory.php | 2 +- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 3c2291847..a6cd886c6 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ "phpecs/phpecs": "^2.2", "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2.1.32", + "phpstan/phpstan-deprecation-rules": "^2.0", "phpstan/phpstan-webmozart-assert": "^2.0", "phpunit/phpunit": "^11.5", "rector/jack": "^0.4", diff --git a/phpstan.neon b/phpstan.neon index f9823a904..2fec926b6 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -71,3 +71,9 @@ parameters: # local use php 8.3 - identifier: typeCoverage.constantTypeCoverage + + # in tests + - + message: '#Fetching deprecated class constant SYMFONY_\d+ of class Rector\\Symfony\\Set\\SymfonySetList#' + path: tests + diff --git a/src/Set/SymfonySetList.php b/src/Set/SymfonySetList.php index c472104e4..ee38b74d1 100644 --- a/src/Set/SymfonySetList.php +++ b/src/Set/SymfonySetList.php @@ -5,8 +5,6 @@ namespace Rector\Symfony\Set; /** - * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead - * * @api */ final class SymfonySetList @@ -17,101 +15,121 @@ final class SymfonySetList public const CONFIGS = __DIR__ . '/../../config/sets/symfony/configs.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_25 = __DIR__ . '/../../config/sets/symfony/symfony25.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_26 = __DIR__ . '/../../config/sets/symfony/symfony26.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_27 = __DIR__ . '/../../config/sets/symfony/symfony27.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_28 = __DIR__ . '/../../config/sets/symfony/symfony28.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_30 = __DIR__ . '/../../config/sets/symfony/symfony3/symfony30.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_31 = __DIR__ . '/../../config/sets/symfony/symfony3/symfony31.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_32 = __DIR__ . '/../../config/sets/symfony/symfony3/symfony32.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_33 = __DIR__ . '/../../config/sets/symfony/symfony3/symfony33.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_34 = __DIR__ . '/../../config/sets/symfony/symfony3/symfony34.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_40 = __DIR__ . '/../../config/sets/symfony/symfony4/symfony40.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_41 = __DIR__ . '/../../config/sets/symfony/symfony4/symfony41.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_42 = __DIR__ . '/../../config/sets/symfony/symfony4/symfony42.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_43 = __DIR__ . '/../../config/sets/symfony/symfony4/symfony43.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_44 = __DIR__ . '/../../config/sets/symfony/symfony4/symfony44.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_50 = __DIR__ . '/../../config/sets/symfony/symfony5/symfony50.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_50_TYPES = __DIR__ . '/../../config/sets/symfony/symfony5/symfony50/symfony50-types.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_51 = __DIR__ . '/../../config/sets/symfony/symfony5/symfony51.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_52 = __DIR__ . '/../../config/sets/symfony/symfony5/symfony52.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_53 = __DIR__ . '/../../config/sets/symfony/symfony5/symfony53.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_54 = __DIR__ . '/../../config/sets/symfony/symfony5/symfony54.php'; @@ -123,56 +141,67 @@ final class SymfonySetList public const SYMFONY_52_VALIDATOR_ATTRIBUTES = __DIR__ . '/../../config/sets/symfony/symfony5/symfony52-validator-attributes.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_60 = __DIR__ . '/../../config/sets/symfony/symfony6/symfony60.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_61 = __DIR__ . '/../../config/sets/symfony/symfony6/symfony61.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_62 = __DIR__ . '/../../config/sets/symfony/symfony6/symfony62.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_63 = __DIR__ . '/../../config/sets/symfony/symfony6/symfony63.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_64 = __DIR__ . '/../../config/sets/symfony/symfony6/symfony64.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_70 = __DIR__ . '/../../config/sets/symfony/symfony7/symfony70.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_71 = __DIR__ . '/../../config/sets/symfony/symfony7/symfony71.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_72 = __DIR__ . '/../../config/sets/symfony/symfony7/symfony72.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_73 = __DIR__ . '/../../config/sets/symfony/symfony7/symfony73.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_74 = __DIR__ . '/../../config/sets/symfony/symfony7/symfony74.php'; /** + * @deprecated Set list are too generic and do not handle package differences. Use ->withComposerBased(symfony: true) instead * @var string */ public const SYMFONY_80 = __DIR__ . '/../../config/sets/symfony/symfony8/symfony80.php'; diff --git a/src/ValueObjectFactory/ServiceMapFactory.php b/src/ValueObjectFactory/ServiceMapFactory.php index bab945abf..18db8d735 100644 --- a/src/ValueObjectFactory/ServiceMapFactory.php +++ b/src/ValueObjectFactory/ServiceMapFactory.php @@ -188,7 +188,7 @@ private function createTagsFromData(array $tagsData): array */ private function convertXmlToArray(SimpleXMLElement $simpleXMLElement): array { - $data = Json::decode(Json::encode((array) $simpleXMLElement), Json::FORCE_ARRAY); + $data = Json::decode(Json::encode((array) $simpleXMLElement), true); $data = $this->unWrapAttributes($data); From c203a8351fb17525e5610f2e5feace500117332e Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Tue, 6 Jan 2026 14:23:19 +0100 Subject: [PATCH 2/3] update file node --- phpstan.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index 2fec926b6..45e022dfc 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -12,7 +12,7 @@ parameters: # see https://phpstan.org/writing-php-code/phpdoc-types#global-type-aliases typeAliases: - StmtsAware: \PhpParser\Node\Stmt\Block | \PhpParser\Node\Expr\Closure | \PhpParser\Node\Stmt\Case_ | \PhpParser\Node\Stmt\Catch_ | \PhpParser\Node\Stmt\ClassMethod | \PhpParser\Node\Stmt\Do_ | \PhpParser\Node\Stmt\Else_ | \PhpParser\Node\Stmt\ElseIf_ | \PhpParser\Node\Stmt\Finally_ | \PhpParser\Node\Stmt\For_ | \PhpParser\Node\Stmt\Foreach_ | \PhpParser\Node\Stmt\Function_ | \PhpParser\Node\Stmt\If_ | \PhpParser\Node\Stmt\Namespace_ | \PhpParser\Node\Stmt\TryCatch | \PhpParser\Node\Stmt\While_ | \Rector\PhpParser\Node\CustomNode\FileWithoutNamespace + StmtsAware: \PhpParser\Node\Stmt\Block | \PhpParser\Node\Expr\Closure | \PhpParser\Node\Stmt\Case_ | \PhpParser\Node\Stmt\Catch_ | \PhpParser\Node\Stmt\ClassMethod | \PhpParser\Node\Stmt\Do_ | \PhpParser\Node\Stmt\Else_ | \PhpParser\Node\Stmt\ElseIf_ | \PhpParser\Node\Stmt\Finally_ | \PhpParser\Node\Stmt\For_ | \PhpParser\Node\Stmt\Foreach_ | \PhpParser\Node\Stmt\Function_ | \PhpParser\Node\Stmt\If_ | \PhpParser\Node\Stmt\Namespace_ | \PhpParser\Node\Stmt\TryCatch | \PhpParser\Node\Stmt\While_ | \Rector\PhpParser\Node\FileNode reportUnmatchedIgnoredErrors: false treatPhpDocTypesAsCertain: false From 4d32bd89c0b48d53d7ef9444f8b785f65f08a59c Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Tue, 6 Jan 2026 14:24:47 +0100 Subject: [PATCH 3/3] cleanup stmts aware and file node --- config/sets/symfony/symfony-code-quality.php | 1 - phpstan.neon | 6 ++++-- .../ClassMethod/TemplateAnnotationToThisRenderRector.php | 6 ++++-- rules/Symfony42/Rector/New_/RootNodeTreeBuilderRector.php | 6 ++++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/config/sets/symfony/symfony-code-quality.php b/config/sets/symfony/symfony-code-quality.php index 0d48bf2a3..58130026a 100644 --- a/config/sets/symfony/symfony-code-quality.php +++ b/config/sets/symfony/symfony-code-quality.php @@ -15,7 +15,6 @@ use Rector\Symfony\CodeQuality\Rector\ClassMethod\ParamTypeFromRouteRequiredRegexRector; use Rector\Symfony\CodeQuality\Rector\ClassMethod\RemoveUnusedRequestParamRector; use Rector\Symfony\CodeQuality\Rector\ClassMethod\ResponseReturnTypeControllerActionRector; -use Rector\Symfony\CodeQuality\Rector\ClassMethod\ReturnDirectJsonResponseRector; use Rector\Symfony\CodeQuality\Rector\MethodCall\AssertSameResponseCodeWithDebugContentsRector; use Rector\Symfony\CodeQuality\Rector\MethodCall\LiteralGetToRequestClassConstantRector; use Rector\Symfony\CodeQuality\Rector\MethodCall\ParameterBagTypedGetMethodCallRector; diff --git a/phpstan.neon b/phpstan.neon index 45e022dfc..1b740fbcf 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -74,6 +74,8 @@ parameters: # in tests - - message: '#Fetching deprecated class constant SYMFONY_\d+ of class Rector\\Symfony\\Set\\SymfonySetList#' - path: tests + message: '#Fetching deprecated class constant SYMFONY_(.*?) of class Rector\\Symfony\\Set\\SymfonySetList#' + paths: + - tests + - config/sets/symfony/annotations-to-attributes.php diff --git a/rules/CodeQuality/Rector/ClassMethod/TemplateAnnotationToThisRenderRector.php b/rules/CodeQuality/Rector/ClassMethod/TemplateAnnotationToThisRenderRector.php index 4fcaa3879..9844874ea 100644 --- a/rules/CodeQuality/Rector/ClassMethod/TemplateAnnotationToThisRenderRector.php +++ b/rules/CodeQuality/Rector/ClassMethod/TemplateAnnotationToThisRenderRector.php @@ -27,7 +27,6 @@ use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover; use Rector\Comments\NodeDocBlock\DocBlockUpdater; -use Rector\Contract\PhpParser\Node\StmtsAwareInterface; use Rector\Doctrine\NodeAnalyzer\AttrinationFinder; use Rector\PhpParser\Node\BetterNodeFinder; use Rector\Rector\AbstractRector; @@ -363,8 +362,11 @@ private function removeDoctrineAnnotationTagValueNode( } } + /** + * @param StmtsAware $stmtsAware + */ private function refactorStmtsAwareNode( - StmtsAwareInterface $stmtsAware, + Node $stmtsAware, DoctrineAnnotationTagValueNode | Attribute $templateTagValueNodeOrAttribute, bool $hasThisRenderOrReturnsResponse, ClassMethod $classMethod diff --git a/rules/Symfony42/Rector/New_/RootNodeTreeBuilderRector.php b/rules/Symfony42/Rector/New_/RootNodeTreeBuilderRector.php index 9bcd4eaed..00b4052f3 100644 --- a/rules/Symfony42/Rector/New_/RootNodeTreeBuilderRector.php +++ b/rules/Symfony42/Rector/New_/RootNodeTreeBuilderRector.php @@ -12,7 +12,6 @@ use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\Expression; use PHPStan\Type\ObjectType; -use Rector\Contract\PhpParser\Node\StmtsAwareInterface; use Rector\PhpParser\Enum\NodeGroup; use Rector\PhpParser\Node\BetterNodeFinder; use Rector\Rector\AbstractRector; @@ -123,7 +122,10 @@ public function refactor(Node $node): ?Node return null; } - private function getRootMethodCallNode(StmtsAwareInterface $stmtsAware): ?Node + /** + * @param StmtsAware $stmtsAware + */ + private function getRootMethodCallNode(Node $stmtsAware): ?Node { $methodCalls = $this->betterNodeFinder->findInstanceOf($stmtsAware, MethodCall::class);