From 45a949f2b5941475d360ead82b44e482a873ceb0 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sat, 22 Jun 2024 22:25:17 +0900 Subject: [PATCH 1/2] [CodeQuality] Deprecate MakeCommandLazyRector, as Symfony 6.1 introduces more reliable native attribute --- config/sets/symfony/symfony-code-quality.php | 2 - .../Fixture/constant_defined_name.php.inc | 31 ----- .../Fixture/fixture.php.inc | 43 ------- .../Fixture/method_chaining.php.inc | 41 ------- .../method_chaining_with_options.php.inc | 55 --------- ...kip_constructor_dependency_command.php.inc | 13 --- ...rent_construct_static_in_construct.php.inc | 15 --- .../skip_non_string_param_construct.php.inc | 16 --- .../Fixture/static_in_execute.php.inc | 47 -------- .../skip_non_string_command_name.php.php.inc | 13 --- ...skip_parent_property_promotion.php.php.inc | 15 --- .../skip_property_promotion.php.inc | 14 --- .../MakeCommandLazyRectorTest.php | 28 ----- .../MakeCommandLazyRector/Php80Test.php | 31 ----- ...ParentClassWithPromotedPropertyCommand.php | 16 --- .../config/configured_rule.php | 10 -- .../Rector/Class_/MakeCommandLazyRector.php | 109 +++--------------- 17 files changed, 13 insertions(+), 486 deletions(-) delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/constant_defined_name.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/fixture.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/method_chaining.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/method_chaining_with_options.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/skip_constructor_dependency_command.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/skip_non_parent_construct_static_in_construct.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/skip_non_string_param_construct.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/static_in_execute.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/FixturePhp80/skip_non_string_command_name.php.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/FixturePhp80/skip_parent_property_promotion.php.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/FixturePhp80/skip_property_promotion.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/MakeCommandLazyRectorTest.php delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Php80Test.php delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Source/ParentClassWithPromotedPropertyCommand.php delete mode 100644 rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/config/configured_rule.php diff --git a/config/sets/symfony/symfony-code-quality.php b/config/sets/symfony/symfony-code-quality.php index f2ee87d3..8334b990 100644 --- a/config/sets/symfony/symfony-code-quality.php +++ b/config/sets/symfony/symfony-code-quality.php @@ -6,7 +6,6 @@ use Rector\Symfony\CodeQuality\Rector\BinaryOp\ResponseStatusCodeRector; use Rector\Symfony\CodeQuality\Rector\Class_\EventListenerToEventSubscriberRector; use Rector\Symfony\CodeQuality\Rector\Class_\LoadValidatorMetadataToAnnotationRector; -use Rector\Symfony\CodeQuality\Rector\Class_\MakeCommandLazyRector; use Rector\Symfony\CodeQuality\Rector\ClassMethod\ActionSuffixRemoverRector; use Rector\Symfony\CodeQuality\Rector\ClassMethod\ParamTypeFromRouteRequiredRegexRector; use Rector\Symfony\CodeQuality\Rector\ClassMethod\RemoveUnusedRequestParamRector; @@ -16,7 +15,6 @@ return static function (RectorConfig $rectorConfig): void { $rectorConfig->rules([ - MakeCommandLazyRector::class, EventListenerToEventSubscriberRector::class, ResponseReturnTypeControllerActionRector::class, // int and string literals to const fetches diff --git a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/constant_defined_name.php.inc b/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/constant_defined_name.php.inc deleted file mode 100644 index 331aa608..00000000 --- a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/constant_defined_name.php.inc +++ /dev/null @@ -1,31 +0,0 @@ -setName(self::COMMAND_NAME); - } -} - -?> ------ - diff --git a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/fixture.php.inc b/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/fixture.php.inc deleted file mode 100644 index 0e4e88b1..00000000 --- a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/fixture.php.inc +++ /dev/null @@ -1,43 +0,0 @@ -setName('sunshine'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $input->setName('trap'); - } -} - -?> ------ -setName('trap'); - } -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/method_chaining.php.inc b/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/method_chaining.php.inc deleted file mode 100644 index 52726edb..00000000 --- a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/method_chaining.php.inc +++ /dev/null @@ -1,41 +0,0 @@ -setName('app:method_chaining') - ->setDescription('some description'); - } - - protected function execute(InputInterface $input, OutputInterface $output) {} -} - -?> ------ -setDescription('some description'); - } - - protected function execute(InputInterface $input, OutputInterface $output) {} -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/method_chaining_with_options.php.inc b/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/method_chaining_with_options.php.inc deleted file mode 100644 index 125ce1fe..00000000 --- a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/method_chaining_with_options.php.inc +++ /dev/null @@ -1,55 +0,0 @@ -setName('some-command') - ->addOption( - 'some_option', - null, - InputOption::VALUE_OPTIONAL, - 'Some text' - ) - ->setDescription('some_description') - ->addOption('some_other_option', 'i', InputOption::VALUE_NONE, 'Some other text'); - } - - protected function execute(InputInterface $input, OutputInterface $output) {} -} - -?> ------ -addOption( - 'some_option', - null, - InputOption::VALUE_OPTIONAL, - 'Some text' - ) - ->setDescription('some_description') - ->addOption('some_other_option', 'i', InputOption::VALUE_NONE, 'Some other text'); - } - - protected function execute(InputInterface $input, OutputInterface $output) {} -} - -?> diff --git a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/skip_constructor_dependency_command.php.inc b/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/skip_constructor_dependency_command.php.inc deleted file mode 100644 index 977345fb..00000000 --- a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/skip_constructor_dependency_command.php.inc +++ /dev/null @@ -1,13 +0,0 @@ - diff --git a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/skip_non_string_param_construct.php.inc b/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/skip_non_string_param_construct.php.inc deleted file mode 100644 index 1201ece5..00000000 --- a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/skip_non_string_param_construct.php.inc +++ /dev/null @@ -1,16 +0,0 @@ -another = $another; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/static_in_execute.php.inc b/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/static_in_execute.php.inc deleted file mode 100644 index 8fc1eca5..00000000 --- a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Fixture/static_in_execute.php.inc +++ /dev/null @@ -1,47 +0,0 @@ -setName('some:command'); - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - // This will fail - SomeClass::staticMethodCall(); - } -} - -?> ------ - diff --git a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/FixturePhp80/skip_non_string_command_name.php.php.inc b/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/FixturePhp80/skip_non_string_command_name.php.php.inc deleted file mode 100644 index bbf65a5a..00000000 --- a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/FixturePhp80/skip_non_string_command_name.php.php.inc +++ /dev/null @@ -1,13 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule.php'; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Php80Test.php b/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Php80Test.php deleted file mode 100644 index d9cabe8c..00000000 --- a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Php80Test.php +++ /dev/null @@ -1,31 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/FixturePhp80'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule.php'; - } -} diff --git a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Source/ParentClassWithPromotedPropertyCommand.php b/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Source/ParentClassWithPromotedPropertyCommand.php deleted file mode 100644 index 22505220..00000000 --- a/rules-tests/CodeQuality/Rector/Class_/MakeCommandLazyRector/Source/ParentClassWithPromotedPropertyCommand.php +++ /dev/null @@ -1,16 +0,0 @@ -rule(MakeCommandLazyRector::class); -}; diff --git a/rules/CodeQuality/Rector/Class_/MakeCommandLazyRector.php b/rules/CodeQuality/Rector/Class_/MakeCommandLazyRector.php index aefb42af..02342593 100644 --- a/rules/CodeQuality/Rector/Class_/MakeCommandLazyRector.php +++ b/rules/CodeQuality/Rector/Class_/MakeCommandLazyRector.php @@ -5,25 +5,19 @@ namespace Rector\Symfony\CodeQuality\Rector\Class_; use PhpParser\Node; -use PhpParser\Node\Expr; -use PhpParser\Node\Expr\MethodCall; -use PhpParser\Node\Expr\Variable; use PhpParser\Node\Stmt\Class_; -use PhpParser\Node\Stmt\ClassMethod; -use PhpParser\Node\Stmt\Expression; -use PhpParser\Node\Stmt\Property; -use PHPStan\Type\ObjectType; use Rector\Rector\AbstractRector; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** - * @changelog https://symfony.com/doc/current/console/commands_as_services.html - * - * @see \Rector\Symfony\Tests\CodeQuality\Rector\Class_\MakeCommandLazyRector\MakeCommandLazyRectorTest + * @deprecated This rule is deprecated since Rector 1.1.2, as Symfony 6.1 introduced native attribute, + * more reliable and validated */ final class MakeCommandLazyRector extends AbstractRector { + private bool $hasWarned = false; + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Make Symfony commands lazy', [ @@ -68,98 +62,21 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - if (! $this->isObjectType($node, new ObjectType('Symfony\Component\Console\Command\Command'))) { - return null; - } - - $defaultNameProperty = $node->getProperty('defaultName'); - if ($defaultNameProperty instanceof Property) { - return null; - } - - $commandNameExpr = $this->resolveCommandNameFromSetName($node); - if (! $commandNameExpr instanceof Expr) { - return null; - } - - $commandNameType = $this->getType($commandNameExpr); - if (! $commandNameType->isConstantScalarValue()->yes()) { - return null; - } - - $defaultNameProperty = $this->createStaticProtectedPropertyWithDefault('defaultName', $commandNameExpr); - $node->stmts = array_merge([$defaultNameProperty], $node->stmts); - - return $node; - } - - private function resolveCommandNameFromSetName(Class_ $class): ?Expr - { - $configureClassMethod = $class->getMethod('configure'); - if (! $configureClassMethod instanceof ClassMethod || $configureClassMethod->stmts === null) { + if ($this->hasWarned) { return null; } - foreach ($configureClassMethod->stmts as $key => $stmt) { - if (! $stmt instanceof Expression) { - continue; - } - - if (! $stmt->expr instanceof MethodCall) { - continue; - } + trigger_error( + sprintf( + 'The "%s" rule was deprecated, as its only dead middle step before more solid PHP attributes.', + self::class, + ) + ); - $methodCall = $stmt->expr; + sleep(3); - if ($methodCall->var instanceof Variable) { - return $this->resolveFromNonFluentMethodCall($methodCall, $configureClassMethod, $key); - } - - $expr = null; - - $this->traverseNodesWithCallable($stmt, function (Node $node) use (&$expr) { - if ($node instanceof MethodCall && $this->isName($node->name, 'setName')) { - $expr = $node->getArgs()[0] -->value; - - // remove nested call - return $node->var; - } - - return null; - }); - - return $expr; - } + $this->hasWarned = true; return null; } - - private function resolveFromNonFluentMethodCall( - MethodCall $methodCall, - ClassMethod $classMethod, - int $key - ): ?Expr { - if (! $this->isName($methodCall->name, 'setName')) { - return null; - } - - $firstArg = $methodCall->getArgs()[0]; - $expr = $firstArg->value; - - // cleanup fluent call - unset($classMethod->stmts[$key]); - - return $expr; - } - - private function createStaticProtectedPropertyWithDefault(string $name, Expr $expr): Property - { - $propertyBuilder = new \PhpParser\Builder\Property($name); - $propertyBuilder->makeProtected(); - $propertyBuilder->makeStatic(); - $propertyBuilder->setDefault($expr); - - return $propertyBuilder->getNode(); - } } From 9ad78120df7d81b7be31215a6fa099d68e8c155f Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sat, 22 Jun 2024 22:31:20 +0900 Subject: [PATCH 2/2] bump docs --- docs/rector_rules_overview.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/rector_rules_overview.md b/docs/rector_rules_overview.md index 41d5cecc..3b649fb6 100644 --- a/docs/rector_rules_overview.md +++ b/docs/rector_rules_overview.md @@ -1,4 +1,4 @@ -# 85 Rules Overview +# 86 Rules Overview ## ActionSuffixRemoverRector @@ -171,6 +171,25 @@ Rename `type` option to `entry_type` in CollectionType
+## ChangeRouteAttributeFromAnnotationSubnamespaceRector + +Replace `Symfony\Component\Routing\Annotation\Route` by `Symfony\Component\Routing\Attribute\Route` when the class use #Route[] attribute + +- class: [`Rector\Symfony\Symfony64\Rector\Class_\ChangeRouteAttributeFromAnnotationSubnamespaceRector`](../rules/Symfony64/Rector/Class_/ChangeRouteAttributeFromAnnotationSubnamespaceRector.php) + +```diff +-/** +- * #[\Symfony\Component\Routing\Annotation\Route("/foo")] +- */ ++#[\Symfony\Component\Routing\Attribute\Route('/foo')] + public function create(Request $request): Response + { + return new Response(); + } +``` + +
+ ## ChangeStringCollectionOptionToConstantRector Change type in CollectionType from alias string to class reference @@ -1688,7 +1707,7 @@ Changes Process string argument to an array ## SwiftCreateMessageToNewEmailRector -Changes `createMessage()` into a new Symfony\Component\Mime\Email +Changes `createMessage()` into a new `Symfony\Component\Mime\Email` - class: [`Rector\Symfony\SwiftMailer\Rector\MethodCall\SwiftCreateMessageToNewEmailRector`](../rules/SwiftMailer/Rector/MethodCall/SwiftCreateMessageToNewEmailRector.php) @@ -1701,7 +1720,7 @@ Changes `createMessage()` into a new Symfony\Component\Mime\Email ## SwiftMessageToEmailRector -Convert `\Swift_Message` into an \Symfony\Component\Mime\Email +Convert `\Swift_Message` into an `\Symfony\Component\Mime\Email` - class: [`Rector\Symfony\SwiftMailer\Rector\ClassMethod\SwiftMessageToEmailRector`](../rules/SwiftMailer/Rector/ClassMethod/SwiftMessageToEmailRector.php)