diff --git a/config/sets/symfony/symfony-code-quality.php b/config/sets/symfony/symfony-code-quality.php index 5582fd4f7..4b73c6d79 100644 --- a/config/sets/symfony/symfony-code-quality.php +++ b/config/sets/symfony/symfony-code-quality.php @@ -16,6 +16,7 @@ use Rector\Symfony\CodeQuality\Rector\ClassMethod\ResponseReturnTypeControllerActionRector; use Rector\Symfony\CodeQuality\Rector\MethodCall\AssertSameResponseCodeWithDebugContentsRector; use Rector\Symfony\CodeQuality\Rector\MethodCall\LiteralGetToRequestClassConstantRector; +use Rector\Symfony\CodeQuality\Rector\MethodCall\ParameterBagTypedGetMethodCallRector; use Rector\Symfony\CodeQuality\Rector\MethodCall\StringCastDebugResponseRector; use Rector\Symfony\Symfony26\Rector\MethodCall\RedirectToRouteRector; @@ -35,6 +36,7 @@ // request method RequestIsMainRector::class, + ParameterBagTypedGetMethodCallRector::class, // tests AssertSameResponseCodeWithDebugContentsRector::class, diff --git a/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/Fixture/fixture.php.inc b/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/Fixture/fixture.php.inc index ce8e5b200..a9b600dd1 100644 --- a/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/Fixture/fixture.php.inc +++ b/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/Fixture/fixture.php.inc @@ -31,12 +31,12 @@ final class SomeController { public function index(Request $request) { - return $request->isMainRequest(); + return $request->isMasterRequest(); } public function second(Request $request) { - return $request->isMainRequest(); + return $request->isMasterRequest(); } } diff --git a/rules-tests/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector/Fixture/get_on_boolean.php.inc b/rules-tests/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector/Fixture/get_on_boolean.php.inc new file mode 100644 index 000000000..2e0b92665 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector/Fixture/get_on_boolean.php.inc @@ -0,0 +1,31 @@ +query->get('debug', false); + } +} + +?> +----- +query->getBoolean('debug'); + } +} + +?> diff --git a/rules-tests/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector/Fixture/skip_non_casted.php.inc b/rules-tests/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector/Fixture/skip_non_casted.php.inc new file mode 100644 index 000000000..df4bd79bd --- /dev/null +++ b/rules-tests/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector/Fixture/skip_non_casted.php.inc @@ -0,0 +1,13 @@ +query->get('debug', false); + } +} diff --git a/rules-tests/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector/ParameterBagTypedGetMethodCallRectorTest.php b/rules-tests/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector/ParameterBagTypedGetMethodCallRectorTest.php new file mode 100644 index 000000000..e64760917 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector/ParameterBagTypedGetMethodCallRectorTest.php @@ -0,0 +1,28 @@ +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/MethodCall/ParameterBagTypedGetMethodCallRector/config/configured_rule.php b/rules-tests/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector/config/configured_rule.php new file mode 100644 index 000000000..5ec5d31fe --- /dev/null +++ b/rules-tests/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(ParameterBagTypedGetMethodCallRector::class); +}; diff --git a/rules/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector.php b/rules/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector.php new file mode 100644 index 000000000..ddcd94eaa --- /dev/null +++ b/rules/CodeQuality/Rector/MethodCall/ParameterBagTypedGetMethodCallRector.php @@ -0,0 +1,125 @@ +query->get('debug', false); + } +} +CODE_SAMPLE + + , + <<<'CODE_SAMPLE' +use Symfony\Component\HttpFoundation\Request; + +class SomeClass +{ + public function run(Request $request) + { + $debug = $request->query->getBoolean('debug'); + } +} + +CODE_SAMPLE + ), + + ] + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [MethodCall::class, Bool_::class]; + } + + /** + * @param MethodCall|Bool_ $node + */ + public function refactor(Node $node): ?Node + { + if ($node instanceof Bool_) { + if (! $node->expr instanceof MethodCall) { + return null; + } + + return $this->refactorMethodCall($node->expr); + } + + return null; + } + + private function refactorMethodCall(MethodCall $methodCall): ?MethodCall + { + // default value must be defined + if (count($methodCall->getArgs()) !== 2) { + return null; + } + + if (! $this->isName($methodCall->name, 'get')) { + return null; + } + + $callerType = $this->getType($methodCall->var); + if (! $callerType instanceof ObjectType) { + return null; + } + + if (! $callerType->isInstanceOf(SymfonyClass::PARAMETER_BAG)->yes()) { + return null; + } + + // the getBoolean() method must exist + if (! $callerType->hasMethod('getBoolean')->yes()) { + return null; + } + + $defaultArg = $methodCall->getArgs()[1]; + + if ($this->valueResolver->isFalse($defaultArg->value)) { + unset($methodCall->args[1]); + $methodCall->name = new Identifier('getBoolean'); + + return $methodCall; + } + + return null; + } +} diff --git a/rules/Symfony42/Rector/MethodCall/ContainerGetToConstructorInjectionRector.php b/rules/Symfony42/Rector/MethodCall/ContainerGetToConstructorInjectionRector.php deleted file mode 100644 index 35f260673..000000000 --- a/rules/Symfony42/Rector/MethodCall/ContainerGetToConstructorInjectionRector.php +++ /dev/null @@ -1,79 +0,0 @@ -get()` in ContainerAware to constructor injection in Command and Controller in Symfony', - [ - new CodeSample( - <<<'CODE_SAMPLE' -final class SomeCommand extends ContainerAwareCommand -{ - public function someMethod() - { - // ... - $this->getContainer()->get('some_service'); - $this->container->get('some_service'); - } -} -CODE_SAMPLE - , - <<<'CODE_SAMPLE' -final class SomeCommand extends ContainerAwareCommand -{ - public function __construct(SomeService $someService) - { - $this->someService = $someService; - } - - public function someMethod() - { - // ... - $this->someService; - $this->someService; - } -} -CODE_SAMPLE - ), - ] - ); - } - - /** - * @return array> - */ - public function getNodeTypes(): array - { - return [Class_::class]; - } - - /** - * @param Class_ $node - */ - public function refactor(Node $node): ?Node - { - throw new ShouldNotHappenException(sprintf( - 'The %s rule is deprecated. Use more reliable set \Rector\Symfony\Set\SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION instead', - self::class - )); - } -} diff --git a/src/Enum/SymfonyClass.php b/src/Enum/SymfonyClass.php index a29faad02..c67f9b09e 100644 --- a/src/Enum/SymfonyClass.php +++ b/src/Enum/SymfonyClass.php @@ -135,4 +135,9 @@ final class SymfonyClass * @var string */ public const CONTAINER_CONFIGURATOR = 'Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator'; + + /** + * @var string + */ + public const PARAMETER_BAG = 'Symfony\Component\HttpFoundation\ParameterBag'; } diff --git a/src/Set/FOSRestSetList.php b/src/Set/FOSRestSetList.php deleted file mode 100644 index c8ca0acec..000000000 --- a/src/Set/FOSRestSetList.php +++ /dev/null @@ -1,18 +0,0 @@ -withAttributesSets(symfony: true) in rector.php config instead - * - * @api used in public - */ -final class FOSRestSetList -{ - /** - * @var string - */ - final public const ANNOTATIONS_TO_ATTRIBUTES = __DIR__ . '/../../config/sets/fosrest/annotations-to-attributes.php'; -} diff --git a/src/Set/JMSSetList.php b/src/Set/JMSSetList.php deleted file mode 100644 index 4ab10c76e..000000000 --- a/src/Set/JMSSetList.php +++ /dev/null @@ -1,18 +0,0 @@ -withAttributesSets(symfony: true) in rector.php config instead - * - * @api - */ -final class JMSSetList -{ - /** - * @var string - */ - final public const ANNOTATIONS_TO_ATTRIBUTES = __DIR__ . '/../../config/sets/jms/annotations-to-attributes.php'; -} diff --git a/src/Set/SensiolabsSetList.php b/src/Set/SensiolabsSetList.php deleted file mode 100644 index 54c69863b..000000000 --- a/src/Set/SensiolabsSetList.php +++ /dev/null @@ -1,18 +0,0 @@ -withAttributesSets(symfony: true) in rector.php config instead - * - * @api - */ -final class SensiolabsSetList -{ - /** - * @var string - */ - final public const ANNOTATIONS_TO_ATTRIBUTES = __DIR__ . '/../../config/sets/sensiolabs/annotations-to-attributes.php'; -} diff --git a/stubs/Symfony/Component/HttpFoundation/Request.php b/stubs/Symfony/Component/HttpFoundation/Request.php deleted file mode 100644 index 0bdb89473..000000000 --- a/stubs/Symfony/Component/HttpFoundation/Request.php +++ /dev/null @@ -1,25 +0,0 @@ -