diff --git a/composer.json b/composer.json index 5bfccf2e..2de1eaa9 100644 --- a/composer.json +++ b/composer.json @@ -8,21 +8,25 @@ "ext-xml": "*" }, "require-dev": { + "phpecs/phpecs": "^2.0.1", "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.0", + "phpstan/phpstan": "^2.1.8", "phpstan/phpstan-webmozart-assert": "^2.0", "phpunit/phpunit": "^11.4", "rector/rector-src": "dev-main", + "rector/type-perfect": "^2.0", "symfony/config": "^6.4", "symfony/dependency-injection": "^6.4", - "symfony/http-kernel": "~6.3", + "symfony/http-kernel": "^6.4", "symfony/routing": "^6.4", "symfony/security-core": "^6.4", "symfony/security-http": "^6.4", "symfony/validator": "^6.4", - "symplify/easy-coding-standard": "^12.3", + "symplify/phpstan-rules": "^14.6", "symplify/vendor-patches": "^11.3", - "tomasvotruba/class-leak": "^1.0", + "tomasvotruba/class-leak": "^2.0", + "tomasvotruba/type-coverage": "^2.0", + "tomasvotruba/unused-public": "^2.0", "tracy/tracy": "^2.10" }, "autoload": { diff --git a/config/sets/symfony/symfony-code-quality.php b/config/sets/symfony/symfony-code-quality.php index 330a73ba..1255e98f 100644 --- a/config/sets/symfony/symfony-code-quality.php +++ b/config/sets/symfony/symfony-code-quality.php @@ -3,9 +3,13 @@ declare(strict_types=1); use Rector\Config\RectorConfig; +use Rector\Symfony\CodeQuality\Rector\AttributeGroup\SingleConditionSecurityAttributeToIsGrantedRector; +use Rector\Symfony\CodeQuality\Rector\BinaryOp\RequestIsMainRector; use Rector\Symfony\CodeQuality\Rector\BinaryOp\ResponseStatusCodeRector; use Rector\Symfony\CodeQuality\Rector\Class_\EventListenerToEventSubscriberRector; +use Rector\Symfony\CodeQuality\Rector\Class_\InlineClassRoutePrefixRector; use Rector\Symfony\CodeQuality\Rector\Class_\LoadValidatorMetadataToAnnotationRector; +use Rector\Symfony\CodeQuality\Rector\Class_\SplitAndSecurityAttributeToIsGrantedRector; use Rector\Symfony\CodeQuality\Rector\ClassMethod\ActionSuffixRemoverRector; use Rector\Symfony\CodeQuality\Rector\ClassMethod\ParamTypeFromRouteRequiredRegexRector; use Rector\Symfony\CodeQuality\Rector\ClassMethod\RemoveUnusedRequestParamRector; @@ -28,7 +32,17 @@ ActionSuffixRemoverRector::class, LoadValidatorMetadataToAnnotationRector::class, + // request method + RequestIsMainRector::class, + // tests AssertSameResponseCodeWithDebugContentsRector::class, + + // routing + InlineClassRoutePrefixRector::class, + + // narrow attributes + SingleConditionSecurityAttributeToIsGrantedRector::class, + SplitAndSecurityAttributeToIsGrantedRector::class, ]); }; diff --git a/config/sets/symfony/symfony3/symfony30.php b/config/sets/symfony/symfony3/symfony30.php new file mode 100644 index 00000000..402cbcbb --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30.php @@ -0,0 +1,24 @@ +import(__DIR__ . '/symfony30/symfony30-class-loader.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-console.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-form.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-security.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-process.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-property-access.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-http-foundation.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-http-kernel.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-validator.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-translation.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-bridge-monolog.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-twig-bundle.php'); + $rectorConfig->import(__DIR__ . '/symfony30/symfony30-bridge-swift-mailer.php'); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-bridge-monolog.php b/config/sets/symfony/symfony3/symfony30/symfony30-bridge-monolog.php new file mode 100644 index 00000000..e6fb1eb7 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-bridge-monolog.php @@ -0,0 +1,22 @@ +ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Bridge\Monolog\Logger' => 'Psr\Log\LoggerInterface', + ]); + + $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Bridge\Monolog\Logger', 'emerg', 'emergency'), + new MethodCallRename('Symfony\Bridge\Monolog\Logger', 'crit', 'critical'), + new MethodCallRename('Symfony\Bridge\Monolog\Logger', 'err', 'error'), + new MethodCallRename('Symfony\Bridge\Monolog\Logger', 'warn', 'warning'), + ]); + +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-bridge-swift-mailer.php b/config/sets/symfony/symfony3/symfony30/symfony30-bridge-swift-mailer.php new file mode 100644 index 00000000..16d254c2 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-bridge-swift-mailer.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // swift mailer + 'Symfony\Bridge\Swiftmailer\DataCollector\MessageDataCollector' => 'Symfony\Bundle\SwiftmailerBundle\DataCollector\MessageDataCollector', + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-class-loader.php b/config/sets/symfony/symfony3/symfony30/symfony30-class-loader.php new file mode 100644 index 00000000..24b78640 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-class-loader.php @@ -0,0 +1,52 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename( + 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', + 'registerNamespaces', + 'addPrefixes' + ), + new MethodCallRename( + 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', + 'registerPrefixes', + 'addPrefixes' + ), + new MethodCallRename( + 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', + 'registerNamespace', + 'addPrefix' + ), + new MethodCallRename( + 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', + 'registerPrefix', + 'addPrefix' + ), + new MethodCallRename( + 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', + 'getNamespaces', + 'getPrefixes' + ), + new MethodCallRename( + 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', + 'getNamespaceFallbacks', + 'getFallbackDirs' + ), + new MethodCallRename( + 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', + 'getPrefixFallbacks', + 'getFallbackDirs' + ), + ]); + + $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader' => 'Symfony\Component\ClassLoader\ClassLoader', + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-console.php b/config/sets/symfony/symfony3/symfony30/symfony30-console.php new file mode 100644 index 00000000..bdac3bf3 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-console.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // console + 'Symfony\Component\Console\Helper\ProgressHelper' => 'Symfony\Component\Console\Helper\ProgressBar', + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-form.php b/config/sets/symfony/symfony3/symfony30/symfony30-form.php new file mode 100644 index 00000000..82dd1652 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-form.php @@ -0,0 +1,80 @@ +rules([ + FormTypeInstanceToClassConstRector::class, + StringFormTypeToClassRector::class, + RemoveDefaultGetBlockPrefixRector::class, + FormTypeGetParentRector::class, + OptionNameRector::class, + ReadOnlyOptionToAttributeRector::class, + ChangeStringCollectionOptionToConstantRector::class, + ]); + + $rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [ + new RenameClassConstFetch('Symfony\Component\Form\FormEvents', 'PRE_BIND', 'PRE_SUBMIT'), + new RenameClassConstFetch('Symfony\Component\Form\FormEvents', 'BIND', 'SUBMIT'), + new RenameClassConstFetch('Symfony\Component\Form\FormEvents', 'POST_BIND', 'POST_SUBMIT'), + new RenameClassConstFetch( + 'Symfony\Component\Form\Extension\Core\DataTransformer', + 'ROUND_HALFEVEN', + 'ROUND_HALF_EVEN' + ), + new RenameClassConstFetch( + 'Symfony\Component\Form\Extension\Core\DataTransformer', + 'ROUND_HALFUP', + 'ROUND_HALF_UP' + ), + new RenameClassConstFetch( + 'Symfony\Component\Form\Extension\Core\DataTransformer', + 'ROUND_HALFDOWN', + 'ROUND_HALF_DOWN' + ), + ]); + + $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\Form\AbstractType', 'getName', 'getBlockPrefix'), + new MethodCallRename('Symfony\Component\Form\FormTypeInterface', 'getName', 'getBlockPrefix'), + + new MethodCallRename('Symfony\Component\Form\FormTypeInterface', 'setDefaultOptions', 'configureOptions'), + new MethodCallRename('Symfony\Component\Form\ResolvedFormTypeInterface', 'getName', 'getBlockPrefix'), + new MethodCallRename( + 'Symfony\Component\Form\AbstractTypeExtension', + 'setDefaultOptions', + 'configureOptions' + ), + new MethodCallRename('Symfony\Component\Form\Form', 'bind', 'submit'), + new MethodCallRename('Symfony\Component\Form\Form', 'isBound', 'isSubmitted'), + ]); + + $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\Form\Util\VirtualFormAwareIterator' => 'Symfony\Component\Form\Util\InheritDataAwareIterator', + 'Symfony\Component\Form\Tests\Extension\Core\Type\TypeTestCase' => 'Symfony\Component\Form\Test\TypeTestCase', + 'Symfony\Component\Form\Tests\FormIntegrationTestCase' => 'Symfony\Component\Form\Test\FormIntegrationTestCase', + 'Symfony\Component\Form\Tests\FormPerformanceTestCase' => 'Symfony\Component\Form\Test\FormPerformanceTestCase', + 'Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface' => 'Symfony\Component\Form\ChoiceList\ChoiceListInterface', + 'Symfony\Component\Form\Extension\Core\View\ChoiceView' => 'Symfony\Component\Form\ChoiceList\View\ChoiceView', + 'Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface' => 'Symfony\Component\Security\Csrf\CsrfTokenManagerInterface', + 'Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList' => 'Symfony\Component\Form\ChoiceList\ArrayChoiceList', + 'Symfony\Component\Form\Extension\Core\ChoiceList\LazyChoiceList' => 'Symfony\Component\Form\ChoiceList\LazyChoiceList', + 'Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList' => 'Symfony\Component\Form\ChoiceList\ArrayChoiceList', + 'Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList' => 'Symfony\Component\Form\ChoiceList\ArrayChoiceList', + 'Symfony\Component\Form\ChoiceList\ArrayKeyChoiceList' => 'Symfony\Component\Form\ChoiceList\ArrayChoiceList', + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-http-foundation.php b/config/sets/symfony/symfony3/symfony30/symfony30-http-foundation.php new file mode 100644 index 00000000..a1e80d19 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-http-foundation.php @@ -0,0 +1,10 @@ +rules([GetRequestRector::class]); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-http-kernel.php b/config/sets/symfony/symfony3/symfony30/symfony30-http-kernel.php new file mode 100644 index 00000000..62b2b223 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-http-kernel.php @@ -0,0 +1,31 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\HttpKernel\Log\LoggerInterface', 'emerg', 'emergency'), + new MethodCallRename('Symfony\Component\HttpKernel\Log\LoggerInterface', 'crit', 'critical'), + new MethodCallRename('Symfony\Component\HttpKernel\Log\LoggerInterface', 'err', 'error'), + new MethodCallRename('Symfony\Component\HttpKernel\Log\LoggerInterface', 'warn', 'warning'), + new MethodCallRename('Symfony\Component\HttpKernel\Log\NullLogger', 'emerg', 'emergency'), + new MethodCallRename('Symfony\Component\HttpKernel\Log\NullLogger', 'crit', 'critical'), + new MethodCallRename('Symfony\Component\HttpKernel\Log\NullLogger', 'err', 'error'), + new MethodCallRename('Symfony\Component\HttpKernel\Log\NullLogger', 'warn', 'warning'), + ]); + + $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\HttpKernel\Debug\ErrorHandler' => 'Symfony\Component\Debug\ErrorHandler', + 'Symfony\Component\HttpKernel\Debug\ExceptionHandler' => 'Symfony\Component\Debug\ExceptionHandler', + 'Symfony\Component\HttpKernel\Exception\FatalErrorException' => 'Symfony\Component\Debug\Exception\FatalErrorException', + 'Symfony\Component\HttpKernel\Exception\FlattenException' => 'Symfony\Component\Debug\Exception\FlattenException', + 'Symfony\Component\HttpKernel\Log\LoggerInterface' => 'Psr\Log\LoggerInterface', + 'Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass' => 'Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass', + 'Symfony\Component\HttpKernel\Log\NullLogger' => 'Psr\Log\LoggerInterface', + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-process.php b/config/sets/symfony/symfony3/symfony30/symfony30-process.php new file mode 100644 index 00000000..d82c0352 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-process.php @@ -0,0 +1,14 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\Process\Process', 'setStdin', 'setInput'), + new MethodCallRename('Symfony\Component\Process\Process', 'getStdin', 'getInput'), + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-property-access.php b/config/sets/symfony/symfony3/symfony30/symfony30-property-access.php new file mode 100644 index 00000000..eec3421c --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-property-access.php @@ -0,0 +1,17 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename( + 'Symfony\Component\PropertyAccess\PropertyAccess', + 'getPropertyAccessor', + 'createPropertyAccessor' + ), + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-security.php b/config/sets/symfony/symfony3/symfony30/symfony30-security.php new file mode 100644 index 00000000..9f97bee6 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-security.php @@ -0,0 +1,12 @@ +ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter' => 'Symfony\Component\Security\Core\Authorization\Voter\Voter', + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-translation.php b/config/sets/symfony/symfony3/symfony30/symfony30-translation.php new file mode 100644 index 00000000..ba64fc1a --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-translation.php @@ -0,0 +1,14 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\Translation\Dumper\FileDumper', 'format', 'formatCatalogue'), + new MethodCallRename('Symfony\Component\Translation\Translator', 'getMessages', 'getCatalogue'), + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-twig-bundle.php b/config/sets/symfony/symfony3/symfony30/symfony30-twig-bundle.php new file mode 100644 index 00000000..d51460ec --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-twig-bundle.php @@ -0,0 +1,12 @@ +ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Bundle\TwigBundle\TwigDefaultEscapingStrategy' => 'Twig_FileExtensionEscapingStrategy', + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony30/symfony30-validator.php b/config/sets/symfony/symfony3/symfony30/symfony30-validator.php new file mode 100644 index 00000000..fda92eef --- /dev/null +++ b/config/sets/symfony/symfony3/symfony30/symfony30-validator.php @@ -0,0 +1,46 @@ +ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\Validator\Constraints\Collection\Optional' => 'Symfony\Component\Validator\Constraints\Optional', + 'Symfony\Component\Validator\Constraints\Collection\Required' => 'Symfony\Component\Validator\Constraints\Required', + 'Symfony\Component\Validator\MetadataInterface' => 'Symfony\Component\Validator\Mapping\MetadataInterface', + 'Symfony\Component\Validator\PropertyMetadataInterface' => 'Symfony\Component\Validator\Mapping\PropertyMetadataInterface', + 'Symfony\Component\Validator\PropertyMetadataContainerInterface' => 'Symfony\Component\Validator\Mapping\ClassMetadataInterface', + 'Symfony\Component\Validator\ClassBasedInterface' => 'Symfony\Component\Validator\Mapping\ClassMetadataInterface', + 'Symfony\Component\Validator\Mapping\ElementMetadata' => 'Symfony\Component\Validator\Mapping\GenericMetadata', + 'Symfony\Component\Validator\ExecutionContextInterface' => 'Symfony\Component\Validator\Context\ExecutionContextInterface', + 'Symfony\Component\Validator\Mapping\ClassMetadataFactory' => 'Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory', + 'Symfony\Component\Validator\Mapping\MetadataFactoryInterface' => 'Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface', + ]); + + $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename( + 'Symfony\Component\Validator\ConstraintViolationInterface', + 'getMessageParameters', + 'getParameters' + ), + new MethodCallRename( + 'Symfony\Component\Validator\ConstraintViolationInterface', + 'getMessagePluralization', + 'getPlural' + ), + new MethodCallRename( + 'Symfony\Component\Validator\ConstraintViolation', + 'getMessageParameters', + 'getParameters' + ), + new MethodCallRename( + 'Symfony\Component\Validator\ConstraintViolation', + 'getMessagePluralization', + 'getPlural' + ), + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony31.php b/config/sets/symfony/symfony3/symfony31.php new file mode 100644 index 00000000..7aa92b7f --- /dev/null +++ b/config/sets/symfony/symfony3/symfony31.php @@ -0,0 +1,9 @@ +import(__DIR__ . '/symfony31/symfony31-yaml.php'); +}; diff --git a/config/sets/symfony/symfony31.php b/config/sets/symfony/symfony3/symfony31/symfony31-yaml.php similarity index 100% rename from config/sets/symfony/symfony31.php rename to config/sets/symfony/symfony3/symfony31/symfony31-yaml.php diff --git a/config/sets/symfony/symfony3/symfony32.php b/config/sets/symfony/symfony3/symfony32.php new file mode 100644 index 00000000..696d849f --- /dev/null +++ b/config/sets/symfony/symfony3/symfony32.php @@ -0,0 +1,9 @@ +import(__DIR__ . '/symfony32/symfony32-dependency-injection.php'); +}; diff --git a/config/sets/symfony/symfony32.php b/config/sets/symfony/symfony3/symfony32/symfony32-dependency-injection.php similarity index 100% rename from config/sets/symfony/symfony32.php rename to config/sets/symfony/symfony3/symfony32/symfony32-dependency-injection.php diff --git a/config/sets/symfony/symfony3/symfony33.php b/config/sets/symfony/symfony3/symfony33.php new file mode 100644 index 00000000..71106836 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony33.php @@ -0,0 +1,12 @@ +import(__DIR__ . '/symfony33/symfony33-console.php'); + $rectorConfig->import(__DIR__ . '/symfony33/symfony33-debug.php'); + $rectorConfig->import(__DIR__ . '/symfony33/symfony33-dependency-injection.php'); + $rectorConfig->import(__DIR__ . '/symfony33/symfony33-framework-bundle.php'); +}; diff --git a/config/sets/symfony/symfony3/symfony33/symfony33-console.php b/config/sets/symfony/symfony3/symfony33/symfony33-console.php new file mode 100644 index 00000000..3735565a --- /dev/null +++ b/config/sets/symfony/symfony3/symfony33/symfony33-console.php @@ -0,0 +1,16 @@ +rules([ConsoleExceptionToErrorEventConstantRector::class]); + + $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ + // console + 'Symfony\Component\Console\Event\ConsoleExceptionEvent' => 'Symfony\Component\Console\Event\ConsoleErrorEvent', + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony33/symfony33-debug.php b/config/sets/symfony/symfony3/symfony33/symfony33-debug.php new file mode 100644 index 00000000..492d6a22 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony33/symfony33-debug.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // debug + 'Symfony\Component\Debug\Exception\ContextErrorException' => 'ErrorException', + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony33/symfony33-dependency-injection.php b/config/sets/symfony/symfony3/symfony33/symfony33-dependency-injection.php new file mode 100644 index 00000000..614ca644 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony33/symfony33-dependency-injection.php @@ -0,0 +1,44 @@ +ruleWithConfiguration(ArgumentAdderRector::class, [ + new ArgumentAdder( + 'Symfony\Component\DependencyInjection\ContainerBuilder', + 'compile', + 0, + 'resolveEnvPlaceholders', + false + ), + new ArgumentAdder( + 'Symfony\Component\DependencyInjection\ContainerBuilder', + 'addCompilerPass', + 2, + 'priority', + 0 + ), + new ArgumentAdder( + 'Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraph', + 'connect', + 6, + 'weak', + false + ), + ]); + + $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\DependencyInjection\DefinitionDecorator' => 'Symfony\Component\DependencyInjection\ChildDefinition', + ]); + + $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\DependencyInjection\Container', 'isFrozen', 'isCompiled'), + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony33/symfony33-framework-bundle.php b/config/sets/symfony/symfony3/symfony33/symfony33-framework-bundle.php new file mode 100644 index 00000000..3cfe7b00 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony33/symfony33-framework-bundle.php @@ -0,0 +1,19 @@ +ruleWithConfiguration(RenameClassRector::class, [ + # framework bundle + 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass' => 'Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass', + 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\SerializerPass' => 'Symfony\Component\Serializer\DependencyInjection\SerializerPass', + 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass' => 'Symfony\Component\Form\DependencyInjection\FormPass', + 'Symfony\Bundle\FrameworkBundle\EventListener\SessionListener' => 'Symfony\Component\HttpKernel\EventListener\SessionListener', + 'Symfony\Bundle\FrameworkBundle\EventListener\TestSessionListenr' => 'Symfony\Component\HttpKernel\EventListener\TestSessionListener', + 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ConfigCachePass' => 'Symfony\Component\Config\DependencyInjection\ConfigCachePass', + 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass' => 'Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass', + ]); +}; diff --git a/config/sets/symfony/symfony3/symfony34.php b/config/sets/symfony/symfony3/symfony34.php new file mode 100644 index 00000000..51de6e82 --- /dev/null +++ b/config/sets/symfony/symfony3/symfony34.php @@ -0,0 +1,12 @@ +import(__DIR__ . '/symfony34/symfony34-yaml.php'); + $rectorConfig->import(__DIR__ . '/symfony34/symfony34-dependency-injection.php'); + $rectorConfig->import(__DIR__ . '/symfony34/symfony34-sensio-framework-extra-bundle.php'); + +}; diff --git a/config/sets/symfony/symfony3/symfony34/symfony34-dependency-injection.php b/config/sets/symfony/symfony3/symfony34/symfony34-dependency-injection.php new file mode 100644 index 00000000..08a87eff --- /dev/null +++ b/config/sets/symfony/symfony3/symfony34/symfony34-dependency-injection.php @@ -0,0 +1,10 @@ +rules([ContainerGetNameToTypeInTestsRector::class]); +}; diff --git a/config/sets/symfony/symfony34.php b/config/sets/symfony/symfony3/symfony34/symfony34-sensio-framework-extra-bundle.php similarity index 54% rename from config/sets/symfony/symfony34.php rename to config/sets/symfony/symfony3/symfony34/symfony34-sensio-framework-extra-bundle.php index 3e554229..890ccf74 100644 --- a/config/sets/symfony/symfony34.php +++ b/config/sets/symfony/symfony3/symfony34/symfony34-sensio-framework-extra-bundle.php @@ -3,27 +3,14 @@ declare(strict_types=1); use Rector\Config\RectorConfig; -use Rector\Removing\Rector\ClassMethod\ArgumentRemoverRector; -use Rector\Removing\ValueObject\ArgumentRemover; use Rector\Symfony\Symfony34\Rector\ClassMethod\MergeMethodAnnotationToRouteAnnotationRector; use Rector\Symfony\Symfony34\Rector\ClassMethod\RemoveServiceFromSensioRouteRector; use Rector\Symfony\Symfony34\Rector\ClassMethod\ReplaceSensioRouteAnnotationWithSymfonyRector; -use Rector\Symfony\Symfony34\Rector\Closure\ContainerGetNameToTypeInTestsRector; return static function (RectorConfig $rectorConfig): void { - $rectorConfig->ruleWithConfiguration(ArgumentRemoverRector::class, [ - new ArgumentRemover( - 'Symfony\Component\Yaml\Yaml', - 'parse', - 2, - ['Symfony\Component\Yaml\Yaml::PARSE_KEYS_AS_STRINGS'] - ), - ]); - $rectorConfig->rules([ MergeMethodAnnotationToRouteAnnotationRector::class, RemoveServiceFromSensioRouteRector::class, ReplaceSensioRouteAnnotationWithSymfonyRector::class, - ContainerGetNameToTypeInTestsRector::class, ]); }; diff --git a/config/sets/symfony/symfony3/symfony34/symfony34-yaml.php b/config/sets/symfony/symfony3/symfony34/symfony34-yaml.php new file mode 100644 index 00000000..237dc1cc --- /dev/null +++ b/config/sets/symfony/symfony3/symfony34/symfony34-yaml.php @@ -0,0 +1,18 @@ +ruleWithConfiguration(ArgumentRemoverRector::class, [ + new ArgumentRemover( + 'Symfony\Component\Yaml\Yaml', + 'parse', + 2, + ['Symfony\Component\Yaml\Yaml::PARSE_KEYS_AS_STRINGS'] + ), + ]); +}; diff --git a/config/sets/symfony/symfony30.php b/config/sets/symfony/symfony30.php deleted file mode 100644 index 0aa8c6ee..00000000 --- a/config/sets/symfony/symfony30.php +++ /dev/null @@ -1,210 +0,0 @@ -rules([ - // php - GetRequestRector::class, - FormTypeGetParentRector::class, - OptionNameRector::class, - ReadOnlyOptionToAttributeRector::class, - - // forms - FormTypeInstanceToClassConstRector::class, - StringFormTypeToClassRector::class, - RemoveDefaultGetBlockPrefixRector::class, - - // forms - collection - ChangeStringCollectionOptionToConstantRector::class, - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [ - new RenameClassConstFetch('Symfony\Component\Form\FormEvents', 'PRE_BIND', 'PRE_SUBMIT'), - new RenameClassConstFetch('Symfony\Component\Form\FormEvents', 'BIND', 'SUBMIT'), - new RenameClassConstFetch('Symfony\Component\Form\FormEvents', 'POST_BIND', 'POST_SUBMIT'), - new RenameClassConstFetch( - 'Symfony\Component\Form\Extension\Core\DataTransformer', - 'ROUND_HALFEVEN', - 'ROUND_HALF_EVEN' - ), - new RenameClassConstFetch( - 'Symfony\Component\Form\Extension\Core\DataTransformer', - 'ROUND_HALFUP', - 'ROUND_HALF_UP' - ), - new RenameClassConstFetch( - 'Symfony\Component\Form\Extension\Core\DataTransformer', - 'ROUND_HALFDOWN', - 'ROUND_HALF_DOWN' - ), - ]); - - $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ - new MethodCallRename( - 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', - 'registerNamespaces', - 'addPrefixes' - ), - new MethodCallRename( - 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', - 'registerPrefixes', - 'addPrefixes' - ), - new MethodCallRename( - 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', - 'registerNamespace', - 'addPrefix' - ), - new MethodCallRename( - 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', - 'registerPrefix', - 'addPrefix' - ), - new MethodCallRename( - 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', - 'getNamespaces', - 'getPrefixes' - ), - new MethodCallRename( - 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', - 'getNamespaceFallbacks', - 'getFallbackDirs' - ), - new MethodCallRename( - 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader', - 'getPrefixFallbacks', - 'getFallbackDirs' - ), - // form - new MethodCallRename('Symfony\Component\Form\AbstractType', 'getName', 'getBlockPrefix'), - new MethodCallRename('Symfony\Component\Form\FormTypeInterface', 'getName', 'getBlockPrefix'), - - new MethodCallRename('Symfony\Component\Form\FormTypeInterface', 'setDefaultOptions', 'configureOptions'), - new MethodCallRename('Symfony\Component\Form\ResolvedFormTypeInterface', 'getName', 'getBlockPrefix'), - new MethodCallRename( - 'Symfony\Component\Form\AbstractTypeExtension', - 'setDefaultOptions', - 'configureOptions' - ), - new MethodCallRename('Symfony\Component\Form\Form', 'bind', 'submit'), - new MethodCallRename('Symfony\Component\Form\Form', 'isBound', 'isSubmitted'), - // process - new MethodCallRename('Symfony\Component\Process\Process', 'setStdin', 'setInput'), - new MethodCallRename('Symfony\Component\Process\Process', 'getStdin', 'getInput'), - // monolog - new MethodCallRename('Symfony\Bridge\Monolog\Logger', 'emerg', 'emergency'), - new MethodCallRename('Symfony\Bridge\Monolog\Logger', 'crit', 'critical'), - new MethodCallRename('Symfony\Bridge\Monolog\Logger', 'err', 'error'), - new MethodCallRename('Symfony\Bridge\Monolog\Logger', 'warn', 'warning'), - # http kernel - new MethodCallRename('Symfony\Component\HttpKernel\Log\LoggerInterface', 'emerg', 'emergency'), - new MethodCallRename('Symfony\Component\HttpKernel\Log\LoggerInterface', 'crit', 'critical'), - new MethodCallRename('Symfony\Component\HttpKernel\Log\LoggerInterface', 'err', 'error'), - new MethodCallRename('Symfony\Component\HttpKernel\Log\LoggerInterface', 'warn', 'warning'), - new MethodCallRename('Symfony\Component\HttpKernel\Log\NullLogger', 'emerg', 'emergency'), - new MethodCallRename('Symfony\Component\HttpKernel\Log\NullLogger', 'crit', 'critical'), - new MethodCallRename('Symfony\Component\HttpKernel\Log\NullLogger', 'err', 'error'), - new MethodCallRename('Symfony\Component\HttpKernel\Log\NullLogger', 'warn', 'warning'), - // property access - new MethodCallRename( - 'Symfony\Component\PropertyAccess\PropertyAccess', - 'getPropertyAccessor', - 'createPropertyAccessor' - ), - // translator - new MethodCallRename('Symfony\Component\Translation\Dumper\FileDumper', 'format', 'formatCatalogue'), - new MethodCallRename('Symfony\Component\Translation\Translator', 'getMessages', 'getCatalogue'), - // validator - new MethodCallRename( - 'Symfony\Component\Validator\ConstraintViolationInterface', - 'getMessageParameters', - 'getParameters' - ), - new MethodCallRename( - 'Symfony\Component\Validator\ConstraintViolationInterface', - 'getMessagePluralization', - 'getPlural' - ), - new MethodCallRename( - 'Symfony\Component\Validator\ConstraintViolation', - 'getMessageParameters', - 'getParameters' - ), - new MethodCallRename( - 'Symfony\Component\Validator\ConstraintViolation', - 'getMessagePluralization', - 'getPlural' - ), - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - # class loader - # partial with method rename - 'Symfony\Component\ClassLoader\UniversalClassLoader\UniversalClassLoader' => 'Symfony\Component\ClassLoader\ClassLoader', - # console - 'Symfony\Component\Console\Helper\ProgressHelper' => 'Symfony\Component\Console\Helper\ProgressBar', - # form - 'Symfony\Component\Form\Util\VirtualFormAwareIterator' => 'Symfony\Component\Form\Util\InheritDataAwareIterator', - 'Symfony\Component\Form\Tests\Extension\Core\Type\TypeTestCase' => 'Symfony\Component\Form\Test\TypeTestCase', - 'Symfony\Component\Form\Tests\FormIntegrationTestCase' => 'Symfony\Component\Form\Test\FormIntegrationTestCase', - 'Symfony\Component\Form\Tests\FormPerformanceTestCase' => 'Symfony\Component\Form\Test\FormPerformanceTestCase', - 'Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface' => 'Symfony\Component\Form\ChoiceList\ChoiceListInterface', - 'Symfony\Component\Form\Extension\Core\View\ChoiceView' => 'Symfony\Component\Form\ChoiceList\View\ChoiceView', - 'Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface' => 'Symfony\Component\Security\Csrf\CsrfTokenManagerInterface', - 'Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList' => 'Symfony\Component\Form\ChoiceList\ArrayChoiceList', - 'Symfony\Component\Form\Extension\Core\ChoiceList\LazyChoiceList' => 'Symfony\Component\Form\ChoiceList\LazyChoiceList', - 'Symfony\Component\Form\Extension\Core\ChoiceList\ObjectChoiceList' => 'Symfony\Component\Form\ChoiceList\ArrayChoiceList', - 'Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList' => 'Symfony\Component\Form\ChoiceList\ArrayChoiceList', - 'Symfony\Component\Form\ChoiceList\ArrayKeyChoiceList' => 'Symfony\Component\Form\ChoiceList\ArrayChoiceList', - # http kernel - 'Symfony\Component\HttpKernel\Debug\ErrorHandler' => 'Symfony\Component\Debug\ErrorHandler', - 'Symfony\Component\HttpKernel\Debug\ExceptionHandler' => 'Symfony\Component\Debug\ExceptionHandler', - 'Symfony\Component\HttpKernel\Exception\FatalErrorException' => 'Symfony\Component\Debug\Exception\FatalErrorException', - 'Symfony\Component\HttpKernel\Exception\FlattenException' => 'Symfony\Component\Debug\Exception\FlattenException', - # partial with method rename - 'Symfony\Component\HttpKernel\Log\LoggerInterface' => 'Psr\Log\LoggerInterface', - # event disptacher - 'Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass' => 'Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass', - # partial with methor rename - 'Symfony\Component\HttpKernel\Log\NullLogger' => 'Psr\Log\LoggerInterface', - # monolog - # partial with method rename - 'Symfony\Bridge\Monolog\Logger' => 'Psr\Log\LoggerInterface', - # security - 'Symfony\Component\Security\Core\Authorization\Voter\AbstractVoter' => 'Symfony\Component\Security\Core\Authorization\Voter\Voter', - # twig - 'Symfony\Bundle\TwigBundle\TwigDefaultEscapingStrategy' => 'Twig_FileExtensionEscapingStrategy', - # validator - 'Symfony\Component\Validator\Constraints\Collection\Optional' => 'Symfony\Component\Validator\Constraints\Optional', - 'Symfony\Component\Validator\Constraints\Collection\Required' => 'Symfony\Component\Validator\Constraints\Required', - 'Symfony\Component\Validator\MetadataInterface' => 'Symfony\Component\Validator\Mapping\MetadataInterface', - 'Symfony\Component\Validator\PropertyMetadataInterface' => 'Symfony\Component\Validator\Mapping\PropertyMetadataInterface', - 'Symfony\Component\Validator\PropertyMetadataContainerInterface' => 'Symfony\Component\Validator\Mapping\ClassMetadataInterface', - 'Symfony\Component\Validator\ClassBasedInterface' => 'Symfony\Component\Validator\Mapping\ClassMetadataInterface', - 'Symfony\Component\Validator\Mapping\ElementMetadata' => 'Symfony\Component\Validator\Mapping\GenericMetadata', - 'Symfony\Component\Validator\ExecutionContextInterface' => 'Symfony\Component\Validator\Context\ExecutionContextInterface', - 'Symfony\Component\Validator\Mapping\ClassMetadataFactory' => 'Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory', - 'Symfony\Component\Validator\Mapping\MetadataFactoryInterface' => 'Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface', - # swift mailer - 'Symfony\Bridge\Swiftmailer\DataCollector\MessageDataCollector' => 'Symfony\Bundle\SwiftmailerBundle\DataCollector\MessageDataCollector', - ]); -}; diff --git a/config/sets/symfony/symfony33.php b/config/sets/symfony/symfony33.php deleted file mode 100644 index 0a8f08c4..00000000 --- a/config/sets/symfony/symfony33.php +++ /dev/null @@ -1,60 +0,0 @@ -ruleWithConfiguration(ArgumentAdderRector::class, [ - new ArgumentAdder( - 'Symfony\Component\DependencyInjection\ContainerBuilder', - 'compile', - 0, - 'resolveEnvPlaceholders', - false - ), - new ArgumentAdder( - 'Symfony\Component\DependencyInjection\ContainerBuilder', - 'addCompilerPass', - 2, - 'priority', - 0 - ), - new ArgumentAdder( - 'Symfony\Component\DependencyInjection\Compiler\ServiceReferenceGraph', - 'connect', - 6, - 'weak', - false - ), - ]); - - $rectorConfig->rule(ConsoleExceptionToErrorEventConstantRector::class); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - # console - 'Symfony\Component\Console\Event\ConsoleExceptionEvent' => 'Symfony\Component\Console\Event\ConsoleErrorEvent', - # debug - 'Symfony\Component\Debug\Exception\ContextErrorException' => 'ErrorException', - # dependency-injection - 'Symfony\Component\DependencyInjection\DefinitionDecorator' => 'Symfony\Component\DependencyInjection\ChildDefinition', - # framework bundle - 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass' => 'Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass', - 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\SerializerPass' => 'Symfony\Component\Serializer\DependencyInjection\SerializerPass', - 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass' => 'Symfony\Component\Form\DependencyInjection\FormPass', - 'Symfony\Bundle\FrameworkBundle\EventListener\SessionListener' => 'Symfony\Component\HttpKernel\EventListener\SessionListener', - 'Symfony\Bundle\FrameworkBundle\EventListener\TestSessionListenr' => 'Symfony\Component\HttpKernel\EventListener\TestSessionListener', - 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ConfigCachePass' => 'Symfony\Component\Config\DependencyInjection\ConfigCachePass', - 'Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass' => 'Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass', - ]); - - $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ - new MethodCallRename('Symfony\Component\DependencyInjection\Container', 'isFrozen', 'isCompiled'), - ]); -}; diff --git a/config/sets/symfony/symfony4/symfony40.php b/config/sets/symfony/symfony4/symfony40.php new file mode 100644 index 00000000..c6b81271 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony40.php @@ -0,0 +1,13 @@ +import(__DIR__ . '/symfony40/symfony40-validator.php'); + $rectorConfig->import(__DIR__ . '/symfony40/symfony40-dependency-injection.php'); + $rectorConfig->import(__DIR__ . '/symfony40/symfony40-process.php'); + $rectorConfig->import(__DIR__ . '/symfony40/symfony40-form.php'); + $rectorConfig->import(__DIR__ . '/symfony40/symfony40-var-dumper.php'); +}; diff --git a/config/sets/symfony/symfony4/symfony40/symfony40-dependency-injection.php b/config/sets/symfony/symfony4/symfony40/symfony40-dependency-injection.php new file mode 100644 index 00000000..d029830b --- /dev/null +++ b/config/sets/symfony/symfony4/symfony40/symfony40-dependency-injection.php @@ -0,0 +1,10 @@ +rules([ContainerBuilderCompileEnvArgumentRector::class]); +}; diff --git a/config/sets/symfony/symfony4/symfony40/symfony40-form.php b/config/sets/symfony/symfony4/symfony40/symfony40-form.php new file mode 100644 index 00000000..f54ea651 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony40/symfony40-form.php @@ -0,0 +1,10 @@ +rules([FormIsValidRector::class]); +}; diff --git a/config/sets/symfony/symfony4/symfony40/symfony40-process.php b/config/sets/symfony/symfony4/symfony40/symfony40-process.php new file mode 100644 index 00000000..02a69337 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony40/symfony40-process.php @@ -0,0 +1,12 @@ +ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\Process\ProcessBuilder' => 'Symfony\Component\Process\Process', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony40/symfony40-validator.php b/config/sets/symfony/symfony4/symfony40/symfony40-validator.php new file mode 100644 index 00000000..9475e864 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony40/symfony40-validator.php @@ -0,0 +1,15 @@ +rules([ConstraintUrlOptionRector::class]); + + $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest' => 'Symfony\Component\Validator\Test\ConstraintValidatorTestCase', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony40/symfony40-var-dumper.php b/config/sets/symfony/symfony4/symfony40/symfony40-var-dumper.php new file mode 100644 index 00000000..b676c11b --- /dev/null +++ b/config/sets/symfony/symfony4/symfony40/symfony40-var-dumper.php @@ -0,0 +1,10 @@ +rules([VarDumperTestTraitMethodArgsRector::class]); +}; diff --git a/config/sets/symfony/symfony4/symfony41.php b/config/sets/symfony/symfony4/symfony41.php new file mode 100644 index 00000000..ee504d83 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony41.php @@ -0,0 +1,13 @@ +import(__DIR__ . '/symfony41/symfony41-console.php'); + $rectorConfig->import(__DIR__ . '/symfony41/symfony41-http-foundation.php'); + $rectorConfig->import(__DIR__ . '/symfony41/symfony41-workflow.php'); + $rectorConfig->import(__DIR__ . '/symfony41/symfony41-framework-bundle.php'); +}; diff --git a/config/sets/symfony/symfony41.php b/config/sets/symfony/symfony4/symfony41/symfony41-console.php similarity index 63% rename from config/sets/symfony/symfony41.php rename to config/sets/symfony/symfony4/symfony41/symfony41-console.php index 326b4c2f..54d00edd 100644 --- a/config/sets/symfony/symfony41.php +++ b/config/sets/symfony/symfony4/symfony41/symfony41-console.php @@ -4,11 +4,9 @@ use Rector\Config\RectorConfig; use Rector\Renaming\Rector\MethodCall\RenameMethodRector; -use Rector\Renaming\Rector\Name\RenameClassRector; use Rector\Renaming\ValueObject\MethodCallRename; use Rector\Renaming\ValueObject\MethodCallRenameWithArrayKey; -# https://github.com/symfony/symfony/blob/master/UPGRADE-4.1.md return static function (RectorConfig $rectorConfig): void { $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ # https://github.com/symfony/symfony/commit/463f986c28a497571967e37c1314e9911f1ef6ba @@ -29,9 +27,7 @@ 'setCrossingChar', 'setDefaultCrossingChar' ), - new MethodCallRename('Symfony\Component\HttpFoundation\File\UploadedFile', 'getClientSize', 'getSize'), - new MethodCallRename('Symfony\Component\Workflow\DefinitionBuilder', 'reset', 'clear'), - new MethodCallRename('Symfony\Component\Workflow\DefinitionBuilder', 'add', 'addWorkflow'), + # https://github.com/symfony/symfony/commit/463f986c28a497571967e37c1314e9911f1ef6ba new MethodCallRenameWithArrayKey( 'Symfony\Component\Console\Helper\TableStyle', @@ -48,11 +44,4 @@ 2 ), ]); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - # https://github.com/symfony/symfony/commit/07dd09db59e2f2a86a291d00d978169d9059e307 - 'Symfony\Bundle\FrameworkBundle\DataCollector\RequestDataCollector' => 'Symfony\Component\HttpKernel\DataCollector\RequestDataCollector', - 'Symfony\Component\Workflow\SupportStrategy\SupportStrategyInterface' => 'Symfony\Component\Workflow\SupportStrategy\WorkflowSupportStrategyInterface', - 'Symfony\Component\Workflow\SupportStrategy\ClassInstanceSupportStrategy' => 'Symfony\Component\Workflow\SupportStrategy\InstanceOfSupportStrategy', - ]); }; diff --git a/config/sets/symfony/symfony4/symfony41/symfony41-framework-bundle.php b/config/sets/symfony/symfony4/symfony41/symfony41-framework-bundle.php new file mode 100644 index 00000000..26559523 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony41/symfony41-framework-bundle.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameClassRector::class, [ + # https://github.com/symfony/symfony/commit/07dd09db59e2f2a86a291d00d978169d9059e307 + 'Symfony\Bundle\FrameworkBundle\DataCollector\RequestDataCollector' => 'Symfony\Component\HttpKernel\DataCollector\RequestDataCollector', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony41/symfony41-http-foundation.php b/config/sets/symfony/symfony4/symfony41/symfony41-http-foundation.php new file mode 100644 index 00000000..78e7376c --- /dev/null +++ b/config/sets/symfony/symfony4/symfony41/symfony41-http-foundation.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\HttpFoundation\File\UploadedFile', 'getClientSize', 'getSize'), + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony41/symfony41-workflow.php b/config/sets/symfony/symfony4/symfony41/symfony41-workflow.php new file mode 100644 index 00000000..5f519315 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony41/symfony41-workflow.php @@ -0,0 +1,20 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\Workflow\DefinitionBuilder', 'reset', 'clear'), + new MethodCallRename('Symfony\Component\Workflow\DefinitionBuilder', 'add', 'addWorkflow'), + ]); + + $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\Workflow\SupportStrategy\SupportStrategyInterface' => 'Symfony\Component\Workflow\SupportStrategy\WorkflowSupportStrategyInterface', + 'Symfony\Component\Workflow\SupportStrategy\ClassInstanceSupportStrategy' => 'Symfony\Component\Workflow\SupportStrategy\InstanceOfSupportStrategy', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony42.php b/config/sets/symfony/symfony4/symfony42.php new file mode 100644 index 00000000..583a3676 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42.php @@ -0,0 +1,22 @@ +import(__DIR__ . '/symfony42/symfony42-http-foundation.php'); + $rectorConfig->import(__DIR__ . '/symfony42/symfony42-http-kernel.php'); + $rectorConfig->import(__DIR__ . '/symfony42/symfony42-framework-bundle.php'); + $rectorConfig->import(__DIR__ . '/symfony42/symfony42-translation.php'); + $rectorConfig->import(__DIR__ . '/symfony42/symfony42-process.php'); + $rectorConfig->import(__DIR__ . '/symfony42/symfony42-config.php'); + $rectorConfig->import(__DIR__ . '/symfony42/symfony42-dom-crawler.php'); + $rectorConfig->import(__DIR__ . '/symfony42/symfony42-finder.php'); + $rectorConfig->import(__DIR__ . '/symfony42/symfony42-monolog-bridge.php'); + $rectorConfig->import(__DIR__ . '/symfony42/symfony42-serializer.php'); + $rectorConfig->import(__DIR__ . '/symfony42/symfony42-form.php'); + $rectorConfig->import(__DIR__ . '/symfony42/symfony42-cache.php'); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-cache.php b/config/sets/symfony/symfony4/symfony42/symfony42-cache.php new file mode 100644 index 00000000..e8fd3ea2 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-cache.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\Cache\CacheItem', 'getPreviousTags', 'getMetadata'), + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-config.php b/config/sets/symfony/symfony4/symfony42/symfony42-config.php new file mode 100644 index 00000000..349c4168 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-config.php @@ -0,0 +1,13 @@ +rules([ + // https://symfony.com/blog/new-in-symfony-4-2-important-deprecations + RootNodeTreeBuilderRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-dom-crawler.php b/config/sets/symfony/symfony4/symfony42/symfony42-dom-crawler.php new file mode 100644 index 00000000..f6196ca2 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-dom-crawler.php @@ -0,0 +1,22 @@ +ruleWithConfiguration(ArgumentAdderRector::class, [ + new ArgumentAdder( + 'Symfony\Component\DomCrawler\Crawler', + 'children', + 0, + null, + null, + null, + ArgumentAddingScope::SCOPE_METHOD_CALL + ), + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-finder.php b/config/sets/symfony/symfony4/symfony42/symfony42-finder.php new file mode 100644 index 00000000..ab3d39c0 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-finder.php @@ -0,0 +1,22 @@ +ruleWithConfiguration(ArgumentAdderRector::class, [ + new ArgumentAdder( + 'Symfony\Component\Finder\Finder', + 'sortByName', + 0, + null, + false, + null, + ArgumentAddingScope::SCOPE_METHOD_CALL + ), + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-form.php b/config/sets/symfony/symfony4/symfony42/symfony42-form.php new file mode 100644 index 00000000..ae5f8201 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-form.php @@ -0,0 +1,50 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\Form\AbstractTypeExtension', 'getExtendedType', 'getExtendedTypes'), + ]); + + $iterableType = new IterableType(new MixedType(), new MixedType()); + + $rectorConfig->ruleWithConfiguration( + AddReturnTypeDeclarationRector::class, + [ + new AddReturnTypeDeclaration( + 'Symfony\Component\Form\AbstractTypeExtension', + 'getExtendedTypes', + $iterableType + ), + ] + ); + + $rectorConfig->ruleWithConfiguration( + ChangeMethodVisibilityRector::class, + [new ChangeMethodVisibility( + 'Symfony\Component\Form\AbstractTypeExtension', + 'getExtendedTypes', + Visibility::STATIC + ), + ] + ); + + $rectorConfig->ruleWithConfiguration( + WrapReturnRector::class, + [new WrapReturn('Symfony\Component\Form\AbstractTypeExtension', 'getExtendedTypes', true)] + ); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-framework-bundle.php b/config/sets/symfony/symfony4/symfony42/symfony42-framework-bundle.php new file mode 100644 index 00000000..da1e0ad1 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-framework-bundle.php @@ -0,0 +1,14 @@ +ruleWithConfiguration(RenameClassRector::class, [ + # https://github.com/symfony/symfony/commit/a7e319d9e1316e2e18843f8ce15b67a8693e5bf9 + 'Symfony\Bundle\FrameworkBundle\Controller\Controller' => 'Symfony\Bundle\FrameworkBundle\Controller\AbstractController', + # https://github.com/symfony/symfony/commit/744bf0e7ac3ecf240d0bf055cc58f881bb0b3ec0 + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-http-foundation.php b/config/sets/symfony/symfony4/symfony42/symfony42-http-foundation.php new file mode 100644 index 00000000..cf74f67b --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-http-foundation.php @@ -0,0 +1,38 @@ +ruleWithConfiguration(NewToStaticCallRector::class, [ + new NewToStaticCall( + 'Symfony\Component\HttpFoundation\Cookie', + 'Symfony\Component\HttpFoundation\Cookie', + 'create' + ), + ]); + + // https://github.com/symfony/symfony/commit/9493cfd5f2366dab19bbdde0d0291d0575454567 + $rectorConfig->ruleWithConfiguration(ReplaceArgumentDefaultValueRector::class, [ + new ReplaceArgumentDefaultValue( + 'Symfony\Component\HttpFoundation\Cookie', + MethodName::CONSTRUCT, + 5, + false, + null + ), + new ReplaceArgumentDefaultValue( + 'Symfony\Component\HttpFoundation\Cookie', + MethodName::CONSTRUCT, + 8, + null, + 'lax' + ), + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-http-kernel.php b/config/sets/symfony/symfony4/symfony42/symfony42-http-kernel.php new file mode 100644 index 00000000..42643b8b --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-http-kernel.php @@ -0,0 +1,27 @@ +ruleWithConfiguration(ArgumentRemoverRector::class, [ + new ArgumentRemover( + 'Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector', + MethodName::CONSTRUCT, + 0, + null + ), + new ArgumentRemover( + 'Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector', + MethodName::CONSTRUCT, + 1, + null + ), + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-monolog-bridge.php b/config/sets/symfony/symfony4/symfony42/symfony42-monolog-bridge.php new file mode 100644 index 00000000..3cd972ef --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-monolog-bridge.php @@ -0,0 +1,49 @@ +ruleWithConfiguration(ArgumentAdderRector::class, [ + new ArgumentAdder( + 'Symfony\Bridge\Monolog\Processor\DebugProcessor', + 'getLogs', + 0, + null, + null, + null, + ArgumentAddingScope::SCOPE_METHOD_CALL + ), + new ArgumentAdder( + 'Symfony\Bridge\Monolog\Processor\DebugProcessor', + 'countErrors', + 0, + 'default_value', + null, + null, + ArgumentAddingScope::SCOPE_METHOD_CALL + ), + new ArgumentAdder( + 'Symfony\Bridge\Monolog\Logger', + 'getLogs', + 0, + 'default_value', + null, + null, + ArgumentAddingScope::SCOPE_METHOD_CALL + ), + new ArgumentAdder( + 'Symfony\Bridge\Monolog\Logger', + 'countErrors', + 0, + 'default_value', + null, + null, + ArgumentAddingScope::SCOPE_METHOD_CALL + ), + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-process.php b/config/sets/symfony/symfony4/symfony42/symfony42-process.php new file mode 100644 index 00000000..4abe48e0 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-process.php @@ -0,0 +1,13 @@ +rules([ + // https://symfony.com/blog/new-in-symfony-4-2-important-deprecations + StringToArrayArgumentProcessRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-serializer.php b/config/sets/symfony/symfony4/symfony42/symfony42-serializer.php new file mode 100644 index 00000000..5627f0b3 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-serializer.php @@ -0,0 +1,31 @@ +ruleWithConfiguration(ArgumentAdderRector::class, [ + new ArgumentAdder( + 'Symfony\Component\Serializer\Normalizer', + 'handleCircularReference', + 1, + null, + null, + null, + ArgumentAddingScope::SCOPE_METHOD_CALL + ), + new ArgumentAdder( + 'Symfony\Component\Serializer\Normalizer', + 'handleCircularReference', + 2, + null, + null, + null, + ArgumentAddingScope::SCOPE_METHOD_CALL + ), + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony42/symfony42-translation.php b/config/sets/symfony/symfony4/symfony42/symfony42-translation.php new file mode 100644 index 00000000..331446f5 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony42/symfony42-translation.php @@ -0,0 +1,12 @@ +ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\Translation\TranslatorInterface' => 'Symfony\Contracts\Translation\TranslatorInterface', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony43.php b/config/sets/symfony/symfony4/symfony43.php new file mode 100644 index 00000000..b977b86a --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43.php @@ -0,0 +1,20 @@ +import(__DIR__ . '/symfony43/symfony43-browser-kit.php'); + $rectorConfig->import(__DIR__ . '/symfony43/symfony43-cache.php'); + $rectorConfig->import(__DIR__ . '/symfony43/symfony43-event-dispatcher.php'); + $rectorConfig->import(__DIR__ . '/symfony43/symfony43-framework-bundle.php'); + $rectorConfig->import(__DIR__ . '/symfony43/symfony43-http-foundation.php'); + $rectorConfig->import(__DIR__ . '/symfony43/symfony43-http-kernel.php'); + $rectorConfig->import(__DIR__ . '/symfony43/symfony43-intl.php'); + $rectorConfig->import(__DIR__ . '/symfony43/symfony43-security-core.php'); + $rectorConfig->import(__DIR__ . '/symfony43/symfony43-security-http.php'); + $rectorConfig->import(__DIR__ . '/symfony43/symfony43-twig-bundle.php'); + $rectorConfig->import(__DIR__ . '/symfony43/symfony43-workflow.php'); +}; diff --git a/config/sets/symfony/symfony4/symfony43/symfony43-browser-kit.php b/config/sets/symfony/symfony4/symfony43/symfony43-browser-kit.php new file mode 100644 index 00000000..0fac5a6f --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43/symfony43-browser-kit.php @@ -0,0 +1,18 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\BrowserKit\Response', 'getStatus', 'getStatusCode'), + ]); + + $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\BrowserKit\Client' => 'Symfony\Component\BrowserKit\AbstractBrowser', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony43/symfony43-cache.php b/config/sets/symfony/symfony4/symfony43/symfony43-cache.php new file mode 100644 index 00000000..5dfb98a6 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43/symfony43-cache.php @@ -0,0 +1,26 @@ +ruleWithConfiguration(RenameClassRector::class, [ + # https://github.com/symfony/symfony/pull/29236 + 'Symfony\Component\Cache\Traits\ApcuTrait\ApcuCache' => 'Symfony\Component\Cache\Traits\ApcuTrait\ApcuAdapter', + 'Symfony\Component\Cache\Adapter\SimpleCacheAdapter' => 'Symfony\Component\Cache\Adapter\Psr16Adapter', + 'Symfony\Component\Cache\Simple\ArrayCache' => 'Symfony\Component\Cache\Adapter\ArrayAdapter', + 'Symfony\Component\Cache\Simple\ChainCache' => 'Symfony\Component\Cache\Adapter\ChainAdapter', + 'Symfony\Component\Cache\Simple\DoctrineCache' => 'Symfony\Component\Cache\Adapter\DoctrineAdapter', + 'Symfony\Component\Cache\Simple\FilesystemCache' => 'Symfony\Component\Cache\Adapter\FilesystemAdapter', + 'Symfony\Component\Cache\Simple\MemcachedCache' => 'Symfony\Component\Cache\Adapter\MemcachedAdapter', + 'Symfony\Component\Cache\Simple\NullCache' => 'Symfony\Component\Cache\Adapter\NullAdapter', + 'Symfony\Component\Cache\Simple\PdoCache' => 'Symfony\Component\Cache\Adapter\PdoAdapter', + 'Symfony\Component\Cache\Simple\PhpArrayCache' => 'Symfony\Component\Cache\Adapter\PhpArrayAdapter', + 'Symfony\Component\Cache\Simple\PhpFilesCache' => 'Symfony\Component\Cache\Adapter\PhpFilesAdapter', + 'Symfony\Component\Cache\Simple\RedisCache' => 'Symfony\Component\Cache\Adapter\RedisAdapter', + 'Symfony\Component\Cache\Simple\TraceableCache' => 'Symfony\Component\Cache\Adapter\TraceableAdapterCache', + 'Symfony\Component\Cache\Simple\Psr6Cache' => 'Symfony\Component\Cache\Psr16Cache', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony43/symfony43-event-dispatcher.php b/config/sets/symfony/symfony4/symfony43/symfony43-event-dispatcher.php new file mode 100644 index 00000000..a23ef4e6 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43/symfony43-event-dispatcher.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // has lowest priority, have to be last + 'Symfony\Component\EventDispatcher\Event' => 'Symfony\Contracts\EventDispatcher\Event', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony43/symfony43-framework-bundle.php b/config/sets/symfony/symfony4/symfony43/symfony43-framework-bundle.php new file mode 100644 index 00000000..5a4e2ee7 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43/symfony43-framework-bundle.php @@ -0,0 +1,27 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // assets deprecation + 'Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper' => 'Symfony\Component\Asset\Packages', + + // templating + 'Symfony\Bundle\FrameworkBundle\Templating\EngineInterface' => 'Symfony\Component\Templating\EngineInterface', + ]); + + $rectorConfig->rules([ + ConvertRenderTemplateShortNotationToBundleSyntaxRector::class, + # https://symfony.com/blog/new-in-symfony-4-3-better-test-assertions + // + WebTestCaseAssertIsSuccessfulRector::class, + WebTestCaseAssertResponseCodeRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony43/symfony43-http-foundation.php b/config/sets/symfony/symfony4/symfony43/symfony43-http-foundation.php new file mode 100644 index 00000000..7f5f9b7d --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43/symfony43-http-foundation.php @@ -0,0 +1,17 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // MimeType + 'Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface' => 'Symfony\Component\Mime\MimeTypesInterface', + 'Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesserInterface' => 'Symfony\Component\Mime\MimeTypesInterface', + 'Symfony\Component\HttpFoundation\File\MimeType\MimeTypeExtensionGuesser' => 'Symfony\Component\Mime\MimeTypes', + 'Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser' => 'Symfony\Component\Mime\FileBinaryMimeTypeGuesser', + 'Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser' => 'Symfony\Component\Mime\FileinfoMimeTypeGuesser', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony43/symfony43-http-kernel.php b/config/sets/symfony/symfony4/symfony43/symfony43-http-kernel.php new file mode 100644 index 00000000..bdd0d7d6 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43/symfony43-http-kernel.php @@ -0,0 +1,22 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // EventDispatcher + 'Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent' => 'Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent', + 'Symfony\Component\HttpKernel\Event\FilterControllerEvent' => 'Symfony\Component\HttpKernel\Event\ControllerEvent', + 'Symfony\Component\HttpKernel\Event\FilterResponseEvent' => 'Symfony\Component\HttpKernel\Event\ResponseEvent', + 'Symfony\Component\HttpKernel\Event\GetResponseEvent' => 'Symfony\Component\HttpKernel\Event\RequestEvent', + 'Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent' => 'Symfony\Component\HttpKernel\Event\ViewEvent', + 'Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent' => 'Symfony\Component\HttpKernel\Event\ExceptionEvent', + 'Symfony\Component\HttpKernel\Event\PostResponseEvent' => 'Symfony\Component\HttpKernel\Event\TerminateEvent', + + // @todo unpack after YAML to PHP migration, Symfony\Component\HttpKernel\Client: Symfony\Component\HttpKernel\HttpKernelBrowser + 'Symfony\Component\HttpKernel\EventListener\TranslatorListener' => 'Symfony\Component\HttpKernel\EventListener\LocaleAwareListener', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony43/symfony43-intl.php b/config/sets/symfony/symfony4/symfony43/symfony43-intl.php new file mode 100644 index 00000000..e9382013 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43/symfony43-intl.php @@ -0,0 +1,10 @@ +rules([GetCurrencyBundleMethodCallsToIntlRector::class]); +}; diff --git a/config/sets/symfony/symfony4/symfony43/symfony43-security-core.php b/config/sets/symfony/symfony4/symfony43/symfony43-security-core.php new file mode 100644 index 00000000..29e8c128 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43/symfony43-security-core.php @@ -0,0 +1,14 @@ +ruleWithConfiguration(RenameClassRector::class, [ + # Security + 'Symfony\Component\Security\Core\Encoder\Argon2iPasswordEncoder' => 'Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder', + 'Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder' => 'Symfony\Component\Security\Core\Encoder\NativePasswordEncoder', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony43/symfony43-security-http.php b/config/sets/symfony/symfony4/symfony43/symfony43-security-http.php new file mode 100644 index 00000000..fbd04252 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43/symfony43-security-http.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\Security\Http\Firewall', 'handleRequest', 'callListeners'), + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony43/symfony43-twig-bundle.php b/config/sets/symfony/symfony4/symfony43/symfony43-twig-bundle.php new file mode 100644 index 00000000..903b98e0 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43/symfony43-twig-bundle.php @@ -0,0 +1,10 @@ +rules([TwigBundleFilesystemLoaderToTwigRector::class]); +}; diff --git a/config/sets/symfony/symfony4/symfony43/symfony43-workflow.php b/config/sets/symfony/symfony4/symfony43/symfony43-workflow.php new file mode 100644 index 00000000..709cd652 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony43/symfony43-workflow.php @@ -0,0 +1,20 @@ +ruleWithConfiguration(ArgumentAdderRector::class, [ + new ArgumentAdder( + 'Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface', + 'setMarking', + 2, + 'context', + [] + ), + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony44.php b/config/sets/symfony/symfony4/symfony44.php new file mode 100644 index 00000000..2fe19897 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony44.php @@ -0,0 +1,15 @@ +import(__DIR__ . '/symfony44/symfony44-dependency-injection.php'); + $rectorConfig->import(__DIR__ . '/symfony44/symfony44-console.php'); + $rectorConfig->import(__DIR__ . '/symfony44/symfony44-http-kernel.php'); + $rectorConfig->import(__DIR__ . '/symfony44/symfony44-templating.php'); + $rectorConfig->import(__DIR__ . '/symfony44/symfony44-security-core.php'); +}; diff --git a/config/sets/symfony/symfony4/symfony44/symfony44-console.php b/config/sets/symfony/symfony4/symfony44/symfony44-console.php new file mode 100644 index 00000000..0804f8f3 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony44/symfony44-console.php @@ -0,0 +1,13 @@ +rules([ + // https://github.com/symfony/symfony/pull/33775 + ConsoleExecuteReturnIntRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony44/symfony44-dependency-injection.php b/config/sets/symfony/symfony4/symfony44/symfony44-dependency-injection.php new file mode 100644 index 00000000..73513ce3 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony44/symfony44-dependency-injection.php @@ -0,0 +1,12 @@ +ruleWithConfiguration(RenameFunctionRector::class, [ + 'Symfony\Component\DependencyInjection\Loader\Configurator\tagged' => 'Symfony\Component\DependencyInjection\Loader\Configurator\tagged_iterator', + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony44/symfony44-http-kernel.php b/config/sets/symfony/symfony4/symfony44/symfony44-http-kernel.php new file mode 100644 index 00000000..ee793b43 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony44/symfony44-http-kernel.php @@ -0,0 +1,25 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + // https://github.com/symfony/http-kernel/blob/801b925e308518ddf821ba91952c41ae77c77507/Event/GetResponseForExceptionEvent.php#L55 + new MethodCallRename( + 'Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent', + 'getException', + 'getThrowable' + ), + + // https://github.com/symfony/http-kernel/blob/801b925e308518ddf821ba91952c41ae77c77507/Event/GetResponseForExceptionEvent.php#L67 + new MethodCallRename( + 'Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent', + 'setException', + 'setThrowable' + ), + ]); +}; diff --git a/config/sets/symfony/symfony4/symfony44/symfony44-security-core.php b/config/sets/symfony/symfony4/symfony44/symfony44-security-core.php new file mode 100644 index 00000000..c6ee9603 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony44/symfony44-security-core.php @@ -0,0 +1,10 @@ +rules([AuthorizationCheckerIsGrantedExtractorRector::class]); +}; diff --git a/config/sets/symfony/symfony4/symfony44/symfony44-templating.php b/config/sets/symfony/symfony4/symfony44/symfony44-templating.php new file mode 100644 index 00000000..834ec702 --- /dev/null +++ b/config/sets/symfony/symfony4/symfony44/symfony44-templating.php @@ -0,0 +1,12 @@ +ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\Templating\EngineInterface' => 'Twig\Environment', + ]); +}; diff --git a/config/sets/symfony/symfony40.php b/config/sets/symfony/symfony40.php deleted file mode 100644 index 61e4afaa..00000000 --- a/config/sets/symfony/symfony40.php +++ /dev/null @@ -1,24 +0,0 @@ -rules([ - ConstraintUrlOptionRector::class, - FormIsValidRector::class, - VarDumperTestTraitMethodArgsRector::class, - ContainerBuilderCompileEnvArgumentRector::class, - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - 'Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest' => 'Symfony\Component\Validator\Test\ConstraintValidatorTestCase', - 'Symfony\Component\Process\ProcessBuilder' => 'Symfony\Component\Process\Process', - ]); -}; diff --git a/config/sets/symfony/symfony42.php b/config/sets/symfony/symfony42.php deleted file mode 100644 index 541301f0..00000000 --- a/config/sets/symfony/symfony42.php +++ /dev/null @@ -1,191 +0,0 @@ -ruleWithConfiguration(NewToStaticCallRector::class, [ - new NewToStaticCall( - 'Symfony\Component\HttpFoundation\Cookie', - 'Symfony\Component\HttpFoundation\Cookie', - 'create' - ), - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - # https://github.com/symfony/symfony/commit/a7e319d9e1316e2e18843f8ce15b67a8693e5bf9 - 'Symfony\Bundle\FrameworkBundle\Controller\Controller' => 'Symfony\Bundle\FrameworkBundle\Controller\AbstractController', - # https://github.com/symfony/symfony/commit/744bf0e7ac3ecf240d0bf055cc58f881bb0b3ec0 - 'Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand' => 'Symfony\Component\Console\Command\Command', - 'Symfony\Component\Translation\TranslatorInterface' => 'Symfony\Contracts\Translation\TranslatorInterface', - ]); - - $rectorConfig->rules([ - # https://symfony.com/blog/new-in-symfony-4-2-important-deprecations - StringToArrayArgumentProcessRector::class, - RootNodeTreeBuilderRector::class, - ]); - - $rectorConfig->ruleWithConfiguration(ArgumentAdderRector::class, [ - new ArgumentAdder( - 'Symfony\Component\DomCrawler\Crawler', - 'children', - 0, - null, - null, - null, - ArgumentAddingScope::SCOPE_METHOD_CALL - ), - new ArgumentAdder( - 'Symfony\Component\Finder\Finder', - 'sortByName', - 0, - null, - false, - null, - ArgumentAddingScope::SCOPE_METHOD_CALL - ), - new ArgumentAdder( - 'Symfony\Bridge\Monolog\Processor\DebugProcessor', - 'getLogs', - 0, - null, - null, - null, - ArgumentAddingScope::SCOPE_METHOD_CALL - ), - new ArgumentAdder( - 'Symfony\Bridge\Monolog\Processor\DebugProcessor', - 'countErrors', - 0, - 'default_value', - null, - null, - ArgumentAddingScope::SCOPE_METHOD_CALL - ), - new ArgumentAdder( - 'Symfony\Bridge\Monolog\Logger', - 'getLogs', - 0, - 'default_value', - null, - null, - ArgumentAddingScope::SCOPE_METHOD_CALL - ), - new ArgumentAdder( - 'Symfony\Bridge\Monolog\Logger', - 'countErrors', - 0, - 'default_value', - null, - null, - ArgumentAddingScope::SCOPE_METHOD_CALL - ), - new ArgumentAdder( - 'Symfony\Component\Serializer\Normalizer', - 'handleCircularReference', - 1, - null, - null, - null, - ArgumentAddingScope::SCOPE_METHOD_CALL - ), - new ArgumentAdder( - 'Symfony\Component\Serializer\Normalizer', - 'handleCircularReference', - 2, - null, - null, - null, - ArgumentAddingScope::SCOPE_METHOD_CALL - ), - ]); - - $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ - new MethodCallRename('Symfony\Component\Cache\CacheItem', 'getPreviousTags', 'getMetadata'), - new MethodCallRename('Symfony\Component\Form\AbstractTypeExtension', 'getExtendedType', 'getExtendedTypes'), - ]); - - $iterableType = new IterableType(new MixedType(), new MixedType()); - - $rectorConfig->ruleWithConfiguration(AddReturnTypeDeclarationRector::class, [ - new AddReturnTypeDeclaration( - 'Symfony\Component\Form\AbstractTypeExtension', - 'getExtendedTypes', - $iterableType - ), - ]); - - $rectorConfig->ruleWithConfiguration(ChangeMethodVisibilityRector::class, [new ChangeMethodVisibility( - 'Symfony\Component\Form\AbstractTypeExtension', - 'getExtendedTypes', - Visibility::STATIC - ), - ]); - - $rectorConfig->ruleWithConfiguration( - WrapReturnRector::class, - [new WrapReturn('Symfony\Component\Form\AbstractTypeExtension', 'getExtendedTypes', true)] - ); - - // https://github.com/symfony/symfony/commit/9493cfd5f2366dab19bbdde0d0291d0575454567 - $rectorConfig->ruleWithConfiguration(ReplaceArgumentDefaultValueRector::class, [ - new ReplaceArgumentDefaultValue( - 'Symfony\Component\HttpFoundation\Cookie', - MethodName::CONSTRUCT, - 5, - false, - null - ), - new ReplaceArgumentDefaultValue( - 'Symfony\Component\HttpFoundation\Cookie', - MethodName::CONSTRUCT, - 8, - null, - 'lax' - ), - ]); - - # https://github.com/symfony/symfony/commit/f5c355e1ba399a1b3512367647d902148bdaf09f - $rectorConfig->ruleWithConfiguration(ArgumentRemoverRector::class, [ - new ArgumentRemover( - 'Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector', - MethodName::CONSTRUCT, - 0, - null - ), - new ArgumentRemover( - 'Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector', - MethodName::CONSTRUCT, - 1, - null - ), - ]); -}; diff --git a/config/sets/symfony/symfony43.php b/config/sets/symfony/symfony43.php deleted file mode 100644 index e71f91fe..00000000 --- a/config/sets/symfony/symfony43.php +++ /dev/null @@ -1,97 +0,0 @@ -rules([ - WebTestCaseAssertIsSuccessfulRector::class, - WebTestCaseAssertResponseCodeRector::class, - TwigBundleFilesystemLoaderToTwigRector::class, - MakeDispatchFirstArgumentEventRector::class, - GetCurrencyBundleMethodCallsToIntlRector::class, - ConvertRenderTemplateShortNotationToBundleSyntaxRector::class, - EventDispatcherParentConstructRector::class, - ]); - - $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ - new MethodCallRename('Symfony\Component\BrowserKit\Response', 'getStatus', 'getStatusCode'), - new MethodCallRename('Symfony\Component\Security\Http\Firewall', 'handleRequest', 'callListeners'), - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - // assets deprecation - 'Symfony\Bundle\FrameworkBundle\Templating\Helper\AssetsHelper' => 'Symfony\Component\Asset\Packages', - - // templating - 'Symfony\Bundle\FrameworkBundle\Templating\EngineInterface' => 'Symfony\Component\Templating\EngineInterface', - - # https://symfony.com/blog/new-in-symfony-4-3-simpler-event-dispatching - # Browser Kit - 'Symfony\Component\BrowserKit\Client' => 'Symfony\Component\BrowserKit\AbstractBrowser', - # Cache - # https://github.com/symfony/symfony/pull/29236 - 'Symfony\Component\Cache\Traits\ApcuTrait\ApcuCache' => 'Symfony\Component\Cache\Traits\ApcuTrait\ApcuAdapter', - 'Symfony\Component\Cache\Adapter\SimpleCacheAdapter' => 'Symfony\Component\Cache\Adapter\Psr16Adapter', - 'Symfony\Component\Cache\Simple\ArrayCache' => 'Symfony\Component\Cache\Adapter\ArrayAdapter', - 'Symfony\Component\Cache\Simple\ChainCache' => 'Symfony\Component\Cache\Adapter\ChainAdapter', - 'Symfony\Component\Cache\Simple\DoctrineCache' => 'Symfony\Component\Cache\Adapter\DoctrineAdapter', - 'Symfony\Component\Cache\Simple\FilesystemCache' => 'Symfony\Component\Cache\Adapter\FilesystemAdapter', - 'Symfony\Component\Cache\Simple\MemcachedCache' => 'Symfony\Component\Cache\Adapter\MemcachedAdapter', - 'Symfony\Component\Cache\Simple\NullCache' => 'Symfony\Component\Cache\Adapter\NullAdapter', - 'Symfony\Component\Cache\Simple\PdoCache' => 'Symfony\Component\Cache\Adapter\PdoAdapter', - 'Symfony\Component\Cache\Simple\PhpArrayCache' => 'Symfony\Component\Cache\Adapter\PhpArrayAdapter', - 'Symfony\Component\Cache\Simple\PhpFilesCache' => 'Symfony\Component\Cache\Adapter\PhpFilesAdapter', - 'Symfony\Component\Cache\Simple\RedisCache' => 'Symfony\Component\Cache\Adapter\RedisAdapter', - 'Symfony\Component\Cache\Simple\TraceableCache' => 'Symfony\Component\Cache\Adapter\TraceableAdapterCache', - 'Symfony\Component\Cache\Simple\Psr6Cache' => 'Symfony\Component\Cache\Psr16Cache', - # EventDispatcher - 'Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent' => 'Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent', - 'Symfony\Component\HttpKernel\Event\FilterControllerEvent' => 'Symfony\Component\HttpKernel\Event\ControllerEvent', - 'Symfony\Component\HttpKernel\Event\FilterResponseEvent' => 'Symfony\Component\HttpKernel\Event\ResponseEvent', - 'Symfony\Component\HttpKernel\Event\GetResponseEvent' => 'Symfony\Component\HttpKernel\Event\RequestEvent', - 'Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent' => 'Symfony\Component\HttpKernel\Event\ViewEvent', - 'Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent' => 'Symfony\Component\HttpKernel\Event\ExceptionEvent', - 'Symfony\Component\HttpKernel\Event\PostResponseEvent' => 'Symfony\Component\HttpKernel\Event\TerminateEvent', - # has lowest priority, have to be last - 'Symfony\Component\EventDispatcher\Event' => 'Symfony\Contracts\EventDispatcher\Event', - # MimeType - 'Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface' => 'Symfony\Component\Mime\MimeTypesInterface', - 'Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesserInterface' => 'Symfony\Component\Mime\MimeTypesInterface', - 'Symfony\Component\HttpFoundation\File\MimeType\MimeTypeExtensionGuesser' => 'Symfony\Component\Mime\MimeTypes', - 'Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser' => 'Symfony\Component\Mime\FileBinaryMimeTypeGuesser', - 'Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser' => 'Symfony\Component\Mime\FileinfoMimeTypeGuesser', - # HttpKernel - # @todo unpack after YAML to PHP migration, Symfony\Component\HttpKernel\Client: Symfony\Component\HttpKernel\HttpKernelBrowser - 'Symfony\Component\HttpKernel\EventListener\TranslatorListener' => 'Symfony\Component\HttpKernel\EventListener\LocaleAwareListener', - # Security - 'Symfony\Component\Security\Core\Encoder\Argon2iPasswordEncoder' => 'Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder', - 'Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder' => 'Symfony\Component\Security\Core\Encoder\NativePasswordEncoder', - ]); - - # https://github.com/symfony/symfony/blob/4.4/UPGRADE-4.3.md#workflow - $rectorConfig->ruleWithConfiguration(ArgumentAdderRector::class, [ - new ArgumentAdder( - 'Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface', - 'setMarking', - 2, - 'context', - [] - ), - ]); -}; diff --git a/config/sets/symfony/symfony44.php b/config/sets/symfony/symfony44.php deleted file mode 100644 index 3d2e52b0..00000000 --- a/config/sets/symfony/symfony44.php +++ /dev/null @@ -1,45 +0,0 @@ -rules([ - // https://github.com/symfony/symfony/pull/33775 - ConsoleExecuteReturnIntRector::class, - // https://github.com/symfony/symfony/blob/4.4/UPGRADE-4.4.md#security - AuthorizationCheckerIsGrantedExtractorRector::class, - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - 'Symfony\Component\Templating\EngineInterface' => 'Twig\Environment', - ]); - - $rectorConfig->ruleWithConfiguration(RenameFunctionRector::class, [ - 'Symfony\Component\DependencyInjection\Loader\Configurator\tagged' => 'Symfony\Component\DependencyInjection\Loader\Configurator\tagged_iterator', - ]); - - $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ - # https://github.com/symfony/http-kernel/blob/801b925e308518ddf821ba91952c41ae77c77507/Event/GetResponseForExceptionEvent.php#L55 - new MethodCallRename( - 'Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent', - 'getException', - 'getThrowable' - ), - # https://github.com/symfony/http-kernel/blob/801b925e308518ddf821ba91952c41ae77c77507/Event/GetResponseForExceptionEvent.php#L67 - new MethodCallRename( - 'Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent', - 'setException', - 'setThrowable' - ), - ]); -}; diff --git a/config/sets/symfony/symfony5/symfony50.php b/config/sets/symfony/symfony5/symfony50.php new file mode 100644 index 00000000..450e0623 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony50.php @@ -0,0 +1,13 @@ +import(__DIR__ . '/symfony50/symfony50-types.php'); + $rectorConfig->import(__DIR__ . '/symfony50/symfony50-console.php'); + $rectorConfig->import(__DIR__ . '/symfony50/symfony50-debug.php'); +}; diff --git a/config/sets/symfony/symfony50.php b/config/sets/symfony/symfony5/symfony50/symfony50-console.php similarity index 61% rename from config/sets/symfony/symfony50.php rename to config/sets/symfony/symfony5/symfony50/symfony50-console.php index e1aeef38..43ecfa16 100644 --- a/config/sets/symfony/symfony50.php +++ b/config/sets/symfony/symfony5/symfony50/symfony50-console.php @@ -4,18 +4,9 @@ use Rector\Config\RectorConfig; use Rector\Renaming\Rector\MethodCall\RenameMethodRector; -use Rector\Renaming\Rector\Name\RenameClassRector; use Rector\Renaming\ValueObject\MethodCallRename; -# https://github.com/symfony/symfony/blob/5.0/UPGRADE-5.0.md - return static function (RectorConfig $rectorConfig): void { - $rectorConfig->import(__DIR__ . '/symfony50-types.php'); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - 'Symfony\Component\Debug\Debug' => 'Symfony\Component\ErrorHandler\Debug', - ]); - $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ new MethodCallRename('Symfony\Component\Console\Application', 'renderException', 'renderThrowable'), new MethodCallRename('Symfony\Component\Console\Application', 'doRenderException', 'doRenderThrowable'), diff --git a/config/sets/symfony/symfony5/symfony50/symfony50-debug.php b/config/sets/symfony/symfony5/symfony50/symfony50-debug.php new file mode 100644 index 00000000..9e4dbab1 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony50/symfony50-debug.php @@ -0,0 +1,12 @@ +ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\Debug\Debug' => 'Symfony\Component\ErrorHandler\Debug', + ]); +}; diff --git a/config/sets/symfony/symfony50-types.php b/config/sets/symfony/symfony5/symfony50/symfony50-types.php similarity index 94% rename from config/sets/symfony/symfony50-types.php rename to config/sets/symfony/symfony5/symfony50/symfony50-types.php index 18e1482e..a687fed9 100644 --- a/config/sets/symfony/symfony50-types.php +++ b/config/sets/symfony/symfony5/symfony50/symfony50-types.php @@ -355,5 +355,30 @@ 1, new StringType() ), + + new AddParamTypeDeclaration( + 'Symfony\Component\Security\Core\User\UserProviderInterface', + 'loadUserByUsername', + 0, + new StringType(), + ), + new AddParamTypeDeclaration( + 'Symfony\Component\Security\Core\User\UserProviderInterface', + 'supportsClass', + 0, + new StringType(), + ), + new AddParamTypeDeclaration( + 'Symfony\Bridge\Doctrine\Security\User\EntityUserProvider', + 'loadUserByUsername', + 0, + new StringType(), + ), + new AddParamTypeDeclaration( + 'Symfony\Bridge\Doctrine\Security\User\EntityUserProvider', + 'supportsClass', + 0, + new StringType(), + ), ]); }; diff --git a/config/sets/symfony/symfony5/symfony51.php b/config/sets/symfony/symfony5/symfony51.php new file mode 100644 index 00000000..a85f399f --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51.php @@ -0,0 +1,20 @@ +import(__DIR__ . '/symfony51/symfony51-config.php'); + $rectorConfig->import(__DIR__ . '/symfony51/symfony51-console.php'); + $rectorConfig->import(__DIR__ . '/symfony51/symfony51-dependency-injection.php'); + $rectorConfig->import(__DIR__ . '/symfony51/symfony51-event-dispatcher.php'); + $rectorConfig->import(__DIR__ . '/symfony51/symfony51-form.php'); + $rectorConfig->import(__DIR__ . '/symfony51/symfony51-framework-bundle.php'); + $rectorConfig->import(__DIR__ . '/symfony51/symfony51-http-foundation.php'); + $rectorConfig->import(__DIR__ . '/symfony51/symfony51-inflector.php'); + $rectorConfig->import(__DIR__ . '/symfony51/symfony51-notifier.php'); + $rectorConfig->import(__DIR__ . '/symfony51/symfony51-security-http.php'); + +}; diff --git a/config/sets/symfony/symfony5/symfony51/symfony51-config.php b/config/sets/symfony/symfony5/symfony51/symfony51-config.php new file mode 100644 index 00000000..d306f643 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51/symfony51-config.php @@ -0,0 +1,17 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename( + 'Symfony\Component\Config\Definition\BaseNode', + 'getDeprecationMessage', + 'getDeprecation' + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony51/symfony51-console.php b/config/sets/symfony/symfony5/symfony51/symfony51-console.php new file mode 100644 index 00000000..06dd6904 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51/symfony51-console.php @@ -0,0 +1,13 @@ +rules([ + // @see https://symfony.com/blog/new-in-symfony-5-1-misc-improvements-part-1#added-constants-for-command-exit-codes + CommandConstantReturnCodeRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony51/symfony51-dependency-injection.php b/config/sets/symfony/symfony5/symfony51/symfony51-dependency-injection.php new file mode 100644 index 00000000..593b257c --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51/symfony51-dependency-injection.php @@ -0,0 +1,28 @@ +ruleWithConfiguration(RenameFunctionRector::class, [ + 'Symfony\Component\DependencyInjection\Loader\Configuraton\inline' => 'Symfony\Component\DependencyInjection\Loader\Configuraton\inline_service', + 'Symfony\Component\DependencyInjection\Loader\Configuraton\ref' => 'Symfony\Component\DependencyInjection\Loader\Configuraton\service', + ]); + + $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename( + 'Symfony\Component\DependencyInjection\Definition', + 'getDeprecationMessage', + 'getDeprecation' + ), + new MethodCallRename( + 'Symfony\Component\DependencyInjection\Alias', + 'getDeprecationMessage', + 'getDeprecation' + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony51/symfony51-event-dispatcher.php b/config/sets/symfony/symfony5/symfony51/symfony51-event-dispatcher.php new file mode 100644 index 00000000..a904f727 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51/symfony51-event-dispatcher.php @@ -0,0 +1,12 @@ +ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy' => 'Symfony\Component\EventDispatcher\EventDispatcherInterface', + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony51/symfony51-form.php b/config/sets/symfony/symfony5/symfony51/symfony51-form.php new file mode 100644 index 00000000..b275a467 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51/symfony51-form.php @@ -0,0 +1,59 @@ +ruleWithConfiguration(RenameClassRector::class, [ + 'Symfony\Component\Form\Extension\Validator\Util\ServerParams' => 'Symfony\Component\Form\Util\ServerParams', + ]); + + $rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [ + new RenameClassAndConstFetch( + 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', + 'ROUND_FLOOR', + 'NumberFormatter', + 'ROUND_FLOOR' + ), + new RenameClassAndConstFetch( + 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', + 'ROUND_DOWN', + 'NumberFormatter', + 'ROUND_DOWN' + ), + new RenameClassAndConstFetch( + 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', + 'ROUND_HALF_DOWN', + 'NumberFormatter', + 'ROUND_HALFDOWN' + ), + new RenameClassAndConstFetch( + 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', + 'ROUND_HALF_EVEN', + 'NumberFormatter', + 'ROUND_HALFEVEN' + ), + new RenameClassAndConstFetch( + 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', + 'ROUND_HALFUP', + 'NumberFormatter', + 'ROUND_HALFUP' + ), + new RenameClassAndConstFetch( + 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', + 'ROUND_UP', + 'NumberFormatter', + 'ROUND_UP' + ), + new RenameClassAndConstFetch( + 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', + 'ROUND_CEILING', + 'NumberFormatter', + 'ROUND_CEILING' + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony51/symfony51-framework-bundle.php b/config/sets/symfony/symfony5/symfony51/symfony51-framework-bundle.php new file mode 100644 index 00000000..6445ce3c --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51/symfony51-framework-bundle.php @@ -0,0 +1,23 @@ +rules([RouteCollectionBuilderToRoutingConfiguratorRector::class]); + + // @see https://github.com/symfony/symfony/pull/36943 + $rectorConfig->ruleWithConfiguration(AddParamTypeDeclarationRector::class, [ + new AddParamTypeDeclaration( + 'Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait', + 'configureRoutes', + 0, + new ObjectType('Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator') + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony51/symfony51-http-foundation.php b/config/sets/symfony/symfony5/symfony51/symfony51-http-foundation.php new file mode 100644 index 00000000..b173120a --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51/symfony51-http-foundation.php @@ -0,0 +1,16 @@ +ruleWithConfiguration(StaticCallToNewRector::class, [ + new StaticCallToNew('Symfony\Component\HttpFoundation\Response', 'create'), + new StaticCallToNew('Symfony\Component\HttpFoundation\JsonResponse', 'create'), + new StaticCallToNew('Symfony\Component\HttpFoundation\RedirectResponse', 'create'), + new StaticCallToNew('Symfony\Component\HttpFoundation\StreamedResponse', 'create'), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony51/symfony51-inflector.php b/config/sets/symfony/symfony5/symfony51/symfony51-inflector.php new file mode 100644 index 00000000..625d778c --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51/symfony51-inflector.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // @see https://github.com/symfony/symfony/pull/35092 + 'Symfony\Component\Inflector' => 'Symfony\Component\String\Inflector\InflectorInterface', + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony51/symfony51-notifier.php b/config/sets/symfony/symfony5/symfony51/symfony51-notifier.php new file mode 100644 index 00000000..47486ab6 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51/symfony51-notifier.php @@ -0,0 +1,14 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + // @see https://github.com/symfony/symfony/pull/35828 + new MethodCallRename('Symfony\Component\Notifier\Bridge\Slack\Slack', 'channel', 'recipient'), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony51/symfony51-security-core.php b/config/sets/symfony/symfony5/symfony51/symfony51-security-core.php new file mode 100644 index 00000000..0ccf58c0 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51/symfony51-security-core.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameStringRector::class, [ + // @see https://github.com/symfony/symfony/pull/35858 + 'ROLE_PREVIOUS_ADMIN' => 'IS_IMPERSONATOR', + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony51/symfony51-security-http.php b/config/sets/symfony/symfony5/symfony51/symfony51-security-http.php new file mode 100644 index 00000000..b21ee710 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony51/symfony51-security-http.php @@ -0,0 +1,15 @@ +rules([ + // @see https://github.com/symfony/symfony/pull/36243 + LogoutHandlerToLogoutEventSubscriberRector::class, + LogoutSuccessHandlerToLogoutEventSubscriberRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony52-validator-attributes.php b/config/sets/symfony/symfony5/symfony52-validator-attributes.php similarity index 100% rename from config/sets/symfony/symfony52-validator-attributes.php rename to config/sets/symfony/symfony5/symfony52-validator-attributes.php diff --git a/config/sets/symfony/symfony5/symfony52.php b/config/sets/symfony/symfony5/symfony52.php new file mode 100644 index 00000000..f5ccb00b --- /dev/null +++ b/config/sets/symfony/symfony5/symfony52.php @@ -0,0 +1,23 @@ +sets([SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES]); + + $rectorConfig->import(__DIR__ . '/symfony52/symfony52-dependency-injection.php'); + $rectorConfig->import(__DIR__ . '/symfony52/symfony52-form.php'); + $rectorConfig->import(__DIR__ . '/symfony52/symfony52-http-foundation.php'); + $rectorConfig->import(__DIR__ . '/symfony52/symfony52-mime.php'); + $rectorConfig->import(__DIR__ . '/symfony52/symfony52-notifier.php'); + $rectorConfig->import(__DIR__ . '/symfony52/symfony52-property-access.php'); + $rectorConfig->import(__DIR__ . '/symfony52/symfony52-property-info.php'); + $rectorConfig->import(__DIR__ . '/symfony52/symfony52-security-core.php'); + $rectorConfig->import(__DIR__ . '/symfony52/symfony52-security-http.php'); + $rectorConfig->import(__DIR__ . '/symfony52/symfony52-validator.php'); + +}; diff --git a/config/sets/symfony/symfony5/symfony52/symfony52-dependency-injection.php b/config/sets/symfony/symfony5/symfony52/symfony52-dependency-injection.php new file mode 100644 index 00000000..3cd62181 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony52/symfony52-dependency-injection.php @@ -0,0 +1,13 @@ +rules([ + # https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#dependencyinjection + DefinitionAliasSetPrivateToSetPublicRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony52/symfony52-form.php b/config/sets/symfony/symfony5/symfony52/symfony52-form.php new file mode 100644 index 00000000..bd854929 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony52/symfony52-form.php @@ -0,0 +1,12 @@ +rules([PropertyPathMapperToDataMapperRector::class, FormBuilderSetDataMapperRector::class]); +}; diff --git a/config/sets/symfony/symfony5/symfony52/symfony52-http-foundation.php b/config/sets/symfony/symfony5/symfony52/symfony52-http-foundation.php new file mode 100644 index 00000000..26029db4 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony52/symfony52-http-foundation.php @@ -0,0 +1,13 @@ +rules([ + // https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#httpfoundation + BinaryFileResponseCreateToNewInstanceRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony52/symfony52-mime.php b/config/sets/symfony/symfony5/symfony52/symfony52-mime.php new file mode 100644 index 00000000..5cea7110 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony52/symfony52-mime.php @@ -0,0 +1,16 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + # https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#mime + new MethodCallRename('Symfony\Component\Mime\Address', 'fromString', 'create'), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony52/symfony52-notifier.php b/config/sets/symfony/symfony5/symfony52/symfony52-notifier.php new file mode 100644 index 00000000..cbba35eb --- /dev/null +++ b/config/sets/symfony/symfony5/symfony52/symfony52-notifier.php @@ -0,0 +1,56 @@ +ruleWithConfiguration(AddParamTypeDeclarationRector::class, [ + new AddParamTypeDeclaration( + 'Symfony\Component\Notifier\NotifierInterface', + 'send', + 1, + new ObjectType('Symfony\Component\Notifier\Recipient\RecipientInterface') + ), + new AddParamTypeDeclaration( + 'Symfony\Component\Notifier\Notifier', + 'getChannels', + 1, + new ObjectType('Symfony\Component\Notifier\Recipient\RecipientInterface') + ), + new AddParamTypeDeclaration( + 'Symfony\Component\Notifier\Channel\ChannelInterface', + 'notify', + 1, + new ObjectType('Symfony\Component\Notifier\Recipient\RecipientInterface') + ), + new AddParamTypeDeclaration( + 'Symfony\Component\Notifier\Channel\ChannelInterface', + 'supports', + 1, + new ObjectType('Symfony\Component\Notifier\Recipient\RecipientInterface') + ), + new AddParamTypeDeclaration( + 'Symfony\Component\Notifier\Notification\ChatNotificationInterface', + 'asChatMessage', + 0, + new ObjectType('Symfony\Component\Notifier\Recipient\RecipientInterface') + ), + new AddParamTypeDeclaration( + 'Symfony\Component\Notifier\Notification\EmailNotificationInterface', + 'asEmailMessage', + 0, + new ObjectType('Symfony\Component\Notifier\Recipient\EmailRecipientInterface') + ), + new AddParamTypeDeclaration( + 'Symfony\Component\Notifier\Notification\SmsNotificationInterface', + 'asSmsMessage', + 0, + new ObjectType('Symfony\Component\Notifier\Recipient\SmsRecipientInterface') + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony52/symfony52-property-access.php b/config/sets/symfony/symfony5/symfony52/symfony52-property-access.php new file mode 100644 index 00000000..d4d50c69 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony52/symfony52-property-access.php @@ -0,0 +1,13 @@ +rules([ + // https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#propertyaccess + PropertyAccessorCreationBooleanToFlagsRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony52/symfony52-property-info.php b/config/sets/symfony/symfony5/symfony52/symfony52-property-info.php new file mode 100644 index 00000000..11f3c564 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony52/symfony52-property-info.php @@ -0,0 +1,13 @@ +rules([ + // https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#propertyinfo + ReflectionExtractorEnableMagicCallExtractorRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony52/symfony52-security-core.php b/config/sets/symfony/symfony5/symfony52/symfony52-security-core.php new file mode 100644 index 00000000..82a2c9fa --- /dev/null +++ b/config/sets/symfony/symfony5/symfony52/symfony52-security-core.php @@ -0,0 +1,53 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename( + 'Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken', + 'setProviderKey', + 'setFirewallName' + ), + new MethodCallRename( + 'Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken', + 'getProviderKey', + 'getFirewallName' + ), + new MethodCallRename( + 'Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', + 'setProviderKey', + 'setFirewallName' + ), + new MethodCallRename( + 'Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', + 'getProviderKey', + 'getFirewallName' + ), + new MethodCallRename( + 'Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken', + 'setProviderKey', + 'setFirewallName' + ), + new MethodCallRename( + 'Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken', + 'getProviderKey', + 'getFirewallName' + ), + new MethodCallRename( + 'Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', + 'setProviderKey', + 'setFirewallName' + ), + new MethodCallRename( + 'Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', + 'getProviderKey', + 'getFirewallName' + ), + ]); + +}; diff --git a/config/sets/symfony/symfony5/symfony52/symfony52-security-http.php b/config/sets/symfony/symfony5/symfony52/symfony52-security-http.php new file mode 100644 index 00000000..94101332 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony52/symfony52-security-http.php @@ -0,0 +1,45 @@ +ruleWithConfiguration(RenameClassConstFetchRector::class, [ + new RenameClassAndConstFetch( + 'Symfony\Component\Security\Http\Firewall\AccessListener', + 'PUBLIC_ACCESS', + 'Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter', + 'PUBLIC_ACCESS' + ), + ]); + + # https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#security + $rectorConfig->ruleWithConfiguration(RenamePropertyRector::class, [ + new RenameProperty( + 'Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices', + 'providerKey', + 'firewallName' + ), + ]); + + $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename( + 'Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler', + 'setProviderKey', + 'setFirewallName' + ), + new MethodCallRename( + 'Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler', + 'getProviderKey', + 'getFirewallName' + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony52/symfony52-validator.php b/config/sets/symfony/symfony5/symfony52/symfony52-validator.php new file mode 100644 index 00000000..88120808 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony52/symfony52-validator.php @@ -0,0 +1,13 @@ +rules([ + # https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#validator + ValidatorBuilderEnableAnnotationMappingRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony53.php b/config/sets/symfony/symfony5/symfony53.php new file mode 100644 index 00000000..b54037e5 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony53.php @@ -0,0 +1,19 @@ +sets([SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES]); + + $rectorConfig->import(__DIR__ . '/symfony53/symfony53-http-foundation.php'); + $rectorConfig->import(__DIR__ . '/symfony53/symfony53-console.php'); + $rectorConfig->import(__DIR__ . '/symfony53/symfony53-http-kernel.php'); + $rectorConfig->import(__DIR__ . '/symfony53/symfony53-security-core.php'); + $rectorConfig->import(__DIR__ . '/symfony53/symfony53-mailer.php'); + $rectorConfig->import(__DIR__ . '/symfony53/symfony53-form.php'); + $rectorConfig->import(__DIR__ . '/symfony53/symfony53-framework-bundle.php'); +}; diff --git a/config/sets/symfony/symfony5/symfony53/symfony53-console.php b/config/sets/symfony/symfony5/symfony53/symfony53-console.php new file mode 100644 index 00000000..0485b22c --- /dev/null +++ b/config/sets/symfony/symfony5/symfony53/symfony53-console.php @@ -0,0 +1,18 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\Console\Helper\Helper', 'strlen', 'width'), + new MethodCallRename( + 'Symfony\Component\Console\Helper\Helper', + 'strlenWithoutDecoration', + 'removeDecoration', + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony53/symfony53-form.php b/config/sets/symfony/symfony5/symfony53/symfony53-form.php new file mode 100644 index 00000000..107ed88f --- /dev/null +++ b/config/sets/symfony/symfony5/symfony53/symfony53-form.php @@ -0,0 +1,27 @@ +ruleWithConfiguration(AddParamTypeDeclarationRector::class, [ + // @see https://github.com/symfony/symfony/commit/ce77be2507631cd12e4ca37510dab37f4c2b759a + new AddParamTypeDeclaration( + 'Symfony\Component\Form\DataMapperInterface', + 'mapFormsToData', + 0, + new ObjectType(Traversable::class) + ), + // @see https://github.com/symfony/symfony/commit/ce77be2507631cd12e4ca37510dab37f4c2b759a + new AddParamTypeDeclaration( + 'Symfony\Component\Form\DataMapperInterface', + 'mapDataToForms', + 1, + new ObjectType(Traversable::class) + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony53/symfony53-framework-bundle.php b/config/sets/symfony/symfony5/symfony53/symfony53-framework-bundle.php new file mode 100644 index 00000000..989cb52d --- /dev/null +++ b/config/sets/symfony/symfony5/symfony53/symfony53-framework-bundle.php @@ -0,0 +1,10 @@ +rules([KernelTestCaseContainerPropertyDeprecationRector::class]); +}; diff --git a/config/sets/symfony/symfony5/symfony53/symfony53-http-foundation.php b/config/sets/symfony/symfony5/symfony53/symfony53-http-foundation.php new file mode 100644 index 00000000..fcbc160f --- /dev/null +++ b/config/sets/symfony/symfony5/symfony53/symfony53-http-foundation.php @@ -0,0 +1,18 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + // @see https://github.com/symfony/symfony/pull/40536 + new MethodCallRename( + 'Symfony\Component\HttpFoundation\RequestStack', + 'getMasterRequest', + 'getMainRequest', + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony53/symfony53-http-kernel.php b/config/sets/symfony/symfony5/symfony53/symfony53-http-kernel.php new file mode 100644 index 00000000..89630fc7 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony53/symfony53-http-kernel.php @@ -0,0 +1,25 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename('Symfony\Component\HttpKernel\Event\KernelEvent', 'isMasterRequest', 'isMainRequest'), + ]); + + // rename constant + $rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [ + // @see https://github.com/symfony/symfony/pull/40536 + new RenameClassConstFetch( + 'Symfony\Component\HttpKernel\HttpKernelInterface', + 'MASTER_REQUEST', + 'MAIN_REQUEST' + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony53/symfony53-mailer.php b/config/sets/symfony/symfony5/symfony53/symfony53-mailer.php new file mode 100644 index 00000000..01292441 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony53/symfony53-mailer.php @@ -0,0 +1,18 @@ +ruleWithConfiguration(AddReturnTypeDeclarationRector::class, [ + new AddReturnTypeDeclaration( + 'Symfony\Component\Mailer\Transport\AbstractTransportFactory', + 'getEndpoint', + new StringType(), + ), + ]); +}; diff --git a/config/sets/symfony/symfony53.php b/config/sets/symfony/symfony5/symfony53/symfony53-security-core.php similarity index 52% rename from config/sets/symfony/symfony53.php rename to config/sets/symfony/symfony5/symfony53/symfony53-security-core.php index 4f187dba..8fa47ded 100644 --- a/config/sets/symfony/symfony53.php +++ b/config/sets/symfony/symfony5/symfony53/symfony53-security-core.php @@ -2,40 +2,13 @@ declare(strict_types=1); -use PHPStan\Type\ObjectType; -use PHPStan\Type\StringType; use Rector\Config\RectorConfig; -use Rector\Renaming\Rector\ClassConstFetch\RenameClassConstFetchRector; use Rector\Renaming\Rector\MethodCall\RenameMethodRector; use Rector\Renaming\Rector\Name\RenameClassRector; use Rector\Renaming\ValueObject\MethodCallRename; -use Rector\Renaming\ValueObject\RenameClassConstFetch; -use Rector\Symfony\Set\SymfonySetList; -use Rector\Symfony\Symfony53\Rector\StaticPropertyFetch\KernelTestCaseContainerPropertyDeprecationRector; -use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeDeclarationRector; -use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationRector; -use Rector\TypeDeclaration\ValueObject\AddParamTypeDeclaration; -use Rector\TypeDeclaration\ValueObject\AddReturnTypeDeclaration; - -# https://github.com/symfony/symfony/blob/5.4/UPGRADE-5.3.md return static function (RectorConfig $rectorConfig): void { - $rectorConfig->sets([SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES]); - $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ - // @see https://github.com/symfony/symfony/pull/40536 - new MethodCallRename( - 'Symfony\Component\HttpFoundation\RequestStack', - 'getMasterRequest', - 'getMainRequest', - ), - new MethodCallRename('Symfony\Component\Console\Helper\Helper', 'strlen', 'width'), - new MethodCallRename( - 'Symfony\Component\Console\Helper\Helper', - 'strlenWithoutDecoration', - 'removeDecoration', - ), - new MethodCallRename('Symfony\Component\HttpKernel\Event\KernelEvent', 'isMasterRequest', 'isMainRequest'), new MethodCallRename( 'Symfony\Component\Security\Core\Authentication\Token\TokenInterface', 'getUsername', @@ -73,41 +46,4 @@ 'Symfony\Component\Security\Core\Encoder\UserPasswordEncoder' => 'Symfony\Component\PasswordHasher\Hasher\UserPasswordHasher', 'Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface' => 'Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface', ]); - - $rectorConfig->ruleWithConfiguration(AddReturnTypeDeclarationRector::class, [ - new AddReturnTypeDeclaration( - 'Symfony\Component\Mailer\Transport\AbstractTransportFactory', - 'getEndpoint', - new StringType(), - ), - ]); - - // rename constant - $rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [ - // @see https://github.com/symfony/symfony/pull/40536 - new RenameClassConstFetch( - 'Symfony\Component\HttpKernel\HttpKernelInterface', - 'MASTER_REQUEST', - 'MAIN_REQUEST' - ), - ]); - - $rectorConfig->ruleWithConfiguration(AddParamTypeDeclarationRector::class, [ - // @see https://github.com/symfony/symfony/commit/ce77be2507631cd12e4ca37510dab37f4c2b759a - new AddParamTypeDeclaration( - 'Symfony\Component\Form\DataMapperInterface', - 'mapFormsToData', - 0, - new ObjectType(Traversable::class) - ), - // @see https://github.com/symfony/symfony/commit/ce77be2507631cd12e4ca37510dab37f4c2b759a - new AddParamTypeDeclaration( - 'Symfony\Component\Form\DataMapperInterface', - 'mapDataToForms', - 1, - new ObjectType(Traversable::class) - ), - ]); - - $rectorConfig->rules([KernelTestCaseContainerPropertyDeprecationRector::class]); }; diff --git a/config/sets/symfony/symfony5/symfony54.php b/config/sets/symfony/symfony5/symfony54.php new file mode 100644 index 00000000..4f551ce2 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony54.php @@ -0,0 +1,19 @@ +sets([SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES]); + + $rectorConfig->import(__DIR__ . '/symfony54/symfony54-validator.php'); + $rectorConfig->import(__DIR__ . '/symfony54/symfony54-security-bundle.php'); + $rectorConfig->import(__DIR__ . '/symfony54/symfony54-security-core.php'); + $rectorConfig->import(__DIR__ . '/symfony54/symfony54-security-http.php'); + $rectorConfig->import(__DIR__ . '/symfony54/symfony54-cache.php'); + $rectorConfig->import(__DIR__ . '/symfony54/symfony54-http-kernel.php'); + $rectorConfig->import(__DIR__ . '/symfony54/symfony54-notifier.php'); +}; diff --git a/config/sets/symfony/symfony5/symfony54/symfony54-cache.php b/config/sets/symfony/symfony5/symfony54/symfony54-cache.php new file mode 100644 index 00000000..fbdfcd42 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony54/symfony54-cache.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // @see https://github.com/symfony/symfony/pull/42965 + 'Symfony\Component\Cache\Adapter\DoctrineAdapter' => 'Doctrine\Common\Cache\Psr6\CacheAdapter', + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony54/symfony54-http-kernel.php b/config/sets/symfony/symfony5/symfony54/symfony54-http-kernel.php new file mode 100644 index 00000000..40b2318f --- /dev/null +++ b/config/sets/symfony/symfony5/symfony54/symfony54-http-kernel.php @@ -0,0 +1,14 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // @see https://github.com/symfony/symfony/pull/45615 + 'Symfony\Component\HttpKernel\EventListener\AbstractTestSessionListener' => 'Symfony\Component\HttpKernel\EventListener\AbstractSessionListener', + 'Symfony\Component\HttpKernel\EventListener\TestSessionListener' => 'Symfony\Component\HttpKernel\EventListener\SessionListener', + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony54/symfony54-notifier.php b/config/sets/symfony/symfony5/symfony54/symfony54-notifier.php new file mode 100644 index 00000000..aeee6b81 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony54/symfony54-notifier.php @@ -0,0 +1,14 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // @see https://github.com/symfony/symfony/pull/44271 + 'Symfony\Component\Notifier\Bridge\Nexmo\NexmoTransportFactory' => 'Symfony\Component\Notifier\Bridge\Vonage\VonageTransportFactory', + 'Symfony\Component\Notifier\Bridge\Nexmo\NexmoTransport' => 'Symfony\Component\Notifier\Bridge\Vonage\VonageTransport', + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony54/symfony54-security-bundle.php b/config/sets/symfony/symfony5/symfony54/symfony54-security-bundle.php new file mode 100644 index 00000000..ac917b7b --- /dev/null +++ b/config/sets/symfony/symfony5/symfony54/symfony54-security-bundle.php @@ -0,0 +1,24 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + // @see https://github.com/symfony/symfony/pull/42582 + new MethodCallRename( + 'Symfony\Bundle\SecurityBundle\Security\FirewallConfig', + 'getListeners', + 'getAuthenticators' + ), + // @see https://github.com/symfony/symfony/pull/41754 + new MethodCallRename( + 'Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension', + 'addSecurityListenerFactory', + 'addAuthenticatorFactory' + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony54/symfony54-security-core.php b/config/sets/symfony/symfony5/symfony54/symfony54-security-core.php new file mode 100644 index 00000000..f9447874 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony54/symfony54-security-core.php @@ -0,0 +1,36 @@ +ruleWithConfiguration(RenameClassConstFetchRector::class, [ + new RenameClassAndConstFetch( + 'Symfony\Component\Security\Core\AuthenticationEvents', + 'AUTHENTICATION_SUCCESS', + 'Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent', + 'class' + ), + new RenameClassAndConstFetch( + 'Symfony\Component\Security\Core\AuthenticationEvents', + 'AUTHENTICATION_FAILURE', + 'Symfony\Component\Security\Core\Event\AuthenticationFailureEvent', + 'class' + ), + // @see https://github.com/symfony/symfony/pull/42510 + new RenameClassConstFetch( + 'Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter', + 'IS_ANONYMOUS', + 'PUBLIC_ACCESS' + ), + new RenameClassConstFetch( + 'Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter', + 'IS_AUTHENTICATED_ANONYMOUSLY', + 'PUBLIC_ACCESS' + ), + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony54/symfony54-security-http.php b/config/sets/symfony/symfony5/symfony54/symfony54-security-http.php new file mode 100644 index 00000000..85537433 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony54/symfony54-security-http.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // @see https://github.com/symfony/symfony/pull/42050 + 'Symfony\Component\Security\Http\Event\DeauthenticatedEvent' => 'Symfony\Component\Security\Http\Event\TokenDeauthenticatedEvent', + ]); +}; diff --git a/config/sets/symfony/symfony5/symfony54/symfony54-validator.php b/config/sets/symfony/symfony5/symfony54/symfony54-validator.php new file mode 100644 index 00000000..f3a446e3 --- /dev/null +++ b/config/sets/symfony/symfony5/symfony54/symfony54-validator.php @@ -0,0 +1,18 @@ +ruleWithConfiguration(AnnotationToAttributeRector::class, [ + new AnnotationToAttribute('Symfony\Component\Validator\Constraints\All'), + new AnnotationToAttribute('Symfony\Component\Validator\Constraints\Collection'), + new AnnotationToAttribute('Symfony\Component\Validator\Constraints\AtLeastOneOf'), + new AnnotationToAttribute('Symfony\Component\Validator\Constraints\Sequentially'), + ]); +}; diff --git a/config/sets/symfony/symfony51.php b/config/sets/symfony/symfony51.php deleted file mode 100644 index 31290453..00000000 --- a/config/sets/symfony/symfony51.php +++ /dev/null @@ -1,131 +0,0 @@ -rules([ - // @see https://github.com/symfony/symfony/pull/36243 - LogoutHandlerToLogoutEventSubscriberRector::class, - LogoutSuccessHandlerToLogoutEventSubscriberRector::class, - // @see https://symfony.com/blog/new-in-symfony-5-1-misc-improvements-part-1#added-constants-for-command-exit-codes - CommandConstantReturnCodeRector::class, - RouteCollectionBuilderToRoutingConfiguratorRector::class, - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - 'Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy' => 'Symfony\Component\EventDispatcher\EventDispatcherInterface', - 'Symfony\Component\Form\Extension\Validator\Util\ServerParams' => 'Symfony\Component\Form\Util\ServerParams', - // @see https://github.com/symfony/symfony/pull/35092 - 'Symfony\Component\Inflector' => 'Symfony\Component\String\Inflector\InflectorInterface', - ]); - - $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ - new MethodCallRename( - 'Symfony\Component\Config\Definition\BaseNode', - 'getDeprecationMessage', - 'getDeprecation' - ), - new MethodCallRename( - 'Symfony\Component\DependencyInjection\Definition', - 'getDeprecationMessage', - 'getDeprecation' - ), - new MethodCallRename( - 'Symfony\Component\DependencyInjection\Alias', - 'getDeprecationMessage', - 'getDeprecation' - ), - // @see https://github.com/symfony/symfony/pull/35828 - new MethodCallRename('Symfony\Component\Notifier\Bridge\Slack\Slack', 'channel', 'recipient'), - ]); - - $rectorConfig->ruleWithConfiguration(RenameFunctionRector::class, [ - 'Symfony\Component\DependencyInjection\Loader\Configuraton\inline' => 'Symfony\Component\DependencyInjection\Loader\Configuraton\inline_service', - 'Symfony\Component\DependencyInjection\Loader\Configuraton\ref' => 'Symfony\Component\DependencyInjection\Loader\Configuraton\service', - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [ - new RenameClassAndConstFetch( - 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', - 'ROUND_FLOOR', - 'NumberFormatter', - 'ROUND_FLOOR' - ), - new RenameClassAndConstFetch( - 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', - 'ROUND_DOWN', - 'NumberFormatter', - 'ROUND_DOWN' - ), - new RenameClassAndConstFetch( - 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', - 'ROUND_HALF_DOWN', - 'NumberFormatter', - 'ROUND_HALFDOWN' - ), - new RenameClassAndConstFetch( - 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', - 'ROUND_HALF_EVEN', - 'NumberFormatter', - 'ROUND_HALFEVEN' - ), - new RenameClassAndConstFetch( - 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', - 'ROUND_HALFUP', - 'NumberFormatter', - 'ROUND_HALFUP' - ), - new RenameClassAndConstFetch( - 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', - 'ROUND_UP', - 'NumberFormatter', - 'ROUND_UP' - ), - new RenameClassAndConstFetch( - 'Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer', - 'ROUND_CEILING', - 'NumberFormatter', - 'ROUND_CEILING' - ), - ]); - - // @see https://github.com/symfony/symfony/pull/36943 - $rectorConfig->ruleWithConfiguration(AddParamTypeDeclarationRector::class, [ - new AddParamTypeDeclaration( - 'Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait', - 'configureRoutes', - 0, - new ObjectType('Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator') - ), - ]); - $rectorConfig->ruleWithConfiguration(StaticCallToNewRector::class, [ - new StaticCallToNew('Symfony\Component\HttpFoundation\Response', 'create'), - new StaticCallToNew('Symfony\Component\HttpFoundation\JsonResponse', 'create'), - new StaticCallToNew('Symfony\Component\HttpFoundation\RedirectResponse', 'create'), - new StaticCallToNew('Symfony\Component\HttpFoundation\StreamedResponse', 'create'), - ]); - - $rectorConfig->ruleWithConfiguration(RenameStringRector::class, [ - // @see https://github.com/symfony/symfony/pull/35858 - 'ROLE_PREVIOUS_ADMIN' => 'IS_IMPERSONATOR', - ]); -}; diff --git a/config/sets/symfony/symfony52.php b/config/sets/symfony/symfony52.php deleted file mode 100644 index 3fd7ea04..00000000 --- a/config/sets/symfony/symfony52.php +++ /dev/null @@ -1,172 +0,0 @@ -sets([SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES]); - - $rectorConfig->rules([ - // https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#form - PropertyPathMapperToDataMapperRector::class, - - // https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#httpfoundation - BinaryFileResponseCreateToNewInstanceRector::class, - - // https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#propertyaccess - PropertyAccessorCreationBooleanToFlagsRector::class, - - // https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#propertyinfo - ReflectionExtractorEnableMagicCallExtractorRector::class, - - # https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#dependencyinjection - DefinitionAliasSetPrivateToSetPublicRector::class, - - # https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#form - FormBuilderSetDataMapperRector::class, - - # https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#validator - ValidatorBuilderEnableAnnotationMappingRector::class, - ]); - - # https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#security - $rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [ - new RenameClassAndConstFetch( - 'Symfony\Component\Security\Http\Firewall\AccessListener', - 'PUBLIC_ACCESS', - 'Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter', - 'PUBLIC_ACCESS' - ), - ]); - - $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ - # https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#mime - new MethodCallRename('Symfony\Component\Mime\Address', 'fromString', 'create'), - - new MethodCallRename( - 'Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken', - 'setProviderKey', - 'setFirewallName' - ), - new MethodCallRename( - 'Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken', - 'getProviderKey', - 'getFirewallName' - ), - new MethodCallRename( - 'Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', - 'setProviderKey', - 'setFirewallName' - ), - new MethodCallRename( - 'Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', - 'getProviderKey', - 'getFirewallName' - ), - new MethodCallRename( - 'Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken', - 'setProviderKey', - 'setFirewallName' - ), - new MethodCallRename( - 'Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken', - 'getProviderKey', - 'getFirewallName' - ), - new MethodCallRename( - 'Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', - 'setProviderKey', - 'setFirewallName' - ), - new MethodCallRename( - 'Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', - 'getProviderKey', - 'getFirewallName' - ), - new MethodCallRename( - 'Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler', - 'setProviderKey', - 'setFirewallName' - ), - new MethodCallRename( - 'Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler', - 'getProviderKey', - 'getFirewallName' - ), - ]); - - # https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#notifier - $rectorConfig->ruleWithConfiguration(AddParamTypeDeclarationRector::class, [ - new AddParamTypeDeclaration( - 'Symfony\Component\Notifier\NotifierInterface', - 'send', - 1, - new ObjectType('Symfony\Component\Notifier\Recipient\RecipientInterface') - ), - new AddParamTypeDeclaration( - 'Symfony\Component\Notifier\Notifier', - 'getChannels', - 1, - new ObjectType('Symfony\Component\Notifier\Recipient\RecipientInterface') - ), - new AddParamTypeDeclaration( - 'Symfony\Component\Notifier\Channel\ChannelInterface', - 'notify', - 1, - new ObjectType('Symfony\Component\Notifier\Recipient\RecipientInterface') - ), - new AddParamTypeDeclaration( - 'Symfony\Component\Notifier\Channel\ChannelInterface', - 'supports', - 1, - new ObjectType('Symfony\Component\Notifier\Recipient\RecipientInterface') - ), - new AddParamTypeDeclaration( - 'Symfony\Component\Notifier\Notification\ChatNotificationInterface', - 'asChatMessage', - 0, - new ObjectType('Symfony\Component\Notifier\Recipient\RecipientInterface') - ), - new AddParamTypeDeclaration( - 'Symfony\Component\Notifier\Notification\EmailNotificationInterface', - 'asEmailMessage', - 0, - new ObjectType('Symfony\Component\Notifier\Recipient\EmailRecipientInterface') - ), - new AddParamTypeDeclaration( - 'Symfony\Component\Notifier\Notification\SmsNotificationInterface', - 'asSmsMessage', - 0, - new ObjectType('Symfony\Component\Notifier\Recipient\SmsRecipientInterface') - ), - ]); - - # https://github.com/symfony/symfony/blob/5.x/UPGRADE-5.2.md#security - $rectorConfig->ruleWithConfiguration(RenamePropertyRector::class, [ - new RenameProperty( - 'Symfony\Component\Security\Http\RememberMe\AbstractRememberMeServices', - 'providerKey', - 'firewallName' - ), - ]); -}; diff --git a/config/sets/symfony/symfony54.php b/config/sets/symfony/symfony54.php deleted file mode 100644 index 21e4b258..00000000 --- a/config/sets/symfony/symfony54.php +++ /dev/null @@ -1,82 +0,0 @@ -sets([SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES]); - - // @see https://symfony.com/blog/new-in-symfony-5-4-nested-validation-attributes - // @see https://github.com/symfony/symfony/pull/41994 - $rectorConfig->ruleWithConfiguration(AnnotationToAttributeRector::class, [ - new AnnotationToAttribute('Symfony\Component\Validator\Constraints\All'), - new AnnotationToAttribute('Symfony\Component\Validator\Constraints\Collection'), - new AnnotationToAttribute('Symfony\Component\Validator\Constraints\AtLeastOneOf'), - new AnnotationToAttribute('Symfony\Component\Validator\Constraints\Sequentially'), - ]); - $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ - // @see https://github.com/symfony/symfony/pull/42582 - new MethodCallRename( - 'Symfony\Bundle\SecurityBundle\Security\FirewallConfig', - 'getListeners', - 'getAuthenticators' - ), - // @see https://github.com/symfony/symfony/pull/41754 - new MethodCallRename( - 'Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension', - 'addSecurityListenerFactory', - 'addAuthenticatorFactory' - ), - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [ - new RenameClassAndConstFetch( - 'Symfony\Component\Security\Core\AuthenticationEvents', - 'AUTHENTICATION_SUCCESS', - 'Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent', - 'class' - ), - new RenameClassAndConstFetch( - 'Symfony\Component\Security\Core\AuthenticationEvents', - 'AUTHENTICATION_FAILURE', - 'Symfony\Component\Security\Core\Event\AuthenticationFailureEvent', - 'class' - ), - // @see https://github.com/symfony/symfony/pull/42510 - new RenameClassConstFetch( - 'Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter', - 'IS_ANONYMOUS', - 'PUBLIC_ACCESS' - ), - new RenameClassConstFetch( - 'Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter', - 'IS_AUTHENTICATED_ANONYMOUSLY', - 'PUBLIC_ACCESS' - ), - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - // @see https://github.com/symfony/symfony/pull/42050 - 'Symfony\Component\Security\Http\Event\DeauthenticatedEvent' => 'Symfony\Component\Security\Http\Event\TokenDeauthenticatedEvent', - // @see https://github.com/symfony/symfony/pull/42965 - 'Symfony\Component\Cache\Adapter\DoctrineAdapter' => 'Doctrine\Common\Cache\Psr6\CacheAdapter', - // @see https://github.com/symfony/symfony/pull/45615 - 'Symfony\Component\HttpKernel\EventListener\AbstractTestSessionListener' => 'Symfony\Component\HttpKernel\EventListener\AbstractSessionListener', - 'Symfony\Component\HttpKernel\EventListener\TestSessionListener' => 'Symfony\Component\HttpKernel\EventListener\SessionListener', - // @see https://github.com/symfony/symfony/pull/44271 - 'Symfony\Component\Notifier\Bridge\Nexmo\NexmoTransportFactory' => 'Symfony\Component\Notifier\Bridge\Vonage\VonageTransportFactory', - 'Symfony\Component\Notifier\Bridge\Nexmo\NexmoTransport' => 'Symfony\Component\Notifier\Bridge\Vonage\VonageTransport', - ]); -}; diff --git a/config/sets/symfony/symfony6/symfony60.php b/config/sets/symfony/symfony6/symfony60.php new file mode 100644 index 00000000..e80bde6d --- /dev/null +++ b/config/sets/symfony/symfony6/symfony60.php @@ -0,0 +1,20 @@ +sets([SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES]); + + $rectorConfig->import(__DIR__ . '/symfony-return-types.php'); // todo: extract this as well + + $rectorConfig->import(__DIR__ . '/symfony60/symfony60-dependency-injection.php'); + $rectorConfig->import(__DIR__ . '/symfony60/symfony60-contracts.php'); + $rectorConfig->import(__DIR__ . '/symfony60/symfony60-config.php'); + $rectorConfig->import(__DIR__ . '/symfony60/symfony60-framework-bundle.php'); + $rectorConfig->import(__DIR__ . '/symfony60/symfony60-doctrine-bridge.php'); + $rectorConfig->import(__DIR__ . '/symfony60/symfony60-security-core.php'); +}; diff --git a/config/sets/symfony/symfony6/symfony60/symfony60-config.php b/config/sets/symfony/symfony6/symfony60/symfony60-config.php new file mode 100644 index 00000000..a954aa5b --- /dev/null +++ b/config/sets/symfony/symfony6/symfony60/symfony60-config.php @@ -0,0 +1,25 @@ +ruleWithConfiguration(AddParamTypeDeclarationRector::class, [ + new AddParamTypeDeclaration( + 'Symfony\Component\Config\Loader\LoaderInterface', + 'load', + 0, + new MixedType(true) + ), + new AddParamTypeDeclaration( + 'Symfony\Component\Config\Loader\LoaderInterface', + 'supports', + 0, + new MixedType(true) + ), + ]); +}; diff --git a/config/sets/symfony/symfony6/symfony60/symfony60-contracts.php b/config/sets/symfony/symfony6/symfony60/symfony60-contracts.php new file mode 100644 index 00000000..26318e47 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony60/symfony60-contracts.php @@ -0,0 +1,13 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // @see https://github.com/symfony/symfony/pull/39484 + 'Symfony\Contracts\HttpClient\HttpClientInterface\RemoteJsonManifestVersionStrategy' => 'Symfony\Component\Asset\VersionStrategy\JsonManifestVersionStrategy', + ]); +}; diff --git a/config/sets/symfony/symfony6/symfony60/symfony60-dependency-injection.php b/config/sets/symfony/symfony6/symfony60/symfony60-dependency-injection.php new file mode 100644 index 00000000..4bf9cdd9 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony60/symfony60-dependency-injection.php @@ -0,0 +1,18 @@ +ruleWithConfiguration(ReplaceServiceArgumentRector::class, [ + new ReplaceServiceArgument('Psr\Container\ContainerInterface', new String_('service_container')), + new ReplaceServiceArgument( + 'Symfony\Component\DependencyInjection\ContainerInterface', + new String_('service_container') + ), + ]); +}; diff --git a/config/sets/symfony/symfony6/symfony60/symfony60-doctrine-bridge.php b/config/sets/symfony/symfony6/symfony60/symfony60-doctrine-bridge.php new file mode 100644 index 00000000..6172ca0b --- /dev/null +++ b/config/sets/symfony/symfony6/symfony60/symfony60-doctrine-bridge.php @@ -0,0 +1,20 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + // @see https://github.com/symfony/symfony/pull/40403 + new MethodCallRename( + 'Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface', + 'loadUserByUsername', + 'loadUserByIdentifier' + ), + ]); +}; diff --git a/config/sets/symfony/symfony6/symfony60/symfony60-framework-bundle.php b/config/sets/symfony/symfony6/symfony60/symfony60-framework-bundle.php new file mode 100644 index 00000000..a39bf210 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony60/symfony60-framework-bundle.php @@ -0,0 +1,21 @@ +ruleWithConfiguration(AddParamTypeDeclarationRector::class, [ + new AddParamTypeDeclaration( + 'Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait', + 'configureRoutes', + 0, + new ObjectType('Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator'), + ), + ]); + $rectorConfig->rule(GetHelperControllerToServiceRector::class); +}; diff --git a/config/sets/symfony/symfony6/symfony60/symfony60-security-core.php b/config/sets/symfony/symfony6/symfony60/symfony60-security-core.php new file mode 100644 index 00000000..8e745abf --- /dev/null +++ b/config/sets/symfony/symfony6/symfony60/symfony60-security-core.php @@ -0,0 +1,23 @@ +ruleWithConfiguration(RenameMethodRector::class, [ + new MethodCallRename( + 'Symfony\Component\Security\Core\User\UserProviderInterface', + 'loadUserByUsername', + 'loadUserByIdentifier', + ), + // @see https://github.com/rectorphp/rector-symfony/issues/112 + new MethodCallRename( + 'Symfony\Component\Security\Core\User\UserInterface', + 'getUsername', + 'getUserIdentifier', + ), + ]); +}; diff --git a/config/sets/symfony/symfony6/symfony61.php b/config/sets/symfony/symfony6/symfony61.php new file mode 100644 index 00000000..97c9eac3 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony61.php @@ -0,0 +1,14 @@ +import(__DIR__ . '/symfony61/symfony61-serializer.php'); + $rectorConfig->import(__DIR__ . '/symfony61/symfony61-validator.php'); + $rectorConfig->import(__DIR__ . '/symfony61/symfony61-console.php'); + $rectorConfig->import(__DIR__ . '/symfony61/symfony61-twig-bridge.php'); +}; diff --git a/config/sets/symfony/symfony6/symfony61/symfony61-console.php b/config/sets/symfony/symfony6/symfony61/symfony61-console.php new file mode 100644 index 00000000..c9207808 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony61/symfony61-console.php @@ -0,0 +1,14 @@ +rules([ + CommandConfigureToAttributeRector::class, + CommandPropertyToAttributeRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony6/symfony61/symfony61-serializer.php b/config/sets/symfony/symfony6/symfony61/symfony61-serializer.php new file mode 100644 index 00000000..3ea81200 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony61/symfony61-serializer.php @@ -0,0 +1,14 @@ +ruleWithConfiguration(RenameClassRector::class, [ + // @see https://github.com/symfony/symfony/pull/43982 + 'Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface' => 'Symfony\Component\Serializer\Normalizer\DenormalizerInterface', + 'Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface' => 'Symfony\Component\Serializer\Normalizer\NormalizerInterface', + ]); +}; diff --git a/config/sets/symfony/symfony6/symfony61/symfony61-twig-bridge.php b/config/sets/symfony/symfony6/symfony61/symfony61-twig-bridge.php new file mode 100644 index 00000000..928fa6cd --- /dev/null +++ b/config/sets/symfony/symfony6/symfony61/symfony61-twig-bridge.php @@ -0,0 +1,10 @@ +rule(MagicClosureTwigExtensionToNativeMethodsRector::class); +}; diff --git a/config/sets/symfony/symfony6/symfony61/symfony61-validator.php b/config/sets/symfony/symfony6/symfony61/symfony61-validator.php new file mode 100644 index 00000000..eac0207d --- /dev/null +++ b/config/sets/symfony/symfony6/symfony61/symfony61-validator.php @@ -0,0 +1,16 @@ +rule(ErrorNamesPropertyToConstantRector::class); + $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ + // @see https://github.com/symfony/symfony/pull/45623 + 'Symfony\Component\Validator\Constraints\ExpressionLanguageSyntax' => 'Symfony\Component\Validator\Constraints\ExpressionSyntax', + 'Symfony\Component\Validator\Constraints\ExpressionLanguageSyntaxValidator' => 'Symfony\Component\Validator\Constraints\ExpressionSyntaxValidator', + ]); +}; diff --git a/config/sets/symfony/symfony6/symfony62.php b/config/sets/symfony/symfony6/symfony62.php new file mode 100644 index 00000000..fd8a16d7 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62.php @@ -0,0 +1,33 @@ +ruleWithConfiguration(AnnotationToAttributeRector::class, [ + // @see https://github.com/symfony/symfony/pull/46907 + new AnnotationToAttribute('Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted'), + // @see https://github.com/symfony/symfony/pull/46880 + new AnnotationToAttribute('Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache'), + // @see https://github.com/symfony/symfony/pull/46906 + new AnnotationToAttribute('Sensio\Bundle\FrameworkExtraBundle\Configuration\Template'), + ]); + + $rectorConfig->import(__DIR__ . '/symfony62/symfony62-security-core.php'); + $rectorConfig->import(__DIR__ . '/symfony62/symfony62-security-http.php'); + $rectorConfig->import(__DIR__ . '/symfony62/symfony62-mime.php'); + $rectorConfig->import(__DIR__ . '/symfony62/symfony62-http-kernel.php'); + $rectorConfig->import(__DIR__ . '/symfony62/symfony62-framework-bundle.php'); + $rectorConfig->import(__DIR__ . '/symfony62/symfony62-http-foundation.php'); + $rectorConfig->import(__DIR__ . '/symfony62/symfony62-twig-bridge.php'); + $rectorConfig->import(__DIR__ . '/symfony62/symfony62-translation.php'); + $rectorConfig->import(__DIR__ . '/symfony62/symfony62-doctrine-bridge.php'); + $rectorConfig->import(__DIR__ . '/symfony62/symfony62-messenger.php'); + $rectorConfig->import(__DIR__ . '/symfony62/symfony62-mail-pace-mailer.php'); +}; diff --git a/config/sets/symfony/symfony6/symfony62/symfony62-doctrine-bridge.php b/config/sets/symfony/symfony6/symfony62/symfony62-doctrine-bridge.php new file mode 100644 index 00000000..9a3f18a7 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62/symfony62-doctrine-bridge.php @@ -0,0 +1,10 @@ +rule(ParamConverterAttributeToMapEntityAttributeRector::class); +}; diff --git a/config/sets/symfony/symfony6/symfony62/symfony62-framework-bundle.php b/config/sets/symfony/symfony6/symfony62/symfony62-framework-bundle.php new file mode 100644 index 00000000..51876555 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62/symfony62-framework-bundle.php @@ -0,0 +1,24 @@ +rule(SimplifyFormRenderingRector::class); + + $rectorConfig->ruleWithConfiguration( + RenameMethodRector::class, + [ + // @see https://github.com/symfony/symfony/pull/46854 + new MethodCallRename( + 'Symfony\Bundle\FrameworkBundle\Controller\AbstractController', + 'renderForm', + 'render' + ), + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony62/symfony62-http-foundation.php b/config/sets/symfony/symfony6/symfony62/symfony62-http-foundation.php new file mode 100644 index 00000000..30854a40 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62/symfony62-http-foundation.php @@ -0,0 +1,32 @@ +ruleWithConfiguration( + RenameClassRector::class, + [ + // @see https://github.com/symfony/symfony/pull/47595 + 'Symfony\Component\HttpFoundation\ExpressionRequestMatcher' => 'Symfony\Component\HttpFoundation\RequestMatcher\ExpressionRequestMatcher', + 'Symfony\Component\HttpFoundation\RequestMatcher' => 'Symfony\Component\HttpFoundation\ChainRequestMatcher', + ], + ); + + $rectorConfig->ruleWithConfiguration( + RenameMethodRector::class, + [ + // @see https://github.com/symfony/symfony/pull/45034 + new MethodCallRename( + 'Symfony\Component\HttpFoundation\Request', + 'getContentType', + 'getContentTypeFormat' + ), + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony62/symfony62-http-kernel.php b/config/sets/symfony/symfony6/symfony62/symfony62-http-kernel.php new file mode 100644 index 00000000..093805ae --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62/symfony62-http-kernel.php @@ -0,0 +1,25 @@ +rules([ + // @see https://github.com/symfony/symfony/pull/47363 + ArgumentValueResolverToValueResolverRector::class, + ]); + + // https://symfony.com/blog/new-in-symfony-6-2-built-in-cache-security-template-and-doctrine-attributes + $rectorConfig->ruleWithConfiguration( + RenameClassRector::class, + [ + // @see https://github.com/symfony/symfony/pull/46880 + 'Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache' => 'Symfony\Component\HttpKernel\Attribute\Cache', + // @see https://github.com/symfony/symfony/pull/47363 + 'Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface' => 'Symfony\Component\HttpKernel\Controller\ValueResolverInterface', + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony62/symfony62-mail-pace-mailer.php b/config/sets/symfony/symfony6/symfony62/symfony62-mail-pace-mailer.php new file mode 100644 index 00000000..3f9349cb --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62/symfony62-mail-pace-mailer.php @@ -0,0 +1,19 @@ +ruleWithConfiguration( + RenameClassRector::class, + [ + // @see https://github.com/symfony/symfony/pull/46714 + 'Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpApiTransport' => 'Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceApiTransport', + 'Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpSmtpTransport' => 'Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceSmtpTransport', + 'Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory' => 'Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceTransportFactory', + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony62/symfony62-messenger.php b/config/sets/symfony/symfony6/symfony62/symfony62-messenger.php new file mode 100644 index 00000000..55f635c1 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62/symfony62-messenger.php @@ -0,0 +1,15 @@ +rules([ + // @see https://github.com/symfony/symfony/pull/47068, #[AsMessageHandler] attribute + MessageHandlerInterfaceToAttributeRector::class, + MessageSubscriberInterfaceToAttributeRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony6/symfony62/symfony62-mime.php b/config/sets/symfony/symfony6/symfony62/symfony62-mime.php new file mode 100644 index 00000000..85ec9339 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62/symfony62-mime.php @@ -0,0 +1,17 @@ +ruleWithConfiguration( + RenameMethodRector::class, + [ + // @see https://github.com/symfony/symfony/pull/47711 + new MethodCallRename('Symfony\Component\Mime\Email', 'attachPart', 'addPart'), + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony62/symfony62-security-core.php b/config/sets/symfony/symfony6/symfony62/symfony62-security-core.php new file mode 100644 index 00000000..68be856b --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62/symfony62-security-core.php @@ -0,0 +1,48 @@ +ruleWithConfiguration( + RenameClassRector::class, + [ + // @see https://github.com/symfony/symfony/pull/46094 + 'Symfony\Component\Security\Core\Security' => 'Symfony\Bundle\SecurityBundle\Security', + ], + ); + + // @see https://github.com/symfony/symfony/pull/46094 + // @see https://github.com/symfony/symfony/pull/48554 + $rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [ + new RenameClassAndConstFetch( + 'Symfony\Component\Security\Core\Security', + 'ACCESS_DENIED_ERROR', + 'Symfony\Component\Security\Http\SecurityRequestAttributes', + 'ACCESS_DENIED_ERROR' + ), + new RenameClassAndConstFetch( + 'Symfony\Component\Security\Core\Security', + 'AUTHENTICATION_ERROR', + 'Symfony\Component\Security\Http\SecurityRequestAttributes', + 'AUTHENTICATION_ERROR' + ), + new RenameClassAndConstFetch( + 'Symfony\Component\Security\Core\Security', + 'LAST_USERNAME', + 'Symfony\Component\Security\Http\SecurityRequestAttributes', + 'LAST_USERNAME' + ), + new RenameClassAndConstFetch( + 'Symfony\Component\Security\Core\Security', + 'MAX_USERNAME_LENGTH', + 'Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge', + 'MAX_USERNAME_LENGTH' + ), + ]); +}; diff --git a/config/sets/symfony/symfony6/symfony62/symfony62-security-http.php b/config/sets/symfony/symfony6/symfony62/symfony62-security-http.php new file mode 100644 index 00000000..95ea65ca --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62/symfony62-security-http.php @@ -0,0 +1,19 @@ +rule(SecurityAttributeToIsGrantedAttributeRector::class); + // https://symfony.com/blog/new-in-symfony-6-2-built-in-cache-security-template-and-doctrine-attributes + $rectorConfig->ruleWithConfiguration( + RenameClassRector::class, + [ + // @see https://github.com/symfony/symfony/pull/46907 + 'Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted' => 'Symfony\Component\Security\Http\Attribute\IsGranted', + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony62/symfony62-translation.php b/config/sets/symfony/symfony6/symfony62/symfony62-translation.php new file mode 100644 index 00000000..6010a7a7 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62/symfony62-translation.php @@ -0,0 +1,17 @@ +ruleWithConfiguration( + RenameClassRector::class, + [ + // @see https://github.com/symfony/symfony/pull/46161 + 'Symfony\Component\Translation\Extractor\PhpAstExtractor' => 'Symfony\Component\Translation\Extractor\PhpAstExtractor', + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony62/symfony62-twig-bridge.php b/config/sets/symfony/symfony6/symfony62/symfony62-twig-bridge.php new file mode 100644 index 00000000..a27cb35c --- /dev/null +++ b/config/sets/symfony/symfony6/symfony62/symfony62-twig-bridge.php @@ -0,0 +1,17 @@ +ruleWithConfiguration( + RenameClassRector::class, + [ + // @see https://github.com/symfony/symfony/pull/46906 + 'Sensio\Bundle\FrameworkExtraBundle\Configuration\Template' => 'Symfony\Bridge\Twig\Attribute\Template', + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony63.php b/config/sets/symfony/symfony6/symfony63.php new file mode 100644 index 00000000..c1434228 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony63.php @@ -0,0 +1,14 @@ +import(__DIR__ . '/symfony63/symfony63-dependency-injection.php'); + $rectorConfig->import(__DIR__ . '/symfony63/symfony63-http-client.php'); + $rectorConfig->import(__DIR__ . '/symfony63/symfony63-messenger.php'); + $rectorConfig->import(__DIR__ . '/symfony63/symfony63-console.php'); +}; diff --git a/config/sets/symfony/symfony6/symfony63/symfony63-console.php b/config/sets/symfony/symfony6/symfony63/symfony63-console.php new file mode 100644 index 00000000..28834c50 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony63/symfony63-console.php @@ -0,0 +1,13 @@ +rules([ + // @see https://github.com/symfony/symfony/commit/1650e3861b5fcd931e5d3eb1dd84bad764020d8e + SignalableCommandInterfaceReturnTypeRector::class, + ]); +}; diff --git a/config/sets/symfony/symfony6/symfony63/symfony63-dependency-injection.php b/config/sets/symfony/symfony6/symfony63/symfony63-dependency-injection.php new file mode 100644 index 00000000..8909aaf2 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony63/symfony63-dependency-injection.php @@ -0,0 +1,22 @@ +rules([ + // @see https://symfony.com/blog/new-in-symfony-6-3-dependency-injection-improvements#new-options-for-autowire-attribute + ParamAndEnvAttributeRector::class, + ]); + + $rectorConfig->ruleWithConfiguration( + RenameClassRector::class, + [ + // @see https://github.com/symfony/symfony/commit/b653adf426aedc66d16c5fc1cf71e261f20b9638 + 'Symfony\Component\DependencyInjection\Attribute\MapDecorated' => 'Symfony\Component\DependencyInjection\Attribute\AutowireDecorated', + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony63/symfony63-http-client.php b/config/sets/symfony/symfony6/symfony63/symfony63-http-client.php new file mode 100644 index 00000000..ca22adea --- /dev/null +++ b/config/sets/symfony/symfony6/symfony63/symfony63-http-client.php @@ -0,0 +1,16 @@ +ruleWithConfiguration( + RenameClassRector::class, + [ + // @see https://github.com/symfony/symfony/commit/20ab567385e3812ef661dae01a1fdc5d1bde2666 + 'Http\Client\HttpClient' => 'Psr\Http\Client\ClientInterface', + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony63/symfony63-messenger.php b/config/sets/symfony/symfony6/symfony63/symfony63-messenger.php new file mode 100644 index 00000000..8486ed97 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony63/symfony63-messenger.php @@ -0,0 +1,19 @@ +ruleWithConfiguration( + RenameClassRector::class, + [ + // @see https://github.com/symfony/symfony/commit/9415b438b75204c72ff66b838307b73646393cbf + 'Symfony\Component\Messenger\EventListener\StopWorkerOnSigtermSignalListener' => 'Symfony\Component\Messenger\EventListener\StopWorkerOnSignalsListener', + // @see https://github.com/symfony/symfony/commit/a7926b2d83f35fe53c41a28d8055490cc1955928 + 'Symfony\Component\Messenger\Transport\InMemoryTransport' => 'Symfony\Component\Messenger\Transport\InMemory\InMemoryTransport', + 'Symfony\Component\Messenger\Transport\InMemoryTransportFactory' => 'Symfony\Component\Messenger\Transport\InMemory\InMemoryTransportFactory', + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony64.php b/config/sets/symfony/symfony6/symfony64.php new file mode 100644 index 00000000..aa5355be --- /dev/null +++ b/config/sets/symfony/symfony6/symfony64.php @@ -0,0 +1,13 @@ +import(__DIR__ . '/symfony64/symfony64-routing.php'); + $rectorConfig->import(__DIR__ . '/symfony64/symfony64-form.php'); + $rectorConfig->import(__DIR__ . '/symfony64/symfony64-http-foundation.php'); + $rectorConfig->import(__DIR__ . '/symfony64/symfony64-error-handler.php'); +}; diff --git a/config/sets/symfony/symfony6/symfony64/symfony64-error-handler.php b/config/sets/symfony/symfony6/symfony64/symfony64-error-handler.php new file mode 100644 index 00000000..55337a94 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony64/symfony64-error-handler.php @@ -0,0 +1,16 @@ +ruleWithConfiguration( + RenameClassRector::class, + [ + 'Symfony\Component\HttpKernel\Debug\FileLinkFormatter' => 'Symfony\Component\ErrorHandler\ErrorRenderer\FileLinkFormatter', + ], + ); +}; diff --git a/config/sets/symfony/symfony64.php b/config/sets/symfony/symfony6/symfony64/symfony64-form.php similarity index 51% rename from config/sets/symfony/symfony64.php rename to config/sets/symfony/symfony6/symfony64/symfony64-form.php index 5d7a2cab..62a1c530 100644 --- a/config/sets/symfony/symfony64.php +++ b/config/sets/symfony/symfony6/symfony64/symfony64-form.php @@ -4,29 +4,11 @@ use PHPStan\Type\MixedType; use Rector\Config\RectorConfig; -use Rector\Renaming\Rector\Class_\RenameAttributeRector; -use Rector\Renaming\Rector\Name\RenameClassRector; -use Rector\Renaming\ValueObject\RenameAttribute; use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationRector; use Rector\TypeDeclaration\ValueObject\AddReturnTypeDeclaration; // @see https://github.com/symfony/symfony/blob/6.4/UPGRADE-6.4.md return static function (RectorConfig $rectorConfig): void { - $rectorConfig->ruleWithConfiguration( - RenameClassRector::class, - [ - 'Symfony\Component\HttpKernel\UriSigner' => 'Symfony\Component\HttpFoundation\UriSigner', - 'Symfony\Component\HttpKernel\Debug\FileLinkFormatter' => 'Symfony\Component\ErrorHandler\ErrorRenderer\FileLinkFormatter', - ], - ); - - $rectorConfig->ruleWithConfiguration(RenameAttributeRector::class, [ - new RenameAttribute( - 'Symfony\Component\Routing\Annotation\Route', - 'Symfony\Component\Routing\Attribute\Route' - ), - ]); - $rectorConfig->ruleWithConfiguration(AddReturnTypeDeclarationRector::class, [ new AddReturnTypeDeclaration( 'Symfony\Component\Form\DataTransformerInterface', diff --git a/config/sets/symfony/symfony6/symfony64/symfony64-http-foundation.php b/config/sets/symfony/symfony6/symfony64/symfony64-http-foundation.php new file mode 100644 index 00000000..4c6b4490 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony64/symfony64-http-foundation.php @@ -0,0 +1,16 @@ +ruleWithConfiguration( + RenameClassRector::class, + [ + 'Symfony\Component\HttpKernel\UriSigner' => 'Symfony\Component\HttpFoundation\UriSigner', + ], + ); +}; diff --git a/config/sets/symfony/symfony6/symfony64/symfony64-routing.php b/config/sets/symfony/symfony6/symfony64/symfony64-routing.php new file mode 100644 index 00000000..370cf016 --- /dev/null +++ b/config/sets/symfony/symfony6/symfony64/symfony64-routing.php @@ -0,0 +1,16 @@ +ruleWithConfiguration(RenameAttributeRector::class, [ + new RenameAttribute( + 'Symfony\Component\Routing\Annotation\Route', + 'Symfony\Component\Routing\Attribute\Route' + ), + ]); +}; diff --git a/config/sets/symfony/symfony60.php b/config/sets/symfony/symfony60.php deleted file mode 100644 index 49d9c810..00000000 --- a/config/sets/symfony/symfony60.php +++ /dev/null @@ -1,68 +0,0 @@ -sets([SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES]); - - $rectorConfig->import(__DIR__ . '/symfony6/symfony-return-types.php'); - $rectorConfig->ruleWithConfiguration(ReplaceServiceArgumentRector::class, [ - new ReplaceServiceArgument('Psr\Container\ContainerInterface', new String_('service_container')), - new ReplaceServiceArgument( - 'Symfony\Component\DependencyInjection\ContainerInterface', - new String_('service_container') - ), - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - // @see https://github.com/symfony/symfony/pull/39484 - 'Symfony\Contracts\HttpClient\HttpClientInterface\RemoteJsonManifestVersionStrategy' => 'Symfony\Component\Asset\VersionStrategy\JsonManifestVersionStrategy', - ]); - - $rectorConfig->ruleWithConfiguration(AddParamTypeDeclarationRector::class, [ - new AddParamTypeDeclaration('Symfony\Component\Config\Loader\LoaderInterface', 'load', 0, new MixedType(true)), - new AddParamTypeDeclaration( - 'Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait', - 'configureRoutes', - 0, - new ObjectType('Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator'), - ), - ]); - - $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ - // @see https://github.com/symfony/symfony/pull/40403 - new MethodCallRename( - 'Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface', - 'loadUserByUsername', - 'loadUserByIdentifier' - ), - new MethodCallRename( - 'Symfony\Component\Security\Core\User\UserProviderInterface', - 'loadUserByUsername', - 'loadUserByIdentifier', - ), - // @see https://github.com/rectorphp/rector-symfony/issues/112 - new MethodCallRename( - 'Symfony\Component\Security\Core\User\UserInterface', - 'getUsername', - 'getUserIdentifier', - ), - ]); - $rectorConfig->rule(GetHelperControllerToServiceRector::class); -}; diff --git a/config/sets/symfony/symfony61.php b/config/sets/symfony/symfony61.php deleted file mode 100644 index 84d4ad6b..00000000 --- a/config/sets/symfony/symfony61.php +++ /dev/null @@ -1,30 +0,0 @@ -rules([ - CommandConfigureToAttributeRector::class, - CommandPropertyToAttributeRector::class, - ErrorNamesPropertyToConstantRector::class, - MagicClosureTwigExtensionToNativeMethodsRector::class, - ]); - - $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [ - // @see https://github.com/symfony/symfony/pull/43982 - 'Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface' => 'Symfony\Component\Serializer\Normalizer\DenormalizerInterface', - 'Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface' => 'Symfony\Component\Serializer\Normalizer\NormalizerInterface', - // @see https://github.com/symfony/symfony/pull/45623 - 'Symfony\Component\Validator\Constraints\ExpressionLanguageSyntax' => 'Symfony\Component\Validator\Constraints\ExpressionSyntax', - 'Symfony\Component\Validator\Constraints\ExpressionLanguageSyntaxValidator' => 'Symfony\Component\Validator\Constraints\ExpressionSyntaxValidator', - ]); -}; diff --git a/config/sets/symfony/symfony62.php b/config/sets/symfony/symfony62.php deleted file mode 100644 index 69aa6086..00000000 --- a/config/sets/symfony/symfony62.php +++ /dev/null @@ -1,119 +0,0 @@ -rules([ - SimplifyFormRenderingRector::class, - SecurityAttributeToIsGrantedAttributeRector::class, - ParamConverterAttributeToMapEntityAttributeRector::class, - - // @see https://github.com/symfony/symfony/pull/47068, #[AsMessageHandler] attribute - MessageHandlerInterfaceToAttributeRector::class, - MessageSubscriberInterfaceToAttributeRector::class, - // @see https://github.com/symfony/symfony/pull/47363 - ArgumentValueResolverToValueResolverRector::class, - ]); - - // change to attribute before rename - // https://symfony.com/blog/new-in-symfony-6-2-built-in-cache-security-template-and-doctrine-attributes - // @see https://github.com/rectorphp/rector-symfony/issues/535#issuecomment-1783983383 - $rectorConfig->ruleWithConfiguration(AnnotationToAttributeRector::class, [ - // @see https://github.com/symfony/symfony/pull/46907 - new AnnotationToAttribute('Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted'), - // @see https://github.com/symfony/symfony/pull/46880 - new AnnotationToAttribute('Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache'), - // @see https://github.com/symfony/symfony/pull/46906 - new AnnotationToAttribute('Sensio\Bundle\FrameworkExtraBundle\Configuration\Template'), - ]); - - // https://symfony.com/blog/new-in-symfony-6-2-built-in-cache-security-template-and-doctrine-attributes - $rectorConfig->ruleWithConfiguration( - RenameClassRector::class, - [ - // @see https://github.com/symfony/symfony/pull/46907 - 'Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted' => 'Symfony\Component\Security\Http\Attribute\IsGranted', - // @see https://github.com/symfony/symfony/pull/46880 - 'Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache' => 'Symfony\Component\HttpKernel\Attribute\Cache', - // @see https://github.com/symfony/symfony/pull/46906 - 'Sensio\Bundle\FrameworkExtraBundle\Configuration\Template' => 'Symfony\Bridge\Twig\Attribute\Template', - // @see https://github.com/symfony/symfony/pull/46714 - 'Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpApiTransport' => 'Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceApiTransport', - 'Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpSmtpTransport' => 'Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceSmtpTransport', - 'Symfony\Component\Mailer\Bridge\OhMySmtp\Transport\OhMySmtpTransportFactory' => 'Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceTransportFactory', - // @see https://github.com/symfony/symfony/pull/47363 - 'Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface' => 'Symfony\Component\HttpKernel\Controller\ValueResolverInterface', - // @see https://github.com/symfony/symfony/pull/46094 - 'Symfony\Component\Security\Core\Security' => 'Symfony\Bundle\SecurityBundle\Security', - // @see https://github.com/symfony/symfony/pull/46161 - 'Symfony\Component\Translation\Extractor\PhpAstExtractor' => 'Symfony\Component\Translation\Extractor\PhpAstExtractor', - // @see https://github.com/symfony/symfony/pull/47595 - 'Symfony\Component\HttpFoundation\ExpressionRequestMatcher' => 'Symfony\Component\HttpFoundation\RequestMatcher\ExpressionRequestMatcher', - 'Symfony\Component\HttpFoundation\RequestMatcher' => 'Symfony\Component\HttpFoundation\ChainRequestMatcher', - ], - ); - - $rectorConfig->ruleWithConfiguration( - RenameMethodRector::class, - [ - // @see https://github.com/symfony/symfony/pull/46854 - new MethodCallRename( - 'Symfony\Bundle\FrameworkBundle\Controller\AbstractController', - 'renderForm', - 'render' - ), - // @see https://github.com/symfony/symfony/pull/45034 - new MethodCallRename( - 'Symfony\Component\HttpFoundation\Request', - 'getContentType', - 'getContentTypeFormat' - ), - // @see https://github.com/symfony/symfony/pull/47711 - new MethodCallRename('Symfony\Component\Mime\Email', 'attachPart', 'addPart'), - ], - ); - - // @see https://github.com/symfony/symfony/pull/46094 - // @see https://github.com/symfony/symfony/pull/48554 - $rectorConfig->ruleWithConfiguration(RenameClassConstFetchRector::class, [ - new RenameClassAndConstFetch( - 'Symfony\Component\Security\Core\Security', - 'ACCESS_DENIED_ERROR', - 'Symfony\Component\Security\Http\SecurityRequestAttributes', - 'ACCESS_DENIED_ERROR' - ), - new RenameClassAndConstFetch( - 'Symfony\Component\Security\Core\Security', - 'AUTHENTICATION_ERROR', - 'Symfony\Component\Security\Http\SecurityRequestAttributes', - 'AUTHENTICATION_ERROR' - ), - new RenameClassAndConstFetch( - 'Symfony\Component\Security\Core\Security', - 'LAST_USERNAME', - 'Symfony\Component\Security\Http\SecurityRequestAttributes', - 'LAST_USERNAME' - ), - new RenameClassAndConstFetch( - 'Symfony\Component\Security\Core\Security', - 'MAX_USERNAME_LENGTH', - 'Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge', - 'MAX_USERNAME_LENGTH' - ), - ]); -}; diff --git a/config/sets/symfony/symfony63.php b/config/sets/symfony/symfony63.php deleted file mode 100644 index 5c33feea..00000000 --- a/config/sets/symfony/symfony63.php +++ /dev/null @@ -1,34 +0,0 @@ -ruleWithConfiguration( - RenameClassRector::class, - [ - // @see https://github.com/symfony/symfony/commit/b653adf426aedc66d16c5fc1cf71e261f20b9638 - 'Symfony\Component\DependencyInjection\Attribute\MapDecorated' => 'Symfony\Component\DependencyInjection\Attribute\AutowireDecorated', - // @see https://github.com/symfony/symfony/commit/20ab567385e3812ef661dae01a1fdc5d1bde2666 - '\Http\Client\HttpClient' => 'Psr\Http\Client\ClientInterface', - // @see https://github.com/symfony/symfony/commit/9415b438b75204c72ff66b838307b73646393cbf - 'Symfony\Component\Messenger\EventListener\StopWorkerOnSigtermSignalListener' => 'Symfony\Component\Messenger\EventListener\StopWorkerOnSignalsListener', - // @see https://github.com/symfony/symfony/commit/a7926b2d83f35fe53c41a28d8055490cc1955928 - 'Symfony\Component\Messenger\Transport\InMemoryTransport' => 'Symfony\Component\Messenger\Transport\InMemory\InMemoryTransport', - 'Symfony\Component\Messenger\Transport\InMemoryTransportFactory' => 'Symfony\Component\Messenger\Transport\InMemory\InMemoryTransportFactory', - ], - ); - - $rectorConfig->rules([ - // @see https://github.com/symfony/symfony/commit/1650e3861b5fcd931e5d3eb1dd84bad764020d8e - SignalableCommandInterfaceReturnTypeRector::class, - // @see https://symfony.com/blog/new-in-symfony-6-3-dependency-injection-improvements#new-options-for-autowire-attribute - ParamAndEnvAttributeRector::class, - ]); -}; diff --git a/config/sets/symfony/symfony73.php b/config/sets/symfony/symfony73.php new file mode 100644 index 00000000..2c2ae0ad --- /dev/null +++ b/config/sets/symfony/symfony73.php @@ -0,0 +1,12 @@ +withRules([CommandHelpToAttributeRector::class, InvokableCommandInputAttributeRector::class]); diff --git a/phpstan.neon b/phpstan.neon index 1c88c994..39fa6b84 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,8 +1,10 @@ +rules: + - Symplify\PHPStanRules\Rules\StringFileAbsolutePathExistsRule + parameters: level: 8 reportUnmatchedIgnoredErrors: false - treatPhpDocTypesAsCertain: false paths: @@ -12,18 +14,17 @@ parameters: - rules - rules-tests -# to be enabled later once rector upgraded to use phpstan v2 -# # https://github.com/rectorphp/type-perfect/ -# type_perfect: -# no_mixed: true -# null_over_false: true -# narrow_param: true -# narrow_return: true + # https://github.com/rectorphp/type-perfect/ + type_perfect: + no_mixed: true + null_over_false: true + narrow_param: true + narrow_return: true -# unused_public: -# constants: true -# methods: true -# properties: true + unused_public: + constants: true + methods: true + properties: true scanDirectories: - stubs @@ -54,16 +55,12 @@ parameters: - '#Doing instanceof PHPStan\\Type\\.+ is error\-prone and deprecated#' # phpstan instanceof - - - identifier: phpstanApi.instanceofAssumption - - - - identifier: phpstanApi.varTagAssumption + - identifier: argument.type + - identifier: assign.propertyType - - - identifier: argument.type + - '#::provideMinPhpVersion\(\) never returns \d+ so it can be removed from the return type#' + # node finder - - identifier: assign.propertyType - - - '#::provideMinPhpVersion\(\) never returns \d+ so it can be removed from the return type#' + identifier: return.type + path: rules/Symfony73/NodeAnalyzer/CommandArgumentsAndOptionsResolver.php diff --git a/rector.php b/rector.php index f11081f4..3659749f 100644 --- a/rector.php +++ b/rector.php @@ -54,4 +54,4 @@ naming: true, rectorPreset: true ) - ->withImportNames(); + ->withImportNames(removeUnusedImports: true); diff --git a/rules-tests/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/Fixture/controller_with_security_attribute.php.inc b/rules-tests/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/Fixture/controller_with_security_attribute.php.inc new file mode 100644 index 00000000..ae5d8251 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/Fixture/controller_with_security_attribute.php.inc @@ -0,0 +1,31 @@ + +----- + diff --git a/rules-tests/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/Fixture/skip_multiples.php.inc b/rules-tests/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/Fixture/skip_multiples.php.inc new file mode 100644 index 00000000..4a9f01cb --- /dev/null +++ b/rules-tests/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/Fixture/skip_multiples.php.inc @@ -0,0 +1,13 @@ + +----- + diff --git a/rules-tests/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/SingleConditionSecurityAttributeToIsGrantedRectorTest.php b/rules-tests/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/SingleConditionSecurityAttributeToIsGrantedRectorTest.php new file mode 100644 index 00000000..1e3a6f3a --- /dev/null +++ b/rules-tests/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/SingleConditionSecurityAttributeToIsGrantedRectorTest.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/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/config/configured_rule.php b/rules-tests/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/config/configured_rule.php new file mode 100644 index 00000000..c6217805 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(SingleConditionSecurityAttributeToIsGrantedRector::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 new file mode 100644 index 00000000..ce8e5b20 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/Fixture/fixture.php.inc @@ -0,0 +1,43 @@ +getRequestType() === HttpKernel::MASTER_REQUEST; + } + + public function second(Request $request) + { + return $request->getRequestType() === HttpKernel::MAIN_REQUEST; + } +} + +?> +----- +isMainRequest(); + } + + public function second(Request $request) + { + return $request->isMainRequest(); + } +} + +?> diff --git a/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/Fixture/skip_different_type.php.inc b/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/Fixture/skip_different_type.php.inc new file mode 100644 index 00000000..30f007e8 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/Fixture/skip_different_type.php.inc @@ -0,0 +1,13 @@ +getRequestType() === HttpKernel::MASTER_REQUEST; + } +} diff --git a/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/RequestIsMainRectorTest.php b/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/RequestIsMainRectorTest.php new file mode 100644 index 00000000..5bfe32e5 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/RequestIsMainRectorTest.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/BinaryOp/RequestIsMainRector/config/configured_rule.php b/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/config/configured_rule.php new file mode 100644 index 00000000..bdd6c9fb --- /dev/null +++ b/rules-tests/CodeQuality/Rector/BinaryOp/RequestIsMainRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(RequestIsMainRector::class); +}; diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/attribute_routing_class.php.inc b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/attribute_routing_class.php.inc new file mode 100644 index 00000000..767a0e81 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/attribute_routing_class.php.inc @@ -0,0 +1,34 @@ + +----- + diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/attribute_routing_class_with_other_annotation.php.inc b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/attribute_routing_class_with_other_annotation.php.inc new file mode 100644 index 00000000..110bd414 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/attribute_routing_class_with_other_annotation.php.inc @@ -0,0 +1,40 @@ + +----- + diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/explicit_silent_mix.php.inc b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/explicit_silent_mix.php.inc new file mode 100644 index 00000000..1d110132 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/explicit_silent_mix.php.inc @@ -0,0 +1,40 @@ + +----- + diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/inversed_explicit_silent_mix.php.inc b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/inversed_explicit_silent_mix.php.inc new file mode 100644 index 00000000..e2ac7f1b --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/inversed_explicit_silent_mix.php.inc @@ -0,0 +1,40 @@ + +----- + diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/skip_no_controller.php.inc b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/skip_no_controller.php.inc new file mode 100644 index 00000000..2ce30425 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/skip_no_controller.php.inc @@ -0,0 +1,18 @@ + +----- + diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/with_existing_name.php.inc b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/with_existing_name.php.inc new file mode 100644 index 00000000..040bd10e --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/with_existing_name.php.inc @@ -0,0 +1,40 @@ + +----- + diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/with_existing_name2.php.inc b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/with_existing_name2.php.inc new file mode 100644 index 00000000..1191d193 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/Fixture/with_existing_name2.php.inc @@ -0,0 +1,34 @@ + +----- + diff --git a/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/InlineClassRoutePrefixRectorTest.php b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/InlineClassRoutePrefixRectorTest.php new file mode 100644 index 00000000..ee362781 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/InlineClassRoutePrefixRectorTest.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/Class_/InlineClassRoutePrefixRector/config/configured_rule.php b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/config/configured_rule.php new file mode 100644 index 00000000..5044168a --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(InlineClassRoutePrefixRector::class); +}; diff --git a/rules-tests/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector/Fixture/skip_single_or.php.inc b/rules-tests/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector/Fixture/skip_single_or.php.inc new file mode 100644 index 00000000..a51b83fb --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector/Fixture/skip_single_or.php.inc @@ -0,0 +1,11 @@ + +----- + diff --git a/rules-tests/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector/Fixture/with_ampersand_attributes.php.inc b/rules-tests/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector/Fixture/with_ampersand_attributes.php.inc new file mode 100644 index 00000000..8ef6db8c --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector/Fixture/with_ampersand_attributes.php.inc @@ -0,0 +1,26 @@ + +----- + diff --git a/rules-tests/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector/SplitAndSecurityAttributeToIsGrantedRectorTest.php b/rules-tests/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector/SplitAndSecurityAttributeToIsGrantedRectorTest.php new file mode 100644 index 00000000..244e8f5c --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector/SplitAndSecurityAttributeToIsGrantedRectorTest.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/Class_/SplitAndSecurityAttributeToIsGrantedRector/config/configured_rule.php b/rules-tests/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector/config/configured_rule.php new file mode 100644 index 00000000..99695fc3 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(SplitAndSecurityAttributeToIsGrantedRector::class); +}; diff --git a/rules-tests/CodeQuality/Rector/Closure/StringExtensionToConfigBuilderRector/Fixture/skip_no_extension.php.inc b/rules-tests/CodeQuality/Rector/Closure/StringExtensionToConfigBuilderRector/Fixture/skip_no_extension.php.inc new file mode 100644 index 00000000..bd0f0e5b --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Closure/StringExtensionToConfigBuilderRector/Fixture/skip_no_extension.php.inc @@ -0,0 +1,31 @@ +services(); + + $services->alias(RequestFactoryInterface::class, 'http_discovery.psr17_factory'); + + $services->alias(ResponseFactoryInterface::class, 'http_discovery.psr17_factory'); + + $services->alias(ServerRequestFactoryInterface::class, 'http_discovery.psr17_factory'); + + $services->alias(StreamFactoryInterface::class, 'http_discovery.psr17_factory'); + + $services->alias(UploadedFileFactoryInterface::class, 'http_discovery.psr17_factory'); + + $services->alias(UriFactoryInterface::class, 'http_discovery.psr17_factory'); + + $services->set('http_discovery.psr17_factory', Psr17Factory::class); +}; \ No newline at end of file diff --git a/rules-tests/Configs/Rector/Closure/ServiceSetStringNameToClassNameRector/Fixture/skip_excluded_tag.php.inc b/rules-tests/Configs/Rector/Closure/ServiceSetStringNameToClassNameRector/Fixture/skip_excluded_tag.php.inc new file mode 100644 index 00000000..bd958fc2 --- /dev/null +++ b/rules-tests/Configs/Rector/Closure/ServiceSetStringNameToClassNameRector/Fixture/skip_excluded_tag.php.inc @@ -0,0 +1,12 @@ +services(); + + $services->set('excluded', ExcludedService::class); +}; diff --git a/rules-tests/Configs/Rector/Closure/ServiceSetStringNameToClassNameRector/Source/ExcludedService.php b/rules-tests/Configs/Rector/Closure/ServiceSetStringNameToClassNameRector/Source/ExcludedService.php new file mode 100644 index 00000000..1446bb3e --- /dev/null +++ b/rules-tests/Configs/Rector/Closure/ServiceSetStringNameToClassNameRector/Source/ExcludedService.php @@ -0,0 +1,9 @@ + + + + diff --git a/rules-tests/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector/Fixture/command_validator.php.inc b/rules-tests/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector/Fixture/command_validator.php.inc index eee09ad6..adb8d006 100644 --- a/rules-tests/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector/Fixture/command_validator.php.inc +++ b/rules-tests/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector/Fixture/command_validator.php.inc @@ -24,6 +24,7 @@ final class CommandValidator extends ContainerAwareCommand { public function __construct(private readonly \Symfony\Component\Validator\Validator\ValidatorInterface $validator) { + parent::__construct(); } public function configure() { diff --git a/rules-tests/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector/Fixture/prefer_required_setter.php.inc b/rules-tests/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector/Fixture/prefer_required_setter.php.inc new file mode 100644 index 00000000..56b71157 --- /dev/null +++ b/rules-tests/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector/Fixture/prefer_required_setter.php.inc @@ -0,0 +1,59 @@ +eventDispatcher = $eventDispatcher; + } + + + public function configure() + { + $someType = $this->get('validator'); + } +} + +?> +----- +eventDispatcher = $eventDispatcher; + $this->validator = $validator; + } + + + public function configure() + { + $someType = $this->validator; + } +} + +?> diff --git a/rules-tests/Symfony61/Rector/Class_/CommandConfigureToAttributeRector/Fixture/call_all_option.php.inc b/rules-tests/Symfony61/Rector/Class_/CommandConfigureToAttributeRector/Fixture/call_all_option.php.inc new file mode 100644 index 00000000..8a8360c2 --- /dev/null +++ b/rules-tests/Symfony61/Rector/Class_/CommandConfigureToAttributeRector/Fixture/call_all_option.php.inc @@ -0,0 +1,43 @@ +setName('sunshine') + ->setDescription('Some description') + ->setHidden(false) + ->setHelp('Some help text') + ->addArgument('argument name') + ->addOption('option', 'o', InputOption::VALUE_NONE, 'Option description') + ->setAliases(['first', 'second']); + } +} + +?> +----- +setHelp('Some help text') + ->addArgument('argument name') + ->addOption('option', 'o', InputOption::VALUE_NONE, 'Option description'); + } +} + +?> diff --git a/rules-tests/Symfony61/Rector/Class_/CommandConfigureToAttributeRector/Fixture/other-calls-middle.php.inc b/rules-tests/Symfony61/Rector/Class_/CommandConfigureToAttributeRector/Fixture/other-calls-middle.php.inc deleted file mode 100644 index f5bad67f..00000000 --- a/rules-tests/Symfony61/Rector/Class_/CommandConfigureToAttributeRector/Fixture/other-calls-middle.php.inc +++ /dev/null @@ -1,31 +0,0 @@ -setName('sunshine') - ->addArgument('argument name') - ->setAliases(['first', 'second']); - } -} - -?> ------ -addArgument('argument name'); - } -} - -?> diff --git a/rules-tests/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector/Fixture/class_that_extends_abstact_class_that_implements_handler.php.inc b/rules-tests/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector/Fixture/class_that_extends_abstact_class_that_implements_handler.php.inc new file mode 100644 index 00000000..c4413e61 --- /dev/null +++ b/rules-tests/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector/Fixture/class_that_extends_abstact_class_that_implements_handler.php.inc @@ -0,0 +1,24 @@ + +----- + diff --git a/rules-tests/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector/Fixture/only_remove_interface_from_abstract_class.php.inc b/rules-tests/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector/Fixture/only_remove_interface_from_abstract_class.php.inc new file mode 100644 index 00000000..f2d70532 --- /dev/null +++ b/rules-tests/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector/Fixture/only_remove_interface_from_abstract_class.php.inc @@ -0,0 +1,23 @@ + +----- + diff --git a/rules-tests/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector/Source/AbstractClassWithHandlerInterface.php b/rules-tests/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector/Source/AbstractClassWithHandlerInterface.php new file mode 100644 index 00000000..8ac71dfe --- /dev/null +++ b/rules-tests/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector/Source/AbstractClassWithHandlerInterface.php @@ -0,0 +1,9 @@ +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/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/add_help_to_attribute_command.php.inc b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/add_help_to_attribute_command.php.inc new file mode 100644 index 00000000..f84d1421 --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/add_help_to_attribute_command.php.inc @@ -0,0 +1,36 @@ +setHelp('Some help text'); + } +} + +?> +----- + diff --git a/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/all_attribute_set_also_add_help.php.inc b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/all_attribute_set_also_add_help.php.inc new file mode 100644 index 00000000..46fce7e7 --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/all_attribute_set_also_add_help.php.inc @@ -0,0 +1,42 @@ +setHelp('Some help text') + ->addArgument('argument name') + ->addOption('option', 'o', InputOption::VALUE_NONE, 'Option description'); + } +} + +?> +----- +addArgument('argument name') + ->addOption('option', 'o', InputOption::VALUE_NONE, 'Option description'); + } +} + +?> diff --git a/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/skip_has_help_attribute_command.php.inc b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/skip_has_help_attribute_command.php.inc new file mode 100644 index 00000000..65f90158 --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/skip_has_help_attribute_command.php.inc @@ -0,0 +1,32 @@ +addArgument('argument', InputArgument::REQUIRED, 'Argument description'); + $this->addOption('option', 'o', InputOption::VALUE_NONE, 'Option description'); + } + + public function execute(InputInterface $input, OutputInterface $output): int + { + $someArgument = $input->getArgument('argument'); + $someOption = $input->getOption('option'); + + // ... + + return 1; + } +} + +?> diff --git a/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/skip_no_as_command_attribute_and_no_help_command.php.inc b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/skip_no_as_command_attribute_and_no_help_command.php.inc new file mode 100644 index 00000000..2be9b2e7 --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/Fixture/skip_no_as_command_attribute_and_no_help_command.php.inc @@ -0,0 +1,16 @@ +setName('Some command'); + } +} + +?> diff --git a/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/config/configured_rule.php b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/config/configured_rule.php new file mode 100644 index 00000000..e5cd37d4 --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/CommandHelpToAttributeRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(CommandHelpToAttributeRector::class); +}; diff --git a/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command.php.inc b/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command.php.inc new file mode 100644 index 00000000..53118a80 --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command.php.inc @@ -0,0 +1,61 @@ +addArgument('argument', InputArgument::REQUIRED, 'Argument description'); + $this->addOption('option', 'o', InputOption::VALUE_NONE, 'Option description'); + } + + public function execute(InputInterface $input, OutputInterface $output): int + { + $someArgument = $input->getArgument('argument'); + $someOption = $input->getOption('option'); + + // ... + + return 1; + } +} + +?> +----- + diff --git a/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command_with_method_chaining.php.inc b/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command_with_method_chaining.php.inc new file mode 100644 index 00000000..55725f52 --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command_with_method_chaining.php.inc @@ -0,0 +1,62 @@ +addArgument('argument', InputArgument::REQUIRED, 'Argument description') + ->addOption('option', 'o', InputOption::VALUE_NONE, 'Option description'); + } + + public function execute(InputInterface $input, OutputInterface $output): int + { + $someArgument = $input->getArgument('argument'); + $someOption = $input->getOption('option'); + + // ... + + return 1; + } +} + +?> +----- + diff --git a/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command_with_set_help.php.inc b/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command_with_set_help.php.inc new file mode 100644 index 00000000..875252d1 --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture/some_command_with_set_help.php.inc @@ -0,0 +1,67 @@ +setHelp('argument'); + $this->addArgument('argument', InputArgument::REQUIRED, 'Argument description'); + $this->addOption('option', 'o', InputOption::VALUE_NONE, 'Option description'); + } + + public function execute(InputInterface $input, OutputInterface $output): int + { + $someArgument = $input->getArgument('argument'); + $someOption = $input->getOption('option'); + + // ... + + return 1; + } +} + +?> +----- +setHelp('argument'); + } + + public function __invoke(#[\Symfony\Component\Console\Attribute\Command\Argument] + string $argument, #[\Symfony\Component\Console\Attribute\Command\Option] + $option): int + { + $someArgument = $argument; + $someOption = $option; + + // ... + + return 1; + } +} + +?> diff --git a/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/InvokableCommandInputAttributeRectorTest.php b/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/InvokableCommandInputAttributeRectorTest.php new file mode 100644 index 00000000..551b491e --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/InvokableCommandInputAttributeRectorTest.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/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/config/configured_rule.php b/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/config/configured_rule.php new file mode 100644 index 00000000..bd5997cd --- /dev/null +++ b/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(InvokableCommandInputAttributeRector::class); +}; diff --git a/rules/CodeQuality/NodeAnalyzer/AttributePresenceDetector.php b/rules/CodeQuality/NodeAnalyzer/AttributePresenceDetector.php new file mode 100644 index 00000000..69ee1eb2 --- /dev/null +++ b/rules/CodeQuality/NodeAnalyzer/AttributePresenceDetector.php @@ -0,0 +1,28 @@ +reflectionProvider->hasClass($attributeClass)) { + return false; + } + + // must be attribute, not just annotation + $securityClassReflection = $this->reflectionProvider->getClass($attributeClass); + + return $securityClassReflection->isAttributeClass(); + } +} diff --git a/rules/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector.php b/rules/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector.php new file mode 100644 index 00000000..e956e95e --- /dev/null +++ b/rules/CodeQuality/Rector/AttributeGroup/SingleConditionSecurityAttributeToIsGrantedRector.php @@ -0,0 +1,102 @@ +attributePresenceDetector->detect(SensioAttribute::SECURITY)) { + return null; + } + + foreach ($node->attrs as $attr) { + if (! $this->isName($attr->name, SensioAttribute::SECURITY)) { + continue; + } + + $firstArgValue = $attr->args[0]->value; + if (! $firstArgValue instanceof String_) { + continue; + } + + $matches = Strings::match( + $firstArgValue->value, + '#^(is_granted|has_role)\(\'(?[A-Za-z_]+)\'\)$#' + ); + if (! isset($matches['access_right'])) { + continue; + } + + $attr->name = new FullyQualified(SensioAttribute::IS_GRANTED); + $attr->args = [new Arg(new String_($matches['access_right']))]; + + return $node; + } + + return null; + } +} diff --git a/rules/CodeQuality/Rector/BinaryOp/RequestIsMainRector.php b/rules/CodeQuality/Rector/BinaryOp/RequestIsMainRector.php new file mode 100644 index 00000000..0347e0a9 --- /dev/null +++ b/rules/CodeQuality/Rector/BinaryOp/RequestIsMainRector.php @@ -0,0 +1,115 @@ +getRequestType() === HttpKernel::MASTER_REQUEST; + } +} +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\HttpKernel; + +class SomeController +{ + public function index(Request $request): bool + { + return $request->isMasterRequestType(); + } +} +CODE_SAMPLE + ), + ]); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [BinaryOp::class]; + } + + /** + * @param BinaryOp $node + */ + public function refactor(Node $node): ?Node + { + if (! $node->left instanceof MethodCall) { + return null; + } + + $methodCall = $node->left; + if (! $this->isRequestGetRequestType($methodCall)) { + return null; + } + + if (! $this->isHttpKernelMainRequestClassConstFetch($node->right)) { + return null; + } + + $requestClassReflection = $this->reflectionProvider->getClass(SymfonyClass::REQUEST); + $methodName = $requestClassReflection->hasMethod('isMainRequest') ? 'isMainRequest' : 'isMasterRequest'; + + return new MethodCall($methodCall->var, $methodName); + } + + private function isRequestGetRequestType(MethodCall $methodCall): bool + { + if (! $this->isName($methodCall->name, 'getRequestType')) { + return false; + } + + return $this->isObjectType($methodCall->var, new ObjectType(SymfonyClass::REQUEST)); + } + + private function isHttpKernelMainRequestClassConstFetch(Expr $expr): bool + { + if (! $expr instanceof ClassConstFetch) { + return false; + } + + if (! $this->isNames($expr->class, [SymfonyClass::HTTP_KERNEL_INTERFACE, SymfonyClass::HTTP_KERNEL])) { + return false; + } + + return $this->isNames($expr->name, ['MASTER_REQUEST', 'MAIN_REQUEST']); + } +} diff --git a/rules/CodeQuality/Rector/ClassMethod/ActionSuffixRemoverRector.php b/rules/CodeQuality/Rector/ClassMethod/ActionSuffixRemoverRector.php index ec85c9fe..dc652cad 100644 --- a/rules/CodeQuality/Rector/ClassMethod/ActionSuffixRemoverRector.php +++ b/rules/CodeQuality/Rector/ClassMethod/ActionSuffixRemoverRector.php @@ -72,16 +72,18 @@ public function refactor(Node $node): ?Node return null; } - $this->removeSuffix($node, 'Action'); - - return $node; + return $this->removeSuffix($node, 'Action'); } - private function removeSuffix(ClassMethod $classMethod, string $suffixToRemove): void + private function removeSuffix(ClassMethod $classMethod, string $suffixToRemove): ?ClassMethod { $name = $this->nodeNameResolver->getName($classMethod); $newName = Strings::replace($name, sprintf('#%s$#', $suffixToRemove), ''); + if ($newName === $name) { + return null; + } $classMethod->name = new Identifier($newName); + return $classMethod; } } diff --git a/rules/CodeQuality/Rector/ClassMethod/TemplateAnnotationToThisRenderRector.php b/rules/CodeQuality/Rector/ClassMethod/TemplateAnnotationToThisRenderRector.php index 77835565..64905ed9 100644 --- a/rules/CodeQuality/Rector/ClassMethod/TemplateAnnotationToThisRenderRector.php +++ b/rules/CodeQuality/Rector/ClassMethod/TemplateAnnotationToThisRenderRector.php @@ -152,7 +152,7 @@ private function decorateAbstractControllerParentClass(Class_ $class): void } // this will make $this->render() method available - $class->extends = new FullyQualified('Symfony\Bundle\FrameworkBundle\Controller\AbstractController'); + $class->extends = new FullyQualified(SymfonyClass::ABSTRACT_CONTROLLER); } private function replaceTemplateAnnotation( @@ -204,14 +204,15 @@ private function refactorClassMethod( return null; } - $this->refactorStmtsAwareNode( + $hasChangedNode = $this->refactorStmtsAwareNode( $node, $templateDoctrineAnnotationTagValueNode, $hasThisRenderOrReturnsResponse, $classMethod ); - - $hasChanged = true; + if ($hasChangedNode) { + $hasChanged = true; + } return null; }); @@ -256,10 +257,10 @@ private function refactorReturn( DoctrineAnnotationTagValueNode $templateDoctrineAnnotationTagValueNode, bool $hasThisRenderOrReturnsResponse, ClassMethod $classMethod - ): void { + ): bool { // nothing we can do if (! $return->expr instanceof Expr) { - return; + return false; } // create "$this->render('template.file.twig.html', ['key' => 'value']);" method call @@ -269,7 +270,7 @@ private function refactorReturn( $classMethod ); - $this->refactorReturnWithValue( + return $this->refactorReturnWithValue( $return, $hasThisRenderOrReturnsResponse, $thisRenderMethodCall, @@ -295,7 +296,7 @@ private function refactorReturnWithValue( MethodCall $thisRenderMethodCall, ClassMethod $classMethod, DoctrineAnnotationTagValueNode $doctrineAnnotationTagValueNode - ): void { + ): bool { /** @var Expr $lastReturnExpr */ $lastReturnExpr = $return->expr; @@ -309,7 +310,7 @@ private function refactorReturnWithValue( $return->expr = $thisRenderMethodCall; } elseif ($returnStaticType instanceof MixedType) { // nothing we can do - return; + return false; } $isArrayOrResponseType = $this->arrayUnionResponseTypeAnalyzer->isArrayUnionResponseType( @@ -319,12 +320,13 @@ private function refactorReturnWithValue( // skip as the original class method has to change first if ($isArrayOrResponseType) { - return; + return false; } // already response $this->removeDoctrineAnnotationTagValueNode($classMethod, $doctrineAnnotationTagValueNode); $this->returnTypeDeclarationUpdater->updateClassMethod($classMethod, SymfonyClass::RESPONSE); + return true; } private function removeDoctrineAnnotationTagValueNode( @@ -342,11 +344,12 @@ private function refactorStmtsAwareNode( DoctrineAnnotationTagValueNode $templateDoctrineAnnotationTagValueNode, bool $hasThisRenderOrReturnsResponse, ClassMethod $classMethod - ): void { + ): bool { if ($stmtsAware->stmts === null) { - return; + return false; } + $hasChanged = false; foreach ($stmtsAware->stmts as $stmt) { if (! $stmt instanceof Return_) { continue; @@ -354,15 +357,19 @@ private function refactorStmtsAwareNode( // just created node, skip it if ($stmt->getAttributes() === []) { - return; + return false; } - $this->refactorReturn( + $hasChangedReturn = $this->refactorReturn( $stmt, $templateDoctrineAnnotationTagValueNode, $hasThisRenderOrReturnsResponse, $classMethod ); + if ($hasChangedReturn) { + $hasChanged = true; + } } + return $hasChanged; } } diff --git a/rules/CodeQuality/Rector/Class_/EventListenerToEventSubscriberRector.php b/rules/CodeQuality/Rector/Class_/EventListenerToEventSubscriberRector.php index cae412d0..b0c9b5db 100644 --- a/rules/CodeQuality/Rector/Class_/EventListenerToEventSubscriberRector.php +++ b/rules/CodeQuality/Rector/Class_/EventListenerToEventSubscriberRector.php @@ -170,7 +170,7 @@ private function changeListenerToSubscriberWithMethods(Class_ $class, array $eve */ private function hasAsListenerAttribute(Class_ $class): bool { - if ($this->phpAttributeAnalyzer->hasPhpAttribute($class, SymfonyAttribute::EVENT_LISTENER_ATTRIBUTE)) { + if ($this->phpAttributeAnalyzer->hasPhpAttribute($class, SymfonyAttribute::AS_EVENT_LISTENER)) { return true; } @@ -179,10 +179,7 @@ private function hasAsListenerAttribute(Class_ $class): bool continue; } - if ($this->phpAttributeAnalyzer->hasPhpAttribute( - $classMethod, - SymfonyAttribute::EVENT_LISTENER_ATTRIBUTE - )) { + if ($this->phpAttributeAnalyzer->hasPhpAttribute($classMethod, SymfonyAttribute::AS_EVENT_LISTENER)) { return true; } } diff --git a/rules/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector.php b/rules/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector.php new file mode 100644 index 00000000..3b53c7ee --- /dev/null +++ b/rules/CodeQuality/Rector/Class_/InlineClassRoutePrefixRector.php @@ -0,0 +1,317 @@ +shouldSkipClass($node)) { + return null; + } + + $classRoutePath = null; + $classRouteName = null; + + // 1. detect attribute + $routeAttributeOrAnnotation = $this->attrinationFinder->getByMany( + $node, + [SymfonyAttribute::ROUTE, SymfonyAnnotation::ROUTE] + ); + + if ($routeAttributeOrAnnotation instanceof DoctrineAnnotationTagValueNode) { + $classRoutePath = $this->resolveRoutePath($routeAttributeOrAnnotation); + $classRouteName = $this->resolveRouteName($routeAttributeOrAnnotation); + } elseif ($routeAttributeOrAnnotation instanceof Attribute) { + $classRoutePath = $this->resolveRoutePathFromAttribute($routeAttributeOrAnnotation); + $classRouteName = $this->resolveRouteNameFromAttribute($routeAttributeOrAnnotation); + } + + if ($classRoutePath === null) { + return null; + } + + // 2. inline prefix to all method routes + $hasChanged = false; + + foreach ($node->getMethods() as $classMethod) { + if (! $classMethod->isPublic() || $classMethod->isMagic()) { + continue; + } + + // can be route method + $methodRouteAnnotationOrAttributes = $this->attrinationFinder->findManyByMany( + $classMethod, + [SymfonyAttribute::ROUTE, SymfonyAnnotation::ROUTE] + ); + + foreach ($methodRouteAnnotationOrAttributes as $methodRouteAnnotationOrAttribute) { + if ($methodRouteAnnotationOrAttribute instanceof DoctrineAnnotationTagValueNode) { + $routePathArrayItemNode = $methodRouteAnnotationOrAttribute->getSilentValue() ?? $methodRouteAnnotationOrAttribute->getValue( + self::PATH + ); + if (! $routePathArrayItemNode instanceof ArrayItemNode) { + continue; + } + + if (! $routePathArrayItemNode->value instanceof StringNode) { + continue; + } + + $methodPrefix = $routePathArrayItemNode->value; + $newMethodPath = $classRoutePath . $methodPrefix->value; + + $routePathArrayItemNode->value = new StringNode($newMethodPath); + + foreach ($methodRouteAnnotationOrAttribute->values as $value) { + if ($value->key === 'name' && $value->value instanceof StringNode && is_string( + $classRouteName + )) { + $value->value->value = $classRouteName . $value->value->value; + } + } + + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($classMethod); + + $hasChanged = true; + } elseif ($methodRouteAnnotationOrAttribute instanceof Attribute) { + foreach ($methodRouteAnnotationOrAttribute->args as $methodRouteArg) { + if ($methodRouteArg->name === null || $methodRouteArg->name->toString() === self::PATH) { + if (! $methodRouteArg->value instanceof String_) { + continue; + } + + $methodRouteString = $methodRouteArg->value; + $methodRouteArg->value = new String_(sprintf( + '%s%s', + $classRoutePath, + $methodRouteString->value + )); + + $hasChanged = true; + + continue; + } + + if ($methodRouteArg->name->toString() === 'name') { + if (! $methodRouteArg->value instanceof String_) { + continue; + } + + $methodRouteString = $methodRouteArg->value; + $methodRouteArg->value = new String_(sprintf( + '%s%s', + $classRouteName, + $methodRouteString->value + )); + + $hasChanged = true; + } + } + } + } + } + + if (! $hasChanged) { + return null; + } + + if ($routeAttributeOrAnnotation instanceof DoctrineAnnotationTagValueNode) { + $classPhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); + + $this->phpDocTagRemover->removeTagValueFromNode($classPhpDocInfo, $routeAttributeOrAnnotation); + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); + } else { + foreach ($node->attrGroups as $attrGroupKey => $attrGroup) { + foreach ($attrGroup->attrs as $attribute) { + if ($attribute === $routeAttributeOrAnnotation) { + unset($node->attrGroups[$attrGroupKey]); + } + } + } + } + + return $node; + } + + private function shouldSkipClass(Class_ $class): bool + { + if (! $this->controllerAnalyzer->isController($class)) { + return true; + } + + foreach ($class->getMethods() as $classMethod) { + if (! $classMethod->isPublic() || $classMethod->isMagic()) { + continue; + } + + // special cases for FOS rest that should be skipped + if ($this->attrinationFinder->hasByMany($class, self::FOS_REST_ANNOTATIONS)) { + return true; + } + } + + return false; + } + + private function resolveRoutePath(DoctrineAnnotationTagValueNode $doctrineAnnotationTagValueNode): ?string + { + $classRoutePathNode = $doctrineAnnotationTagValueNode->getSilentValue() ?: $doctrineAnnotationTagValueNode->getValue( + self::PATH + ); + + if (! $classRoutePathNode instanceof ArrayItemNode) { + return null; + } + + if (! $classRoutePathNode->value instanceof StringNode) { + return null; + } + + return $classRoutePathNode->value->value; + } + + private function resolveRouteName(DoctrineAnnotationTagValueNode $doctrineAnnotationTagValueNode): ?string + { + $classRouteNameNode = $doctrineAnnotationTagValueNode->getValue('name'); + + if (! $classRouteNameNode instanceof ArrayItemNode) { + return null; + } + + if (! $classRouteNameNode->value instanceof StringNode) { + return null; + } + + return $classRouteNameNode->value->value; + } + + private function resolveRoutePathFromAttribute(Attribute $attribute): ?string + { + foreach ($attribute->args as $arg) { + // silent or "path" + if ($arg->name === null || $arg->name->toString() === self::PATH) { + $routeExpr = $arg->value; + if ($routeExpr instanceof String_) { + return $routeExpr->value; + } + } + } + + return null; + } + + private function resolveRouteNameFromAttribute(Attribute $attribute): ?string + { + foreach ($attribute->args as $arg) { + if ($arg->name === null) { + continue; + } + + if ($arg->name->toString() === 'name') { + $routeExpr = $arg->value; + if ($routeExpr instanceof String_) { + return $routeExpr->value; + } + } + } + + return null; + } +} diff --git a/rules/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector.php b/rules/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector.php new file mode 100644 index 00000000..ffb81bc0 --- /dev/null +++ b/rules/CodeQuality/Rector/Class_/SplitAndSecurityAttributeToIsGrantedRector.php @@ -0,0 +1,124 @@ +attrGroups as $key => $attrGroup) { + foreach ($attrGroup->attrs as $attr) { + if (! $this->isName($attr->name, Security::class)) { + continue; + } + + $firstArgValue = $attr->args[0]->value; + if (! $firstArgValue instanceof String_) { + continue; + } + + $content = $firstArgValue->value; + + // unable to resolve with pure attributes + if (str_contains($content, ' or ')) { + continue; + } + + // we look for "and"s + if (! str_contains($content, ' and ') && ! str_contains($content, ' && ')) { + continue; + } + + // split by && and "and" + $andItems = str_contains($content, ' && ') ? explode(' && ', $content) : explode(' and ', $content); + + $accessRights = []; + + foreach ($andItems as $andItem) { + $matches = Strings::match($andItem, '#^(is_granted|has_role)\(\'(?[A-Za-z_]+)\'\)$#'); + if (! isset($matches['access_right'])) { + // all or nothing + return null; + } + + $accessRights[] = $matches['access_right']; + } + + unset($node->attrGroups[$key]); + + $hasChanged = true; + + foreach ($accessRights as $accessRight) { + $attributeGroup = new AttributeGroup([ + new Attribute(new FullyQualified(IsGranted::class), [new Arg(new String_($accessRight))]), + ]); + + $node->attrGroups[] = $attributeGroup; + } + } + } + + if ($hasChanged) { + return $node; + } + + return null; + } +} diff --git a/rules/CodeQuality/Rector/Closure/StringExtensionToConfigBuilderRector.php b/rules/CodeQuality/Rector/Closure/StringExtensionToConfigBuilderRector.php index 58b905d3..b3b8bd3f 100644 --- a/rules/CodeQuality/Rector/Closure/StringExtensionToConfigBuilderRector.php +++ b/rules/CodeQuality/Rector/Closure/StringExtensionToConfigBuilderRector.php @@ -9,7 +9,6 @@ use PhpParser\Node\Expr\Closure; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\Variable; -use PhpParser\Node\Param; use PhpParser\Node\Stmt\Expression; use Rector\Exception\NotImplementedYetException; use Rector\Naming\Naming\PropertyNaming; @@ -51,6 +50,8 @@ final class StringExtensionToConfigBuilderRector extends AbstractRector 'maker' => 'Symfony\Config\MakerConfig', 'nelmio_cors' => 'Symfony\Config\NelmioCorsConfig', 'api_platform' => 'Symfony\Config\ApiPlatformConfig', + // @see https://github.com/thephpleague/flysystem-bundle/blob/3.x/src/DependencyInjection/Configuration.php + 'flysystem' => 'Symfony\Config\FlysystemConfig', ]; public function __construct( diff --git a/rules/Configs/NodeVisitor/CollectServiceArgumentsNodeVisitor.php b/rules/Configs/NodeVisitor/CollectServiceArgumentsNodeVisitor.php index 6e8b5936..199d0048 100644 --- a/rules/Configs/NodeVisitor/CollectServiceArgumentsNodeVisitor.php +++ b/rules/Configs/NodeVisitor/CollectServiceArgumentsNodeVisitor.php @@ -6,7 +6,6 @@ use Nette\Utils\Strings; use PhpParser\Node; -use PhpParser\Node\Arg; use PhpParser\Node\ArrayItem; use PhpParser\Node\Expr; use PhpParser\Node\Expr\Array_; diff --git a/rules/DependencyInjection/Rector/Class_/CommandGetByTypeToConstructorInjectionRector.php b/rules/DependencyInjection/Rector/Class_/CommandGetByTypeToConstructorInjectionRector.php index ba303b87..86a5ba6a 100644 --- a/rules/DependencyInjection/Rector/Class_/CommandGetByTypeToConstructorInjectionRector.php +++ b/rules/DependencyInjection/Rector/Class_/CommandGetByTypeToConstructorInjectionRector.php @@ -134,6 +134,6 @@ private function shouldSkipClass(Class_ $class): bool return true; } - return ! $classReflection->isSubclassOf(SymfonyClass::CONTAINER_AWARE_COMMAND); + return ! $classReflection->is(SymfonyClass::CONTAINER_AWARE_COMMAND); } } diff --git a/rules/DependencyInjection/Rector/Class_/ControllerGetByTypeToConstructorInjectionRector.php b/rules/DependencyInjection/Rector/Class_/ControllerGetByTypeToConstructorInjectionRector.php index 3147ee9f..b1aedc02 100644 --- a/rules/DependencyInjection/Rector/Class_/ControllerGetByTypeToConstructorInjectionRector.php +++ b/rules/DependencyInjection/Rector/Class_/ControllerGetByTypeToConstructorInjectionRector.php @@ -130,6 +130,6 @@ private function shouldSkipClass(Class_ $class): bool return true; } - return ! $classReflection->isSubclassOf(SymfonyClass::CONTROLLER); + return ! $classReflection->is(SymfonyClass::CONTROLLER); } } diff --git a/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php b/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php index bb9236cf..0a2ced0a 100644 --- a/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php +++ b/rules/DependencyInjection/Rector/Class_/GetBySymfonyStringToConstructorInjectionRector.php @@ -31,7 +31,23 @@ final class GetBySymfonyStringToConstructorInjectionRector extends AbstractRecto 'validator' => SymfonyClass::VALIDATOR_INTERFACE, 'event_dispatcher' => SymfonyClass::EVENT_DISPATCHER_INTERFACE, 'logger' => SymfonyClass::LOGGER_INTERFACE, - 'jms_serializer' => SymfonyClass::SERIALIZER_INTERFACE, + 'jms_serializer' => SymfonyClass::JMS_SERIALIZER_INTERFACE, + 'translator' => SymfonyClass::TRANSLATOR_INTERFACE, + 'session' => SymfonyClass::SESSION_INTERFACRE, + 'security.token_storage' => SymfonyClass::TOKEN_STORAGE_INTERFACE, + 'router' => 'Symfony\Component\Routing\RouterInterface', + 'request_stack' => 'Symfony\Component\HttpFoundation\RequestStack', + 'http_kernel' => 'Symfony\Component\HttpKernel\HttpKernelInterface', + 'serializer' => 'Symfony\Component\Serializer\SerializerInterface', + 'security.authorization_checker' => 'Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface', + 'templating' => 'Symfony\Component\Templating\EngineInterface', + 'twig' => 'Twig\Environment', + 'doctrine' => 'Doctrine\Persistence\ManagerRegistry', + 'form.factory' => 'Symfony\Component\Form\FormFactoryInterface', + 'security.csrf.token_manager' => 'Symfony\Component\Security\Core\Authorization\CsrfTokenManagerInterface', + 'parameter_bag' => 'Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface', + 'message_bus' => 'Symfony\Component\Messenger\MessageBusInterface', + 'messenger.default_bus' => 'Symfony\Component\Messenger\MessageBusInterface', ]; public function __construct( @@ -139,10 +155,10 @@ private function shouldSkipClass(Class_ $class): bool return true; } - if ($classReflection->isSubclassOf(SymfonyClass::CONTAINER_AWARE_COMMAND)) { + if ($classReflection->is(SymfonyClass::CONTAINER_AWARE_COMMAND)) { return false; } - return ! $classReflection->isSubclassOf(SymfonyClass::CONTROLLER); + return ! $classReflection->is(SymfonyClass::CONTROLLER); } } diff --git a/rules/DependencyInjection/Rector/Trait_/TraitGetByTypeToInjectRector.php b/rules/DependencyInjection/Rector/Trait_/TraitGetByTypeToInjectRector.php index 3c4921c8..febf5e27 100644 --- a/rules/DependencyInjection/Rector/Trait_/TraitGetByTypeToInjectRector.php +++ b/rules/DependencyInjection/Rector/Trait_/TraitGetByTypeToInjectRector.php @@ -8,7 +8,6 @@ use PhpParser\Node; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Name\FullyQualified; -use PhpParser\Node\Param; use PhpParser\Node\PropertyItem; use PhpParser\Node\Stmt\Property; use PhpParser\Node\Stmt\Trait_; diff --git a/rules/DowngradeSymfony70/Rector/Class_/DowngradeSymfonyCommandAttributeRector.php b/rules/DowngradeSymfony70/Rector/Class_/DowngradeSymfonyCommandAttributeRector.php index 3552074d..d0753f95 100644 --- a/rules/DowngradeSymfony70/Rector/Class_/DowngradeSymfonyCommandAttributeRector.php +++ b/rules/DowngradeSymfony70/Rector/Class_/DowngradeSymfonyCommandAttributeRector.php @@ -77,7 +77,7 @@ public function refactor(Node $node): ?Node return null; } - if (! $classReflection->isSubClassOf('Symfony\Component\Console\Command\Command')) { + if (! $classReflection->is('Symfony\Component\Console\Command\Command')) { return null; } diff --git a/rules/Symfony27/Rector/MethodCall/ChangeCollectionTypeOptionNameFromTypeToEntryTypeRector.php b/rules/Symfony27/Rector/MethodCall/ChangeCollectionTypeOptionNameFromTypeToEntryTypeRector.php index c13e2167..71db08a8 100644 --- a/rules/Symfony27/Rector/MethodCall/ChangeCollectionTypeOptionNameFromTypeToEntryTypeRector.php +++ b/rules/Symfony27/Rector/MethodCall/ChangeCollectionTypeOptionNameFromTypeToEntryTypeRector.php @@ -113,13 +113,17 @@ public function refactor(Node $node): ?Node return null; } - $this->refactorOptionsArray($optionsArray); + $hasChanged = $this->refactorOptionsArray($optionsArray); + if (! $hasChanged) { + return null; + } return $node; } - private function refactorOptionsArray(Array_ $optionsArray): void + private function refactorOptionsArray(Array_ $optionsArray): bool { + $hasChanged = false; foreach ($optionsArray->items as $arrayItem) { if (! $arrayItem instanceof ArrayItem) { continue; @@ -135,7 +139,9 @@ private function refactorOptionsArray(Array_ $optionsArray): void } $arrayItem->key = new String_($newName); + $hasChanged = true; } } + return $hasChanged; } } diff --git a/rules/Symfony30/Rector/MethodCall/OptionNameRector.php b/rules/Symfony30/Rector/MethodCall/OptionNameRector.php index d1eecd54..5b691890 100644 --- a/rules/Symfony30/Rector/MethodCall/OptionNameRector.php +++ b/rules/Symfony30/Rector/MethodCall/OptionNameRector.php @@ -41,13 +41,17 @@ public function getRuleDefinition(): RuleDefinition [ new CodeSample( <<<'CODE_SAMPLE' -$builder = new FormBuilder; -$builder->add("...", ["precision" => "...", "virtual" => "..."]; +use Symfony\Component\Form\FormBuilder; + +$formBuilder = new FormBuilder; +$formBuilder->add("...", ["precision" => "...", "virtual" => "..."]; CODE_SAMPLE , <<<'CODE_SAMPLE' -$builder = new FormBuilder; -$builder->add("...", ["scale" => "...", "inherit_data" => "..."]; +use Symfony\Component\Form\FormBuilder; + +$formBuilder = new FormBuilder; +$formBuilder->add("...", ["scale" => "...", "inherit_data" => "..."]; CODE_SAMPLE ), ] diff --git a/rules/Symfony34/Rector/Closure/ContainerGetNameToTypeInTestsRector.php b/rules/Symfony34/Rector/Closure/ContainerGetNameToTypeInTestsRector.php index d2f4976f..3b304436 100644 --- a/rules/Symfony34/Rector/Closure/ContainerGetNameToTypeInTestsRector.php +++ b/rules/Symfony34/Rector/Closure/ContainerGetNameToTypeInTestsRector.php @@ -30,9 +30,11 @@ public function __construct( public function getRuleDefinition(): RuleDefinition { - return new RuleDefinition('Change $container->get("some_name") to bare type, useful since Symfony 3.4', [ - new CodeSample( - <<<'CODE_SAMPLE' + return new RuleDefinition( + 'Change $container->get("some_name") in tests to bare type, useful since Symfony 3.4', + [ + new CodeSample( + <<<'CODE_SAMPLE' use PHPUnit\Framework\TestCase; final class SomeTest extends TestCase @@ -45,8 +47,8 @@ public function run() } CODE_SAMPLE - , - <<<'CODE_SAMPLE' + , + <<<'CODE_SAMPLE' use PHPUnit\Framework\TestCase; final class SomeTest extends TestCase @@ -58,8 +60,10 @@ public function run() } } CODE_SAMPLE - ), - ]); + ), + + ] + ); } /** diff --git a/rules/Symfony42/Rector/MethodCall/ContainerGetToConstructorInjectionRector.php b/rules/Symfony42/Rector/MethodCall/ContainerGetToConstructorInjectionRector.php index df14f03c..35f26067 100644 --- a/rules/Symfony42/Rector/MethodCall/ContainerGetToConstructorInjectionRector.php +++ b/rules/Symfony42/Rector/MethodCall/ContainerGetToConstructorInjectionRector.php @@ -5,17 +5,10 @@ namespace Rector\Symfony\Symfony42\Rector\MethodCall; use PhpParser\Node; -use PhpParser\Node\Expr\ClassConstFetch; -use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Stmt\Class_; -use PHPStan\Type\ObjectType; use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; -use Rector\NodeManipulator\ClassDependencyManipulator; -use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer; -use Rector\PostRector\ValueObject\PropertyMetadata; +use Rector\Exception\ShouldNotHappenException; use Rector\Rector\AbstractRector; -use Rector\Symfony\DependencyInjection\NodeDecorator\CommandConstructorDecorator; -use Rector\Symfony\NodeAnalyzer\DependencyInjectionMethodCallAnalyzer; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -26,14 +19,6 @@ */ final class ContainerGetToConstructorInjectionRector extends AbstractRector implements DeprecatedInterface { - public function __construct( - private readonly DependencyInjectionMethodCallAnalyzer $dependencyInjectionMethodCallAnalyzer, - private readonly TestsNodeAnalyzer $testsNodeAnalyzer, - private readonly ClassDependencyManipulator $classDependencyManipulator, - private readonly CommandConstructorDecorator $commandConstructorDecorator, - ) { - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( @@ -86,61 +71,9 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - if ($this->testsNodeAnalyzer->isInTestClass($node)) { - return null; - } - - $class = $node; - $propertyMetadatas = []; - - $this->traverseNodesWithCallable($class, function (Node $node) use ($class, &$propertyMetadatas): ?Node { - if (! $node instanceof MethodCall) { - return null; - } - - if (! $this->isName($node->name, 'get')) { - return null; - } - - if (! $this->isObjectType( - $node->var, - new ObjectType('Symfony\Component\DependencyInjection\ContainerInterface') - )) { - return null; - } - - if ($node->isFirstClassCallable()) { - return null; - } - - $args = $node->getArgs(); - if (count($args) === 1 && $args[0]->value instanceof ClassConstFetch) { - return null; - } - - $propertyMetadata = $this->dependencyInjectionMethodCallAnalyzer->replaceMethodCallWithPropertyFetchAndDependency( - $class, - $node - ); - - if (! $propertyMetadata instanceof PropertyMetadata) { - return null; - } - - $propertyMetadatas[] = $propertyMetadata; - return $this->nodeFactory->createPropertyFetch('this', $propertyMetadata->getName()); - }); - - if ($propertyMetadatas === []) { - return null; - } - - foreach ($propertyMetadatas as $propertyMetadata) { - $this->classDependencyManipulator->addConstructorDependency($class, $propertyMetadata); - } - - $this->commandConstructorDecorator->decorate($class); - - return $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/rules/Symfony42/Rector/New_/StringToArrayArgumentProcessRector.php b/rules/Symfony42/Rector/New_/StringToArrayArgumentProcessRector.php index 90868180..6963de2c 100644 --- a/rules/Symfony42/Rector/New_/StringToArrayArgumentProcessRector.php +++ b/rules/Symfony42/Rector/New_/StringToArrayArgumentProcessRector.php @@ -111,7 +111,11 @@ private function processArgumentPosition(New_|MethodCall $node, int $argumentPos return null; } - $this->processStringType($node, $argumentPosition, $activeArgValue); + $hasChanged = $this->processStringType($node, $argumentPosition, $activeArgValue); + + if (! $hasChanged) { + return null; + } return $node; } @@ -121,25 +125,29 @@ private function shouldSkipProcessMethodCall(MethodCall $methodCall): bool return in_array($methodName, self::EXCLUDED_PROCESS_METHOD_CALLS, true); } - private function processStringType(New_|MethodCall $expr, int $argumentPosition, Expr $firstArgumentExpr): void + private function processStringType(New_|MethodCall $expr, int $argumentPosition, Expr $firstArgumentExpr): bool { if ($firstArgumentExpr instanceof Concat) { $arrayNode = $this->nodeTransformer->transformConcatToStringArray($firstArgumentExpr); $expr->args[$argumentPosition] = new Arg($arrayNode); - return; + return true; } $args = $expr->getArgs(); + $hasChanged = false; if ($firstArgumentExpr instanceof FuncCall && $this->isName($firstArgumentExpr, 'sprintf')) { $arrayNode = $this->nodeTransformer->transformSprintfToArray($firstArgumentExpr); if ($arrayNode instanceof Array_) { $args[$argumentPosition]->value = $arrayNode; + $hasChanged = true; } } elseif ($firstArgumentExpr instanceof String_) { $parts = $this->splitProcessCommandToItems($firstArgumentExpr->value); $args[$argumentPosition]->value = $this->nodeFactory->createArray($parts); + $hasChanged = true; } + return $hasChanged; } /** diff --git a/rules/Symfony43/Rector/ClassMethod/EventDispatcherParentConstructRector.php b/rules/Symfony43/Rector/ClassMethod/EventDispatcherParentConstructRector.php index 81d6d0ed..341b4409 100644 --- a/rules/Symfony43/Rector/ClassMethod/EventDispatcherParentConstructRector.php +++ b/rules/Symfony43/Rector/ClassMethod/EventDispatcherParentConstructRector.php @@ -86,7 +86,7 @@ public function refactor(Node $node): ?Node } $classReflection = $scope->getClassReflection(); - if (! $classReflection->isSubclassOf('Symfony\Contracts\EventDispatcher\EventDispatcherInterface')) { + if (! $classReflection->is('Symfony\Contracts\EventDispatcher\EventDispatcherInterface')) { return null; } diff --git a/rules/Symfony43/Rector/MethodCall/ConvertRenderTemplateShortNotationToBundleSyntaxRector.php b/rules/Symfony43/Rector/MethodCall/ConvertRenderTemplateShortNotationToBundleSyntaxRector.php index 21086ab0..cf74da80 100644 --- a/rules/Symfony43/Rector/MethodCall/ConvertRenderTemplateShortNotationToBundleSyntaxRector.php +++ b/rules/Symfony43/Rector/MethodCall/ConvertRenderTemplateShortNotationToBundleSyntaxRector.php @@ -13,12 +13,14 @@ use PHPStan\Type\ThisType; use Rector\PhpParser\Node\Value\ValueResolver; use Rector\Rector\AbstractRector; +use Rector\Symfony\Enum\SymfonyClass; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** * @changelog https://github.com/symfony/symfony/pull/21035 * @changelog https://github.com/symfony/symfony/blob/4.4/src/Symfony/Bundle/FrameworkBundle/Templating/TemplateNameParser.php + * * @changelog https://symfony.com/doc/4.4/templates.html#bundle-templates * * @see \Rector\Symfony\Tests\Symfony43\Rector\MethodCall\ConvertRenderTemplateShortNotationToBundleSyntaxRector\ConvertRenderTemplateShortNotationToBundleSyntaxRectorTest @@ -83,7 +85,7 @@ public function refactor(Node $node): ?Node } $objectType = $this->nodeTypeResolver->getType($node->var); - $controllerType = new ObjectType('Symfony\Bundle\FrameworkBundle\Controller\Controller'); + $controllerType = new ObjectType(SymfonyClass::CONTROLLER); if (! $controllerType->isSuperTypeOf($objectType)->yes()) { return null; } diff --git a/rules/Symfony44/Rector/ClassMethod/ConsoleExecuteReturnIntRector.php b/rules/Symfony44/Rector/ClassMethod/ConsoleExecuteReturnIntRector.php index f46e7441..3e88640c 100644 --- a/rules/Symfony44/Rector/ClassMethod/ConsoleExecuteReturnIntRector.php +++ b/rules/Symfony44/Rector/ClassMethod/ConsoleExecuteReturnIntRector.php @@ -90,6 +90,8 @@ public function refactor(Node $node): ?Node return null; } + $this->hasChanged = false; + $this->refactorReturnTypeDeclaration($executeClassMethod); $this->addReturn0ToExecuteClassMethod($executeClassMethod); diff --git a/rules/Symfony44/Rector/MethodCall/AuthorizationCheckerIsGrantedExtractorRector.php b/rules/Symfony44/Rector/MethodCall/AuthorizationCheckerIsGrantedExtractorRector.php index e01ecf9a..2d1316d9 100644 --- a/rules/Symfony44/Rector/MethodCall/AuthorizationCheckerIsGrantedExtractorRector.php +++ b/rules/Symfony44/Rector/MethodCall/AuthorizationCheckerIsGrantedExtractorRector.php @@ -13,6 +13,7 @@ use PHPStan\Type\ObjectType; use Rector\NodeAnalyzer\ArgsAnalyzer; use Rector\Rector\AbstractRector; +use Rector\Symfony\Enum\SymfonyClass; use Rector\Symfony\TypeAnalyzer\ControllerAnalyzer; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -37,12 +38,44 @@ public function getRuleDefinition(): RuleDefinition [ new CodeSample( <<<'CODE_SAMPLE' -if ($this->authorizationChecker->isGranted(['ROLE_USER', 'ROLE_ADMIN'])) { +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; + +final class SomeController +{ + public function __construct( + private AuthorizationCheckerInterface $authorizationChecker + ) { + } + + public function hasAccess(): bool + { + if ($this->authorizationChecker->isGranted(['ROLE_USER', 'ROLE_ADMIN'])) { + return true; + } + + return false; + } } CODE_SAMPLE , <<<'CODE_SAMPLE' -if ($this->authorizationChecker->isGranted('ROLE_USER') || $this->authorizationChecker->isGranted('ROLE_ADMIN')) { +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; + +final class SomeController +{ + public function __construct( + private AuthorizationCheckerInterface $authorizationChecker + ) { + } + + public function hasAccess(): bool + { + if ($this->authorizationChecker->isGranted('ROLE_USER') || $this->authorizationChecker->isGranted('ROLE_ADMIN')) { + return true; + } + + return false; + } } CODE_SAMPLE ), @@ -72,9 +105,7 @@ public function refactor(Node $node): MethodCall|BooleanOr|null return null; } - $authorizationChecker = new ObjectType( - 'Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface' - ); + $authorizationChecker = new ObjectType(SymfonyClass::AUTHORIZATION_CHECKER); if (! $authorizationChecker->isSuperTypeOf($objectType)->yes()) { return null; } diff --git a/rules/Symfony51/Rector/ClassMethod/CommandConstantReturnCodeRector.php b/rules/Symfony51/Rector/ClassMethod/CommandConstantReturnCodeRector.php index 4ce8cc17..96ebf6f0 100644 --- a/rules/Symfony51/Rector/ClassMethod/CommandConstantReturnCodeRector.php +++ b/rules/Symfony51/Rector/ClassMethod/CommandConstantReturnCodeRector.php @@ -80,7 +80,7 @@ public function refactor(Node $node): ?Node return null; } - if (! $classReflection->isSubclassOf('Symfony\Component\Console\Command\Command')) { + if (! $classReflection->is('Symfony\Component\Console\Command\Command')) { return null; } diff --git a/rules/Symfony52/Rector/New_/PropertyAccessorCreationBooleanToFlagsRector.php b/rules/Symfony52/Rector/New_/PropertyAccessorCreationBooleanToFlagsRector.php index 71451c89..3e656cd3 100644 --- a/rules/Symfony52/Rector/New_/PropertyAccessorCreationBooleanToFlagsRector.php +++ b/rules/Symfony52/Rector/New_/PropertyAccessorCreationBooleanToFlagsRector.php @@ -31,6 +31,8 @@ public function getRuleDefinition(): RuleDefinition return new RuleDefinition('Changes first argument of PropertyAccessor::__construct() to flags from boolean', [ new CodeSample( <<<'CODE_SAMPLE' +use Symfony\Component\PropertyAccess\PropertyAccessor; + class SomeClass { public function run() @@ -41,6 +43,8 @@ public function run() CODE_SAMPLE , <<<'CODE_SAMPLE' +use Symfony\Component\PropertyAccess\PropertyAccessor; + class SomeClass { public function run() diff --git a/rules/Symfony61/Rector/Class_/CommandConfigureToAttributeRector.php b/rules/Symfony61/Rector/Class_/CommandConfigureToAttributeRector.php index c37df3dd..6025824b 100644 --- a/rules/Symfony61/Rector/Class_/CommandConfigureToAttributeRector.php +++ b/rules/Symfony61/Rector/Class_/CommandConfigureToAttributeRector.php @@ -19,14 +19,15 @@ use PHPStan\Type\ObjectType; use Rector\PhpAttribute\NodeFactory\PhpAttributeGroupFactory; use Rector\Rector\AbstractRector; -use Rector\Symfony\Enum\SymfonyAnnotation; +use Rector\Symfony\Enum\SymfonyAttribute; +use Rector\Symfony\Enum\SymfonyClass; use Rector\ValueObject\PhpVersionFeature; use Rector\VersionBonding\Contract\MinPhpVersionInterface; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** - * @changelog https://symfony.com/doc/current/console.html#registering-the-command + * @see https://symfony.com/doc/current/console.html#registering-the-command * * @see \Rector\Symfony\Tests\Symfony61\Rector\Class_\CommandConfigureToAttributeRector\CommandConfigureToAttributeRectorTest */ @@ -102,11 +103,11 @@ public function refactor(Node $node): ?Node return null; } - if (! $this->reflectionProvider->hasClass(SymfonyAnnotation::AS_COMMAND)) { + if (! $this->reflectionProvider->hasClass(SymfonyAttribute::AS_COMMAND)) { return null; } - if (! $this->isObjectType($node, new ObjectType('Symfony\\Component\\Console\\Command\\Command'))) { + if (! $this->isObjectType($node, new ObjectType(SymfonyClass::COMMAND))) { return null; } @@ -120,7 +121,7 @@ public function refactor(Node $node): ?Node $attributeArgs = []; foreach ($node->attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attribute) { - if (! $this->nodeNameResolver->isName($attribute->name, SymfonyAnnotation::AS_COMMAND)) { + if (! $this->nodeNameResolver->isName($attribute->name, SymfonyAttribute::AS_COMMAND)) { continue; } @@ -139,7 +140,7 @@ public function refactor(Node $node): ?Node } if (! $asCommandAttribute instanceof Attribute) { - $asCommandAttributeGroup = $this->phpAttributeGroupFactory->createFromClass(SymfonyAnnotation::AS_COMMAND); + $asCommandAttributeGroup = $this->phpAttributeGroupFactory->createFromClass(SymfonyAttribute::AS_COMMAND); $asCommandAttribute = $asCommandAttributeGroup->attrs[0]; diff --git a/rules/Symfony61/Rector/Class_/CommandPropertyToAttributeRector.php b/rules/Symfony61/Rector/Class_/CommandPropertyToAttributeRector.php index 5c1a0fce..879fcd57 100644 --- a/rules/Symfony61/Rector/Class_/CommandPropertyToAttributeRector.php +++ b/rules/Symfony61/Rector/Class_/CommandPropertyToAttributeRector.php @@ -17,7 +17,7 @@ use Rector\Doctrine\NodeAnalyzer\AttributeFinder; use Rector\PhpAttribute\NodeFactory\PhpAttributeGroupFactory; use Rector\Rector\AbstractRector; -use Rector\Symfony\Enum\SymfonyAnnotation; +use Rector\Symfony\Enum\SymfonyAttribute; use Rector\Symfony\Enum\SymfonyClass; use Rector\ValueObject\PhpVersionFeature; use Rector\VersionBonding\Contract\MinPhpVersionInterface; @@ -91,7 +91,7 @@ public function refactor(Node $node): ?Node } // does attribute already exist? - if (! $this->reflectionProvider->hasClass(SymfonyAnnotation::AS_COMMAND)) { + if (! $this->reflectionProvider->hasClass(SymfonyAttribute::AS_COMMAND)) { return null; } @@ -104,7 +104,7 @@ public function refactor(Node $node): ?Node $existingAsCommandAttribute = $this->attributeFinder->findAttributeByClass( $node, - SymfonyAnnotation::AS_COMMAND + SymfonyAttribute::AS_COMMAND ); $attributeArgs = $this->createAttributeArgs($defaultNameExpr, $defaultDescriptionExpr); @@ -126,7 +126,7 @@ private function createAttributeGroupAsCommand(array $args): AttributeGroup { Assert::allIsInstanceOf($args, Arg::class); - $attributeGroup = $this->phpAttributeGroupFactory->createFromClass(SymfonyAnnotation::AS_COMMAND); + $attributeGroup = $this->phpAttributeGroupFactory->createFromClass(SymfonyAttribute::AS_COMMAND); $attributeGroup->attrs[0]->args = $args; return $attributeGroup; diff --git a/rules/Symfony61/Rector/StaticPropertyFetch/ErrorNamesPropertyToConstantRector.php b/rules/Symfony61/Rector/StaticPropertyFetch/ErrorNamesPropertyToConstantRector.php index 0e8e6b88..a9671a38 100644 --- a/rules/Symfony61/Rector/StaticPropertyFetch/ErrorNamesPropertyToConstantRector.php +++ b/rules/Symfony61/Rector/StaticPropertyFetch/ErrorNamesPropertyToConstantRector.php @@ -73,7 +73,7 @@ public function refactor(Node $node): ?Node if (! $classReflection instanceof ClassReflection) { return null; } - if (! $classReflection->isSubclassOf('Symfony\Component\Validator\Constraint')) { + if (! $classReflection->is('Symfony\Component\Validator\Constraint')) { return null; } if (! $this->nodeNameResolver->isName($node->name, 'errorNames')) { diff --git a/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php b/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php index 2fde7762..16b0a627 100644 --- a/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php +++ b/rules/Symfony62/Rector/Class_/MessageHandlerInterfaceToAttributeRector.php @@ -6,10 +6,11 @@ use PhpParser\Node; use PhpParser\Node\Stmt\Class_; +use PHPStan\Reflection\ReflectionProvider; +use PHPStan\Type\ObjectType; use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer; use Rector\Rector\AbstractRector; use Rector\Symfony\Helper\MessengerHelper; -use Rector\Symfony\NodeAnalyzer\ClassAnalyzer; use Rector\Symfony\NodeManipulator\ClassManipulator; use Rector\Symfony\ValueObject\ServiceDefinition; use Rector\ValueObject\PhpVersionFeature; @@ -25,8 +26,8 @@ final class MessageHandlerInterfaceToAttributeRector extends AbstractRector impl public function __construct( private readonly MessengerHelper $messengerHelper, private readonly ClassManipulator $classManipulator, - private readonly ClassAnalyzer $classAnalyzer, private readonly PhpAttributeAnalyzer $phpAttributeAnalyzer, + private readonly ReflectionProvider $reflectionProvider ) { } @@ -84,11 +85,19 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { + if (! $this->reflectionProvider->hasClass(MessengerHelper::AS_MESSAGE_HANDLER_ATTRIBUTE)) { + return null; + } + if ($this->phpAttributeAnalyzer->hasPhpAttribute($node, MessengerHelper::AS_MESSAGE_HANDLER_ATTRIBUTE)) { return null; } - if (! $this->classAnalyzer->hasImplements($node, MessengerHelper::MESSAGE_HANDLER_INTERFACE)) { + $classType = $this->getType($node); + + $messageHandlerObjectType = new ObjectType(MessengerHelper::MESSAGE_HANDLER_INTERFACE); + + if (! $messageHandlerObjectType->isSuperTypeOf($classType)->yes()) { $handlers = $this->messengerHelper->getHandlersFromServices(); if ($handlers === []) { return null; @@ -99,6 +108,11 @@ public function refactor(Node $node): ?Node $this->classManipulator->removeImplements($node, [MessengerHelper::MESSAGE_HANDLER_INTERFACE]); + // no need to add the attribute + if ($node->isAbstract()) { + return $node; + } + return $this->messengerHelper->addAttribute($node); } diff --git a/rules/Symfony62/Rector/Class_/SecurityAttributeToIsGrantedAttributeRector.php b/rules/Symfony62/Rector/Class_/SecurityAttributeToIsGrantedAttributeRector.php index 3f3748a2..48c2a5d8 100644 --- a/rules/Symfony62/Rector/Class_/SecurityAttributeToIsGrantedAttributeRector.php +++ b/rules/Symfony62/Rector/Class_/SecurityAttributeToIsGrantedAttributeRector.php @@ -14,7 +14,11 @@ use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; +use PHPStan\Reflection\ReflectionProvider; use Rector\Rector\AbstractRector; +use Rector\Symfony\CodeQuality\NodeAnalyzer\AttributePresenceDetector; +use Rector\Symfony\Enum\SensioAttribute; +use Rector\Symfony\Enum\SymfonyAttribute; use Rector\ValueObject\PhpVersionFeature; use Rector\VersionBonding\Contract\MinPhpVersionInterface; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -28,16 +32,6 @@ */ final class SecurityAttributeToIsGrantedAttributeRector extends AbstractRector implements MinPhpVersionInterface { - /** - * @var string - */ - private const SECURITY_ATTRIBUTE = 'Sensio\Bundle\FrameworkExtraBundle\Configuration\Security'; - - /** - * @var string - */ - private const IS_GRANTED_ATTRIBUTE = 'Symfony\Component\Security\Http\Attribute\IsGranted'; - /** * @var string * @see https://regex101.com/r/Si1sDz/1 @@ -50,6 +44,12 @@ final class SecurityAttributeToIsGrantedAttributeRector extends AbstractRector i */ private const IS_GRANTED_AND_SUBJECT_REGEX = '#^is_granted\((\"|\')(?[\w]+)(\"|\'),\s+(?\w+)\)$#'; + public function __construct( + private readonly ReflectionProvider $reflectionProvider, + private readonly AttributePresenceDetector $attributePresenceDetector, + ) { + } + public function provideMinPhpVersion(): int { return PhpVersionFeature::ATTRIBUTES; @@ -84,12 +84,12 @@ public function list() class PostController extends Controller { - #[IsGranted('ROLE_ADMIN')] + #[IsGranted(attribute: 'ROLE_ADMIN')] public function index() { } - #[IsGranted(new Expression("is_granted('ROLE_ADMIN') and is_granted('ROLE_FRIENDLY_USER')"))] + #[IsGranted(attribute: new Expression("is_granted('ROLE_ADMIN') and is_granted('ROLE_FRIENDLY_USER')"))] public function list() { } @@ -113,15 +113,21 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { + if (! $this->attributePresenceDetector->detect(SensioAttribute::SECURITY)) { + return null; + } + $hasChanged = false; foreach ($node->attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attribute) { - if (! $this->isName($attribute->name, self::SECURITY_ATTRIBUTE)) { + if (! $this->isName($attribute->name, SensioAttribute::SECURITY)) { continue; } - $attribute->name = new FullyQualified(self::IS_GRANTED_ATTRIBUTE); + // 1. resolve closest existing name of IsGranted + $isGrantedName = $this->resolveIsGrantedAttributeName(); + $attribute->name = new FullyQualified($isGrantedName); $firstArg = $attribute->args[0]; $firstArg->name = new Identifier('attribute'); @@ -179,4 +185,14 @@ private function wrapToNewExpression(Expr $expr): New_|String_ return new New_(new FullyQualified('Symfony\Component\ExpressionLanguage\Expression'), $args); } + + private function resolveIsGrantedAttributeName(): string + { + if ($this->reflectionProvider->hasClass(SymfonyAttribute::IS_GRANTED)) { + return SymfonyAttribute::IS_GRANTED; + } + + // fallback to "sensio" + return SensioAttribute::IS_GRANTED; + } } diff --git a/rules/Symfony73/NodeAnalyzer/CommandArgumentsAndOptionsResolver.php b/rules/Symfony73/NodeAnalyzer/CommandArgumentsAndOptionsResolver.php new file mode 100644 index 00000000..dd13bce2 --- /dev/null +++ b/rules/Symfony73/NodeAnalyzer/CommandArgumentsAndOptionsResolver.php @@ -0,0 +1,90 @@ +findMethodCallsByName($configureClassMethod, 'addArgument'); + + $commandArguments = []; + foreach ($addArgumentMethodCalls as $addArgumentMethodCall) { + // @todo extract name, type and requirements + $addArgumentArgs = $addArgumentMethodCall->getArgs(); + + $nameArgValue = $addArgumentArgs[0]->value; + if (! $nameArgValue instanceof String_) { + // we need string value, otherwise param will not have a name + throw new ShouldNotHappenException('Argument name is required'); + } + + $optionName = $nameArgValue->value; + + $commandArguments[] = new CommandArgument($optionName); + } + + return $commandArguments; + } + + /** + * @return CommandOption[] + */ + public function collectCommandOptions(ClassMethod $configureClassMethod): array + { + $addOptionMethodCalls = $this->findMethodCallsByName($configureClassMethod, 'addOption'); + + $commandOptionMetadatas = []; + foreach ($addOptionMethodCalls as $addOptionMethodCall) { + // @todo extract name, type and requirements + $addOptionArgs = $addOptionMethodCall->getArgs(); + + $nameArgValue = $addOptionArgs[0]->value; + if (! $nameArgValue instanceof String_) { + // we need string value, otherwise param will not have a name + throw new ShouldNotHappenException('Option name is required'); + } + + $optionName = $nameArgValue->value; + + $commandOptionMetadatas[] = new CommandOption($optionName); + } + + return $commandOptionMetadatas; + } + + /** + * @return MethodCall[] + */ + private function findMethodCallsByName(ClassMethod $classMethod, string $desiredMethodName): array + { + $nodeFinder = new NodeFinder(); + + return $nodeFinder->find($classMethod, function (Node $node) use ($desiredMethodName): bool { + if (! $node instanceof MethodCall) { + return false; + } + + if (! $node->name instanceof Identifier) { + return false; + } + + return $node->name->toString() === $desiredMethodName; + }); + } +} diff --git a/rules/Symfony73/NodeFactory/CommandInvokeParamsFactory.php b/rules/Symfony73/NodeFactory/CommandInvokeParamsFactory.php new file mode 100644 index 00000000..08537f15 --- /dev/null +++ b/rules/Symfony73/NodeFactory/CommandInvokeParamsFactory.php @@ -0,0 +1,78 @@ +createArgumentParams($commandArguments); + $optionParams = $this->createOptionParams($commandOptions); + + return array_merge($argumentParams, $optionParams); + } + + /** + * @param CommandArgument[] $commandArguments + * @return Param[] + */ + private function createArgumentParams(array $commandArguments): array + { + $argumentParams = []; + + foreach ($commandArguments as $commandArgument) { + $argumentParam = new Param(new Variable($commandArgument->getName())); + + $argumentParam->type = new Identifier('string'); + // @todo fill type or default value + // @todo default string, multiple values array + + $argumentParam->attrGroups[] = new AttributeGroup([ + new Attribute(new FullyQualified(SymfonyAttribute::COMMAND_ARGUMENT)), + ]); + + $argumentParams[] = $argumentParam; + } + + return $argumentParams; + } + + /** + * @param CommandOption[] $commandOptions + * @return Param[] + */ + private function createOptionParams(array $commandOptions): array + { + $optionParams = []; + + foreach ($commandOptions as $commandOption) { + $optionParam = new Param(new Variable($commandOption->getName())); + + // @todo fill type or default value + $optionParam->attrGroups[] = new AttributeGroup([ + new Attribute(new FullyQualified(SymfonyAttribute::COMMAND_OPTION)), + ]); + + $optionParams[] = $optionParam; + } + + return $optionParams; + } +} diff --git a/rules/Symfony73/Rector/Class_/CommandHelpToAttributeRector.php b/rules/Symfony73/Rector/Class_/CommandHelpToAttributeRector.php new file mode 100644 index 00000000..5f503401 --- /dev/null +++ b/rules/Symfony73/Rector/Class_/CommandHelpToAttributeRector.php @@ -0,0 +1,212 @@ +setHelp() to the "help" named argument of #[AsCommand]', + [ + new CodeSample( + <<<'CODE_SAMPLE' +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Command\Command; + +#[AsCommand(name: 'app:some')] +final class SomeCommand extends Command +{ + protected function configure(): void + { + $this->setHelp('Some help text'); + } +} +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Command\Command; + +#[AsCommand(name: 'app:some', help: <<<'TXT' +Some help text +TXT)] +final class SomeCommand extends Command +{ +} +CODE_SAMPLE + ), + ] + ); + } + + /** + * @return array> + */ + public function getNodeTypes(): array + { + return [Class_::class]; + } + + /** + * @param Class_ $node + */ + public function refactor(Node $node): ?Node + { + if ($node->isAbstract()) { + return null; + } + + if (! $this->reflectionProvider->hasClass(SymfonyAttribute::AS_COMMAND)) { + return null; + } + + if (! $this->isObjectType($node, new ObjectType(SymfonyClass::COMMAND))) { + return null; + } + + $asCommandAttribute = $this->attributeFinder->findAttributeByClass($node, SymfonyAttribute::AS_COMMAND); + if (! $asCommandAttribute instanceof Attribute) { + return null; + } + + foreach ($asCommandAttribute->args as $arg) { + if ($arg->name?->toString() === 'help') { + return null; + } + } + + $configureClassMethod = $node->getMethod(CommandMethodName::CONFIGURE); + if (! $configureClassMethod instanceof ClassMethod) { + return null; + } + + $helpExpr = $this->findAndRemoveSetHelpExpr($configureClassMethod); + if (! $helpExpr instanceof String_) { + return null; + } + + $wrappedHelpString = new String_( + $helpExpr->value, + [ + Attributekey::KIND => String_::KIND_NOWDOC, + AttributeKey::DOC_LABEL => 'TXT', + ] + ); + + $asCommandAttribute->args[] = new Arg($wrappedHelpString, false, false, [], new Identifier('help')); + + if ($configureClassMethod->stmts === []) { + unset($configureClassMethod); + } + + return $node; + } + + /** + * Returns the argument passed to setHelp() and removes the MethodCall node. + */ + private function findAndRemoveSetHelpExpr(ClassMethod $configureClassMethod): ?String_ + { + $helpString = null; + + $this->traverseNodesWithCallable( + (array) $configureClassMethod->stmts, + function (Node $node) use (&$helpString): int|null|Expr { + if ($node instanceof Class_ || $node instanceof Function_) { + return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN; + } + if (! $node instanceof MethodCall) { + return null; + } + + if (! $this->isName($node->name, 'setHelp')) { + return null; + } + + if ($node->isFirstClassCallable() || ! isset($node->getArgs()[0])) { + return null; + } + + $argExpr = $node->getArgs()[0] + ->value; + if ($argExpr instanceof String_) { + $helpString = $argExpr; + } + + $parent = $node->getAttribute('parent'); + if ($parent instanceof Expression) { + unset($parent); + } + + return $node->var; + } + ); + + foreach ((array) $configureClassMethod->stmts as $key => $stmt) { + if ($this->isExpressionVariableThis($stmt)) { + unset($configureClassMethod->stmts[$key]); + } + } + + return $helpString; + } + + private function isExpressionVariableThis(Stmt $stmt): bool + { + if (! $stmt instanceof Expression) { + return false; + } + + if (! $stmt->expr instanceof Variable) { + return false; + } + + return $this->isName($stmt->expr, 'this'); + } +} diff --git a/rules/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector.php b/rules/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector.php new file mode 100644 index 00000000..41fc7719 --- /dev/null +++ b/rules/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector.php @@ -0,0 +1,267 @@ +addArgument('argument', InputArgument::REQUIRED, 'Argument description'); + $this->addOption('option', 'o', InputOption::VALUE_NONE, 'Option description'); + } + + public function execute(InputInterface $input, OutputInterface $output) + { + $someArgument = $input->getArgument('argument'); + $someOption = $input->getOption('option'); + + // ... + + return 1; + } +} +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Command\Argument; +use Symfony\Component\Console\Command\Option; + +final class SomeCommand +{ + public function __invoke( + #[Argument] + string $argument, + #[Option] + bool $option = false, + ) { + $someArgument = $argument; + $someOption = $option; + + // ... + + return 1; + } +} +CODE_SAMPLE + ), + ]); + } + + public function getNodeTypes(): array + { + return [Class_::class]; + } + + /** + * @param Class_ $node + */ + public function refactor(Node $node): ?Class_ + { + if (! $node->extends instanceof Name) { + return null; + } + + // handle only direct child classes, to keep safe + if (! $this->isName($node->extends, SymfonyClass::COMMAND)) { + return null; + } + + if ($this->isComplexCommand($node)) { + return null; + } + + // as command attribute is required, its handled by previous symfony versions + // @todo possibly to add it here to handle multiple cases + if (! $this->attributeFinder->findAttributeByClass($node, SymfonyAttribute::AS_COMMAND) instanceof Attribute) { + return null; + } + + // 1. fetch configure method to get arguments and options metadata + $configureClassMethod = $node->getMethod(CommandMethodName::CONFIGURE); + if (! $configureClassMethod instanceof ClassMethod) { + return null; + } + + // 2. rename execute to __invoke + $executeClassMethod = $node->getMethod(CommandMethodName::EXECUTE); + if (! $executeClassMethod instanceof ClassMethod) { + return null; + } + + $executeClassMethod->name = new Identifier('__invoke'); + + // 3. create arguments and options parameters + // @todo + $commandArguments = $this->commandArgumentsAndOptionsResolver->collectCommandArguments( + $configureClassMethod + ); + + $commandOptions = $this->commandArgumentsAndOptionsResolver->collectCommandOptions($configureClassMethod); + + // 4. remove configure() method + $this->removeConfigureClassMethod($node); + + // 5. decorate __invoke method with attributes + $invokeParams = $this->commandInvokeParamsFactory->createParams($commandArguments, $commandOptions); + $executeClassMethod->params = $invokeParams; + + // 6. remove parent class + $node->extends = null; + + // 7. replace input->getArgument() and input->getOption() calls with direct variable access + $this->replaceInputArgumentOptionFetchWithVariables($executeClassMethod); + + return $node; + } + + /** + * Skip commands with interact() or initialize() methods as modify the argument/option values + */ + private function isComplexCommand(Class_ $class): bool + { + if ($class->getMethod(CommandMethodName::INTERACT) instanceof ClassMethod) { + return true; + } + + return $class->getMethod(CommandMethodName::INITIALIZE) instanceof ClassMethod; + } + + private function removeConfigureClassMethod(Class_ $class): void + { + foreach ($class->stmts as $key => $stmt) { + if (! $stmt instanceof ClassMethod) { + continue; + } + + if (! $this->isName($stmt->name, CommandMethodName::CONFIGURE)) { + continue; + } + + foreach ((array) $stmt->stmts as $innerKey => $innerStmt) { + if (! $innerStmt instanceof Expression) { + continue; + } + + $expr = $innerStmt->expr; + if (! $expr instanceof MethodCall) { + continue; + } + + if ($this->isFluentArgumentOptionChain($expr)) { + unset($stmt->stmts[$innerKey]); + continue; + } + + if ($this->isName($expr->var, 'this') + && $this->isNames($expr->name, self::MIGRATED_CONFIGURE_CALLS)) { + unset($stmt->stmts[$innerKey]); + } + } + + // 2. if configure() has become empty → remove the method itself + if ($stmt->stmts === [] || $stmt->stmts === null) { + unset($class->stmts[$key]); + } + + return; + } + } + + private function replaceInputArgumentOptionFetchWithVariables(ClassMethod $executeClassMethod): void + { + $this->traverseNodesWithCallable($executeClassMethod->stmts, function (Node $node): ?Variable { + if (! $node instanceof MethodCall) { + return null; + } + + if (! $this->isName($node->var, 'input')) { + return null; + } + + if (! $this->isNames($node->name, ['getOption', 'getArgument'])) { + return null; + } + + $firstArgValue = $node->getArgs()[0] + ->value; + + if (! $firstArgValue instanceof String_) { + // unable to resolve argument/option name + throw new ShouldNotHappenException(); + } + + return new Variable($firstArgValue->value); + }); + } + + private function isFluentArgumentOptionChain(MethodCall $methodCall): bool + { + $current = $methodCall; + + while ($current instanceof MethodCall) { + // every link must be addArgument() or addOption() + if (! $this->isNames($current->name, self::MIGRATED_CONFIGURE_CALLS)) { + return false; + } + + $current = $current->var; // go one step left + } + + // the left-most var must be $this + return $current instanceof Variable && $this->isName($current, 'this'); + } +} diff --git a/rules/Symfony73/ValueObject/CommandArgument.php b/rules/Symfony73/ValueObject/CommandArgument.php new file mode 100644 index 00000000..33bfc873 --- /dev/null +++ b/rules/Symfony73/ValueObject/CommandArgument.php @@ -0,0 +1,20 @@ +name; + } +} diff --git a/rules/Symfony73/ValueObject/CommandOption.php b/rules/Symfony73/ValueObject/CommandOption.php new file mode 100644 index 00000000..b6880612 --- /dev/null +++ b/rules/Symfony73/ValueObject/CommandOption.php @@ -0,0 +1,20 @@ +name; + } +} diff --git a/rules/Twig134/Rector/Return_/SimpleFunctionAndFilterRector.php b/rules/Twig134/Rector/Return_/SimpleFunctionAndFilterRector.php index bea17abc..0fe25901 100644 --- a/rules/Twig134/Rector/Return_/SimpleFunctionAndFilterRector.php +++ b/rules/Twig134/Rector/Return_/SimpleFunctionAndFilterRector.php @@ -151,7 +151,7 @@ private function shouldSkip(ClassMethod $classMethod): bool return true; } - if (! $classReflection->isSubclassOf('Twig_Extension')) { + if (! $classReflection->is('Twig_Extension')) { return true; } diff --git a/src/ApplicationMetadata/ListenerServiceDefinitionProvider.php b/src/ApplicationMetadata/ListenerServiceDefinitionProvider.php index 8da9a2ae..47ea57f4 100644 --- a/src/ApplicationMetadata/ListenerServiceDefinitionProvider.php +++ b/src/ApplicationMetadata/ListenerServiceDefinitionProvider.php @@ -54,13 +54,11 @@ public function extract(): array $eventName = $tag->getEvent(); - if ($tag->getMethod() === '') { - // fill method based on the event - if (str_starts_with($tag->getEvent(), 'kernel.')) { - [, $event] = explode('.', $tag->getEvent()); - $methodName = 'onKernel' . ucfirst($event); - $tag->changeMethod($methodName); - } + // fill method based on the event + if ($tag->getMethod() === '' && str_starts_with($tag->getEvent(), 'kernel.')) { + [, $event] = explode('.', $tag->getEvent()); + $methodName = 'onKernel' . ucfirst($event); + $tag->changeMethod($methodName); } $this->listenerClassesToEvents[$eventListener->getClass()][$eventName][] = $eventListener; diff --git a/src/Enum/CommandMethodName.php b/src/Enum/CommandMethodName.php new file mode 100644 index 00000000..e276426c --- /dev/null +++ b/src/Enum/CommandMethodName.php @@ -0,0 +1,16 @@ +getData(); } } + if ($options['from_transport']) { $options['fromTransport'] = $options['from_transport']; unset($options['from_transport']); @@ -54,8 +60,15 @@ public function extractOptionsFromServiceDefinition(ServiceDefinition $serviceDe */ public function getHandlersFromServices(): array { + if ($this->handlersFromServices !== []) { + return $this->handlersFromServices; + } + $serviceMap = $this->serviceMapProvider->provide(); - return $serviceMap->getServicesByTag($this->messengerTagName); + + $this->handlersFromServices = $serviceMap->getServicesByTag($this->messengerTagName); + + return $this->handlersFromServices; } /** diff --git a/src/NodeAnalyzer/SymfonyClosureExtensionMatcher.php b/src/NodeAnalyzer/SymfonyClosureExtensionMatcher.php index 6ce0a972..3ad58af7 100644 --- a/src/NodeAnalyzer/SymfonyClosureExtensionMatcher.php +++ b/src/NodeAnalyzer/SymfonyClosureExtensionMatcher.php @@ -29,6 +29,10 @@ public function match(Closure $closure): ?ExtensionKeyAndConfiguration return null; } + if ($extensionNames === []) { + return null; + } + // warn use early about it, to avoid silent skip $errorMessage = sprintf( 'Split extensions "%s" to multiple separated files first', diff --git a/src/NodeAnalyzer/SymfonyTestCaseAnalyzer.php b/src/NodeAnalyzer/SymfonyTestCaseAnalyzer.php index 7e1a211e..645efbc6 100644 --- a/src/NodeAnalyzer/SymfonyTestCaseAnalyzer.php +++ b/src/NodeAnalyzer/SymfonyTestCaseAnalyzer.php @@ -22,7 +22,7 @@ public function isInWebTestCase(Node $node): bool return false; } - return $classReflection->isSubclassOf('Symfony\Bundle\FrameworkBundle\Test\WebTestCase'); + return $classReflection->is('Symfony\Bundle\FrameworkBundle\Test\WebTestCase'); } /** @@ -35,6 +35,6 @@ public function isInKernelTestCase(Node $node): bool return false; } - return $classReflection->isSubclassOf('Symfony\Bundle\FrameworkBundle\Test\KernelTestCase'); + return $classReflection->is('Symfony\Bundle\FrameworkBundle\Test\KernelTestCase'); } } diff --git a/src/Set/SetProvider/Symfony3SetProvider.php b/src/Set/SetProvider/Symfony3SetProvider.php new file mode 100644 index 00000000..ad25987c --- /dev/null +++ b/src/Set/SetProvider/Symfony3SetProvider.php @@ -0,0 +1,203 @@ +withComposerBased(symfony: true) instead + * * @api */ final class SymfonySetList @@ -37,113 +39,113 @@ final class SymfonySetList /** * @var string */ - final public const SYMFONY_30 = __DIR__ . '/../../config/sets/symfony/symfony30.php'; + final public const SYMFONY_30 = __DIR__ . '/../../config/sets/symfony/symfony3/symfony30.php'; /** * @var string */ - final public const SYMFONY_31 = __DIR__ . '/../../config/sets/symfony/symfony31.php'; + final public const SYMFONY_31 = __DIR__ . '/../../config/sets/symfony/symfony3/symfony31.php'; /** * @var string */ - final public const SYMFONY_32 = __DIR__ . '/../../config/sets/symfony/symfony32.php'; + final public const SYMFONY_32 = __DIR__ . '/../../config/sets/symfony/symfony3/symfony32.php'; /** * @var string */ - final public const SYMFONY_33 = __DIR__ . '/../../config/sets/symfony/symfony33.php'; + final public const SYMFONY_33 = __DIR__ . '/../../config/sets/symfony/symfony3/symfony33.php'; /** * @var string */ - final public const SYMFONY_34 = __DIR__ . '/../../config/sets/symfony/symfony34.php'; + final public const SYMFONY_34 = __DIR__ . '/../../config/sets/symfony/symfony3/symfony34.php'; /** * @var string */ - final public const SYMFONY_40 = __DIR__ . '/../../config/sets/symfony/symfony40.php'; + final public const SYMFONY_40 = __DIR__ . '/../../config/sets/symfony/symfony4/symfony40.php'; /** * @var string */ - final public const SYMFONY_41 = __DIR__ . '/../../config/sets/symfony/symfony41.php'; + final public const SYMFONY_41 = __DIR__ . '/../../config/sets/symfony/symfony4/symfony41.php'; /** * @var string */ - final public const SYMFONY_42 = __DIR__ . '/../../config/sets/symfony/symfony42.php'; + final public const SYMFONY_42 = __DIR__ . '/../../config/sets/symfony/symfony4/symfony42.php'; /** * @var string */ - final public const SYMFONY_43 = __DIR__ . '/../../config/sets/symfony/symfony43.php'; + final public const SYMFONY_43 = __DIR__ . '/../../config/sets/symfony/symfony4/symfony43.php'; /** * @var string */ - final public const SYMFONY_44 = __DIR__ . '/../../config/sets/symfony/symfony44.php'; + final public const SYMFONY_44 = __DIR__ . '/../../config/sets/symfony/symfony4/symfony44.php'; /** * @var string */ - final public const SYMFONY_50 = __DIR__ . '/../../config/sets/symfony/symfony50.php'; + final public const SYMFONY_50 = __DIR__ . '/../../config/sets/symfony/symfony5/symfony50.php'; /** * @var string */ - final public const SYMFONY_50_TYPES = __DIR__ . '/../../config/sets/symfony/symfony50-types.php'; + final public const SYMFONY_50_TYPES = __DIR__ . '/../../config/sets/symfony/symfony5/symfony50/symfony50-types.php'; /** * @var string */ - final public const SYMFONY_51 = __DIR__ . '/../../config/sets/symfony/symfony51.php'; + final public const SYMFONY_51 = __DIR__ . '/../../config/sets/symfony/symfony5/symfony51.php'; /** * @var string */ - final public const SYMFONY_52 = __DIR__ . '/../../config/sets/symfony/symfony52.php'; + final public const SYMFONY_52 = __DIR__ . '/../../config/sets/symfony/symfony5/symfony52.php'; /** * @var string */ - final public const SYMFONY_53 = __DIR__ . '/../../config/sets/symfony/symfony53.php'; + final public const SYMFONY_53 = __DIR__ . '/../../config/sets/symfony/symfony5/symfony53.php'; /** * @var string */ - final public const SYMFONY_54 = __DIR__ . '/../../config/sets/symfony/symfony54.php'; + final public const SYMFONY_54 = __DIR__ . '/../../config/sets/symfony/symfony5/symfony54.php'; /** * @deprecated Use ->withAttributesSets(symfony: true) in rector.php config instead * @var string */ - final public const SYMFONY_52_VALIDATOR_ATTRIBUTES = __DIR__ . '/../../config/sets/symfony/symfony52-validator-attributes.php'; + final public const SYMFONY_52_VALIDATOR_ATTRIBUTES = __DIR__ . '/../../config/sets/symfony/symfony5/symfony52-validator-attributes.php'; /** * @var string */ - final public const SYMFONY_60 = __DIR__ . '/../../config/sets/symfony/symfony60.php'; + final public const SYMFONY_60 = __DIR__ . '/../../config/sets/symfony/symfony6/symfony60.php'; /** * @var string */ - final public const SYMFONY_61 = __DIR__ . '/../../config/sets/symfony/symfony61.php'; + final public const SYMFONY_61 = __DIR__ . '/../../config/sets/symfony/symfony6/symfony61.php'; /** * @var string */ - final public const SYMFONY_62 = __DIR__ . '/../../config/sets/symfony/symfony62.php'; + final public const SYMFONY_62 = __DIR__ . '/../../config/sets/symfony/symfony6/symfony62.php'; /** * @var string */ - final public const SYMFONY_63 = __DIR__ . '/../../config/sets/symfony/symfony63.php'; + final public const SYMFONY_63 = __DIR__ . '/../../config/sets/symfony/symfony6/symfony63.php'; /** * @var string */ - final public const SYMFONY_64 = __DIR__ . '/../../config/sets/symfony/symfony64.php'; + final public const SYMFONY_64 = __DIR__ . '/../../config/sets/symfony/symfony6/symfony64.php'; /** * @var string @@ -160,6 +162,11 @@ final class SymfonySetList */ final public const SYMFONY_72 = __DIR__ . '/../../config/sets/symfony/symfony72.php'; + /** + * @var string + */ + final public const SYMFONY_73 = __DIR__ . '/../../config/sets/symfony/symfony73.php'; + /** * @var string */ diff --git a/src/TypeAnalyzer/ContainerAwareAnalyzer.php b/src/TypeAnalyzer/ContainerAwareAnalyzer.php index 3d05e094..17490134 100644 --- a/src/TypeAnalyzer/ContainerAwareAnalyzer.php +++ b/src/TypeAnalyzer/ContainerAwareAnalyzer.php @@ -7,6 +7,7 @@ use PhpParser\Node\Expr; use PHPStan\Type\ObjectType; use Rector\NodeTypeResolver\NodeTypeResolver; +use Rector\Symfony\Enum\SymfonyClass; final class ContainerAwareAnalyzer { @@ -19,9 +20,9 @@ public function __construct( private readonly NodeTypeResolver $nodeTypeResolver, ) { $this->getMethodAwareObjectTypes = [ - new ObjectType('Symfony\Bundle\FrameworkBundle\Controller\AbstractController'), - new ObjectType('Symfony\Bundle\FrameworkBundle\Controller\Controller'), - new ObjectType('Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait'), + new ObjectType(SymfonyClass::ABSTRACT_CONTROLLER), + new ObjectType(SymfonyClass::CONTROLLER), + new ObjectType(SymfonyClass::CONTROLLER_TRAIT), ]; } diff --git a/src/TypeAnalyzer/ControllerAnalyzer.php b/src/TypeAnalyzer/ControllerAnalyzer.php index a452e5ff..4081c83b 100644 --- a/src/TypeAnalyzer/ControllerAnalyzer.php +++ b/src/TypeAnalyzer/ControllerAnalyzer.php @@ -14,6 +14,7 @@ use PHPStan\Type\TypeWithClassName; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\Reflection\ReflectionResolver; +use Rector\Symfony\Enum\SymfonyClass; final readonly class ControllerAnalyzer { @@ -68,11 +69,11 @@ public function isInsideController(Node $node): bool private function isControllerClassReflection(ClassReflection $classReflection): bool { - if ($classReflection->isSubclassOf('Symfony\Bundle\FrameworkBundle\Controller\Controller')) { + if ($classReflection->is(SymfonyClass::CONTROLLER)) { return true; } - return $classReflection->isSubclassOf('Symfony\Bundle\FrameworkBundle\Controller\AbstractController'); + return $classReflection->is(SymfonyClass::ABSTRACT_CONTROLLER); } private function isControllerClass(Class_ $class): bool diff --git a/src/ValueObjectFactory/ServiceMapFactory.php b/src/ValueObjectFactory/ServiceMapFactory.php index 76ea7096..c110bbbd 100644 --- a/src/ValueObjectFactory/ServiceMapFactory.php +++ b/src/ValueObjectFactory/ServiceMapFactory.php @@ -47,6 +47,10 @@ public function createFromFileContent(string $configFilePath): ServiceMap $def = $this->convertXmlToArray($def); $tags = $this->createTagFromXmlElement($def); + if (in_array('container.excluded', array_column($tags, 'name'), true)) { + continue; + } + $service = $this->createServiceFromXmlAndTagsData($attrs, $tags); if ($service->getAlias() !== null) { $aliases[] = $service; diff --git a/stubs/Symfony/Bundle/FrameworkExtraBundle/Configuration/Security.php b/stubs/Symfony/Bundle/FrameworkExtraBundle/Configuration/Security.php index ebb0fddd..ee3376d6 100644 --- a/stubs/Symfony/Bundle/FrameworkExtraBundle/Configuration/Security.php +++ b/stubs/Symfony/Bundle/FrameworkExtraBundle/Configuration/Security.php @@ -2,6 +2,10 @@ namespace Sensio\Bundle\FrameworkExtraBundle\Configuration; +#[\Attribute] class Security { + public function __construct(string $expression) + { + } } diff --git a/stubs/Symfony/Component/HttpFoundation/Request.php b/stubs/Symfony/Component/HttpFoundation/Request.php index 2007c895..0bdb8947 100644 --- a/stubs/Symfony/Component/HttpFoundation/Request.php +++ b/stubs/Symfony/Component/HttpFoundation/Request.php @@ -10,5 +10,16 @@ final class Request { + public function getRequestType() + { + } + // newer version + public function isMainRequest() + { + } + + public function isMasterRequest() + { + } } diff --git a/stubs/Symfony/Component/Messenger/Attribute/AsMessageHandler.php b/stubs/Symfony/Component/Messenger/Attribute/AsMessageHandler.php new file mode 100644 index 00000000..083014dd --- /dev/null +++ b/stubs/Symfony/Component/Messenger/Attribute/AsMessageHandler.php @@ -0,0 +1,8 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Attribute; + +if (class_exists('Symfony\Component\Console\Attribute\AsCommand')) { + return; +} + +/** + * Service tag to autoconfigure commands. + * + * @final since Symfony 7.3 + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class AsCommand +{ + /** + * @param string $name The name of the command, used when calling it (i.e. "cache:clear") + * @param string|null $description The description of the command, displayed with the help page + * @param string[] $aliases The list of aliases of the command. The command will be executed when using one of them (i.e. "cache:clean") + * @param bool $hidden If true, the command won't be shown when listing all the available commands, but it can still be run as any other command + * @param string|null $help The help content of the command, displayed with the help page + */ + public function __construct( + public string $name, + public ?string $description = null, + array $aliases = [], + bool $hidden = false, + public ?string $help = null, + ) { + if (!$hidden && !$aliases) { + return; + } + + $name = explode('|', $name); + $name = array_merge($name, $aliases); + + if ($hidden && '' !== $name[0]) { + array_unshift($name, ''); + } + + $this->name = implode('|', $name); + } +} diff --git a/tests/Rector/ClassMethod/ArgumentValueResolverToValueResolverRector/config/configured_rule.php b/tests/Rector/ClassMethod/ArgumentValueResolverToValueResolverRector/config/configured_rule.php deleted file mode 100644 index 846ce4e4..00000000 --- a/tests/Rector/ClassMethod/ArgumentValueResolverToValueResolverRector/config/configured_rule.php +++ /dev/null @@ -1,12 +0,0 @@ -import(__DIR__ . '/../../../../../config/config.php'); - - $rectorConfig->rule(ArgumentValueResolverToValueResolverRector::class); -}; diff --git a/tests/Set/Symfony73/Fixture/command_remove_config.php.inc b/tests/Set/Symfony73/Fixture/command_remove_config.php.inc new file mode 100644 index 00000000..e46999d5 --- /dev/null +++ b/tests/Set/Symfony73/Fixture/command_remove_config.php.inc @@ -0,0 +1,72 @@ +setHelp( + 'The %command.name% command will do some + argument passed to it: + + php %command.full_name% argument' + ); + $this->addArgument('argument', InputArgument::REQUIRED, 'Argument description'); + $this->addOption('option', 'o', InputOption::VALUE_NONE, 'Option description'); + } + + public function execute(InputInterface $input, OutputInterface $output): int + { + $someArgument = $input->getArgument('argument'); + $someOption = $input->getOption('option'); + + // ... + + return 1; + } +} + +?> +----- +%command.name% command will do some + argument passed to it: + + php %command.full_name% argument +TXT)] +final class SomeCommand +{ + public function __invoke(#[\Symfony\Component\Console\Attribute\Command\Argument] + string $argument, #[\Symfony\Component\Console\Attribute\Command\Option] + $option): int + { + $someArgument = $argument; + $someOption = $option; + + // ... + + return 1; + } +} + +?> diff --git a/tests/Set/Symfony73/Symfony73Test.php b/tests/Set/Symfony73/Symfony73Test.php new file mode 100644 index 00000000..a4da7392 --- /dev/null +++ b/tests/Set/Symfony73/Symfony73Test.php @@ -0,0 +1,28 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/symfony73.php'; + } +} diff --git a/tests/Set/Symfony73/config/symfony73.php b/tests/Set/Symfony73/config/symfony73.php new file mode 100644 index 00000000..219b3986 --- /dev/null +++ b/tests/Set/Symfony73/config/symfony73.php @@ -0,0 +1,10 @@ +sets([SymfonySetList::SYMFONY_73]); +};