diff --git a/config/set/laravel-static-to-injection.php b/config/set/laravel-static-to-injection.php index 4179ecfd65a..ca2f7042604 100644 --- a/config/set/laravel-static-to-injection.php +++ b/config/set/laravel-static-to-injection.php @@ -3,7 +3,9 @@ declare(strict_types=1); use Rector\Generic\Rector\FuncCall\FuncCallToNewRector; +use Rector\Laravel\Rector\FuncCall\HelperFuncCallToFacadeClassRector; use Rector\Laravel\Rector\StaticCall\RequestStaticValidateToInjectRector; +use Rector\Renaming\Rector\Name\RenameClassRector; use function Rector\SymfonyPhpConfig\inline_value_objects; use Rector\Transform\Rector\FuncCall\ArgumentFuncCallToMethodCallRector; use Rector\Transform\Rector\StaticCall\StaticCallToMethodCallRector; @@ -12,232 +14,213 @@ use Rector\Transform\ValueObject\ArrayFuncCallToMethodCall; use Rector\Transform\ValueObject\StaticCallToMethodCall; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +/** + * @see https://www.freecodecamp.org/news/moving-away-from-magic-or-why-i-dont-want-to-use-laravel-anymore-2ce098c979bd/ + * @see https://tomasvotruba.com/blog/2019/03/04/how-to-turn-laravel-from-static-to-dependency-injection-in-one-day/ + * @see https://laravel.com/docs/5.7/facades#facades-vs-dependency-injection + */ return static function (ContainerConfigurator $containerConfigurator): void { $containerConfigurator->import(__DIR__ . '/laravel-array-str-functions-to-static-call.php'); - $services = $containerConfigurator->services(); - - // https://laravel.com/docs/5.7/facades#facades-vs-dependency-injection - $services->set(StaticCallToMethodCallRector::class) - ->call('configure', [[ - StaticCallToMethodCallRector::STATIC_CALLS_TO_METHOD_CALLS => inline_value_objects([ - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\App', - '*', - 'Illuminate\Foundation\Application', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Artisan', - '*', - 'Illuminate\Contracts\Console\Kernel', - '*' - ), - new StaticCallToMethodCall('Illuminate\Support\Facades\Auth', '*', 'Illuminate\Auth\AuthManager', '*'), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Blade', - '*', - 'Illuminate\View\Compilers\BladeCompiler', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Broadcast', - '*', - 'Illuminate\Contracts\Broadcasting\Factory', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Bus', - '*', - 'Illuminate\Contracts\Bus\Dispatcher', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Cache', - '*', - 'Illuminate\Cache\CacheManager', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Config', - '*', - 'Illuminate\Config\Repository', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Cookie', - '*', - 'Illuminate\Cookie\CookieJar', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Crypt', - '*', - 'Illuminate\Encryption\Encrypter', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\DB', - '*', - 'Illuminate\Database\DatabaseManager', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Event', - '*', - 'Illuminate\Events\Dispatcher', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\File', - '*', - 'Illuminate\Filesystem\Filesystem', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Gate', - '*', - 'Illuminate\Contracts\Auth\Access\Gate', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Hash', - '*', - 'Illuminate\Contracts\Hashing\Hasher', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Lang', - '*', - 'Illuminate\Translation\Translator', - '*' - ), - new StaticCallToMethodCall('Illuminate\Support\Facades\Log', '*', 'Illuminate\Log\LogManager', '*'), - new StaticCallToMethodCall('Illuminate\Support\Facades\Mail', '*', 'Illuminate\Mail\Mailer', '*'), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Notification', - '*', - 'Illuminate\Notifications\ChannelManager', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Password', - '*', - 'Illuminate\Auth\Passwords\PasswordBrokerManager', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Queue', - '*', - 'Illuminate\Queue\QueueManager', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Redirect', - '*', - 'Illuminate\Routing\Redirector', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Redis', - '*', - 'Illuminate\Redis\RedisManager', - '*' - ), - new StaticCallToMethodCall('Illuminate\Support\Facades\Request', '*', 'Illuminate\Http\Request', '*'), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Response', - '*', - 'Illuminate\Contracts\Routing\ResponseFactory', - '*' - ), - new StaticCallToMethodCall('Illuminate\Support\Facades\Route', '*', 'Illuminate\Routing\Router', '*'), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Schema', - '*', - 'Illuminate\Database\Schema\Builder', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Session', - '*', - 'Illuminate\Session\SessionManager', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Storage', - '*', - 'Illuminate\Filesystem\FilesystemManager', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\URL', - '*', - 'Illuminate\Routing\UrlGenerator', - '*' - ), - new StaticCallToMethodCall( - 'Illuminate\Support\Facades\Validator', - '*', - 'Illuminate\Validation\Factory', - '*' - ), - new StaticCallToMethodCall('Illuminate\Support\Facades\View', '*', 'Illuminate\View\Factory', '*'), - ]), - ]]); - + $services->set(StaticCallToMethodCallRector::class)->call('configure', [[ + StaticCallToMethodCallRector::STATIC_CALLS_TO_METHOD_CALLS => inline_value_objects([ + new StaticCallToMethodCall('Illuminate\Support\Facades\App', '*', 'Illuminate\Foundation\Application', '*'), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Artisan', + '*', + 'Illuminate\Contracts\Console\Kernel', + '*' + ), + new StaticCallToMethodCall('Illuminate\Support\Facades\Auth', '*', 'Illuminate\Auth\AuthManager', '*'), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Blade', + '*', + 'Illuminate\View\Compilers\BladeCompiler', + '*' + ), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Broadcast', + '*', + 'Illuminate\Contracts\Broadcasting\Factory', + '*' + ), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Bus', + '*', + 'Illuminate\Contracts\Bus\Dispatcher', + '*' + ), + new StaticCallToMethodCall('Illuminate\Support\Facades\Cache', '*', 'Illuminate\Cache\CacheManager', '*'), + new StaticCallToMethodCall('Illuminate\Support\Facades\Config', '*', 'Illuminate\Config\Repository', '*'), + new StaticCallToMethodCall('Illuminate\Support\Facades\Cookie', '*', 'Illuminate\Cookie\CookieJar', '*'), + new StaticCallToMethodCall('Illuminate\Support\Facades\Crypt', '*', 'Illuminate\Encryption\Encrypter', '*'), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\DB', + '*', + 'Illuminate\Database\DatabaseManager', + '*' + ), + new StaticCallToMethodCall('Illuminate\Support\Facades\Event', '*', 'Illuminate\Events\Dispatcher', '*'), + new StaticCallToMethodCall('Illuminate\Support\Facades\File', '*', 'Illuminate\Filesystem\Filesystem', '*'), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Gate', + '*', + 'Illuminate\Contracts\Auth\Access\Gate', + '*' + ), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Hash', + '*', + 'Illuminate\Contracts\Hashing\Hasher', + '*' + ), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Lang', + '*', + 'Illuminate\Translation\Translator', + '*' + ), + new StaticCallToMethodCall('Illuminate\Support\Facades\Log', '*', 'Illuminate\Log\LogManager', '*'), + new StaticCallToMethodCall('Illuminate\Support\Facades\Mail', '*', 'Illuminate\Mail\Mailer', '*'), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Notification', + '*', + 'Illuminate\Notifications\ChannelManager', + '*' + ), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Password', + '*', + 'Illuminate\Auth\Passwords\PasswordBrokerManager', + '*' + ), + new StaticCallToMethodCall('Illuminate\Support\Facades\Queue', '*', 'Illuminate\Queue\QueueManager', '*'), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Redirect', + '*', + 'Illuminate\Routing\Redirector', + '*' + ), + new StaticCallToMethodCall('Illuminate\Support\Facades\Redis', '*', 'Illuminate\Redis\RedisManager', '*'), + new StaticCallToMethodCall('Illuminate\Support\Facades\Request', '*', 'Illuminate\Http\Request', '*'), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Response', + '*', + 'Illuminate\Contracts\Routing\ResponseFactory', + '*' + ), + new StaticCallToMethodCall('Illuminate\Support\Facades\Route', '*', 'Illuminate\Routing\Router', '*'), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Schema', + '*', + 'Illuminate\Database\Schema\Builder', + '*' + ), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Session', + '*', + 'Illuminate\Session\SessionManager', + '*' + ), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Storage', + '*', + 'Illuminate\Filesystem\FilesystemManager', + '*' + ), + new StaticCallToMethodCall('Illuminate\Support\Facades\URL', '*', 'Illuminate\Routing\UrlGenerator', '*'), + new StaticCallToMethodCall( + 'Illuminate\Support\Facades\Validator', + '*', + 'Illuminate\Validation\Factory', + '*' + ), + new StaticCallToMethodCall('Illuminate\Support\Facades\View', '*', 'Illuminate\View\Factory', '*'), + ]), + ]]); $services->set(RequestStaticValidateToInjectRector::class); - // @see https://github.com/laravel/framework/blob/78828bc779e410e03cc6465f002b834eadf160d2/src/Illuminate/Foundation/helpers.php#L959 // @see https://gist.github.com/barryvdh/bb6ffc5d11e0a75dba67 - $services->set(ArgumentFuncCallToMethodCallRector::class) - ->call('configure', [[ - ArgumentFuncCallToMethodCallRector::FUNCTIONS_TO_METHOD_CALLS => inline_value_objects([ - new ArgumentFuncCallToMethodCall('auth', 'Illuminate\Contracts\Auth\Guard'), - new ArgumentFuncCallToMethodCall('policy', 'Illuminate\Contracts\Auth\Access\Gate', 'getPolicyFor'), - new ArgumentFuncCallToMethodCall('cookie', 'Illuminate\Contracts\Cookie\Factory', 'make'), - // router - new ArgumentFuncCallToMethodCall('put', 'Illuminate\Routing\Router', 'put'), - new ArgumentFuncCallToMethodCall('get', 'Illuminate\Routing\Router', 'get'), - new ArgumentFuncCallToMethodCall('post', 'Illuminate\Routing\Router', 'post'), - new ArgumentFuncCallToMethodCall('patch', 'Illuminate\Routing\Router', 'patch'), - new ArgumentFuncCallToMethodCall('delete', 'Illuminate\Routing\Router', 'delete'), - new ArgumentFuncCallToMethodCall('resource', 'Illuminate\Routing\Router', 'resource'), - new ArgumentFuncCallToMethodCall( - 'response', - 'Illuminate\Contracts\Routing\ResponseFactory', - 'make' - ), - new ArgumentFuncCallToMethodCall('info', 'Illuminate\Log\Writer', 'info'), - new ArgumentFuncCallToMethodCall('view', 'Illuminate\Contracts\View\Factory', 'make'), - new ArgumentFuncCallToMethodCall('bcrypt', 'Illuminate\Hashing\BcryptHasher', 'make'), - new ArgumentFuncCallToMethodCall('redirect', 'Illuminate\Routing\Redirector', 'back'), - new ArgumentFuncCallToMethodCall('broadcast', 'Illuminate\Contracts\Broadcasting\Factory', 'event'), - new ArgumentFuncCallToMethodCall('event', 'Illuminate\Events\Dispatcher', 'fire'), - new ArgumentFuncCallToMethodCall('dispatch', 'Illuminate\Events\Dispatcher', 'dispatch'), - new ArgumentFuncCallToMethodCall('route', 'Illuminate\Routing\UrlGenerator', 'route'), - new ArgumentFuncCallToMethodCall('asset', 'Illuminate\Routing\UrlGenerator', 'asset'), - new ArgumentFuncCallToMethodCall('url', 'Illuminate\Contracts\Routing\UrlGenerator', 'to'), - new ArgumentFuncCallToMethodCall('action', 'Illuminate\Routing\UrlGenerator', 'action'), - new ArgumentFuncCallToMethodCall('trans', 'Illuminate\Translation\Translator', 'trans'), - new ArgumentFuncCallToMethodCall( - 'trans_choice', - 'Illuminate\Translation\Translator', - 'transChoice' - ), - new ArgumentFuncCallToMethodCall('logger', 'Illuminate\Log\Writer', 'debug'), - new ArgumentFuncCallToMethodCall('back', 'Illuminate\Routing\Redirector', 'back', 'back'), - ]), - ArgumentFuncCallToMethodCallRector::ARRAY_FUNCTIONS_TO_METHOD_CALLS => inline_value_objects([ - new ArrayFuncCallToMethodCall('config', 'Illuminate\Contracts\Config\Repository', 'set', 'get'), - new ArrayFuncCallToMethodCall('session', 'Illuminate\Session\SessionManager', 'put', 'get'), - ]), - ]]); + $services->set(ArgumentFuncCallToMethodCallRector::class)->call('configure', [[ + ArgumentFuncCallToMethodCallRector::FUNCTIONS_TO_METHOD_CALLS => inline_value_objects([ + new ArgumentFuncCallToMethodCall('auth', 'Illuminate\Contracts\Auth\Guard'), + new ArgumentFuncCallToMethodCall('policy', 'Illuminate\Contracts\Auth\Access\Gate', 'getPolicyFor'), + new ArgumentFuncCallToMethodCall('cookie', 'Illuminate\Contracts\Cookie\Factory', 'make'), + // router + new ArgumentFuncCallToMethodCall('put', 'Illuminate\Routing\Router', 'put'), + new ArgumentFuncCallToMethodCall('get', 'Illuminate\Routing\Router', 'get'), + new ArgumentFuncCallToMethodCall('post', 'Illuminate\Routing\Router', 'post'), + new ArgumentFuncCallToMethodCall('patch', 'Illuminate\Routing\Router', 'patch'), + new ArgumentFuncCallToMethodCall('delete', 'Illuminate\Routing\Router', 'delete'), + new ArgumentFuncCallToMethodCall('resource', 'Illuminate\Routing\Router', 'resource'), + new ArgumentFuncCallToMethodCall('response', 'Illuminate\Contracts\Routing\ResponseFactory', 'make'), + new ArgumentFuncCallToMethodCall('info', 'Illuminate\Log\Writer', 'info'), + new ArgumentFuncCallToMethodCall('view', 'Illuminate\Contracts\View\Factory', 'make'), + new ArgumentFuncCallToMethodCall('bcrypt', 'Illuminate\Hashing\BcryptHasher', 'make'), + new ArgumentFuncCallToMethodCall('redirect', 'Illuminate\Routing\Redirector', 'back'), + new ArgumentFuncCallToMethodCall('broadcast', 'Illuminate\Contracts\Broadcasting\Factory', 'event'), + new ArgumentFuncCallToMethodCall('event', 'Illuminate\Events\Dispatcher', 'fire'), + new ArgumentFuncCallToMethodCall('dispatch', 'Illuminate\Events\Dispatcher', 'dispatch'), + new ArgumentFuncCallToMethodCall('route', 'Illuminate\Routing\UrlGenerator', 'route'), + new ArgumentFuncCallToMethodCall('asset', 'Illuminate\Routing\UrlGenerator', 'asset'), + new ArgumentFuncCallToMethodCall('url', 'Illuminate\Contracts\Routing\UrlGenerator', 'to'), + new ArgumentFuncCallToMethodCall('action', 'Illuminate\Routing\UrlGenerator', 'action'), + new ArgumentFuncCallToMethodCall('trans', 'Illuminate\Translation\Translator', 'trans'), + new ArgumentFuncCallToMethodCall('trans_choice', 'Illuminate\Translation\Translator', 'transChoice'), + new ArgumentFuncCallToMethodCall('logger', 'Illuminate\Log\Writer', 'debug'), + new ArgumentFuncCallToMethodCall('back', 'Illuminate\Routing\Redirector', 'back', 'back'), + ]), + ArgumentFuncCallToMethodCallRector::ARRAY_FUNCTIONS_TO_METHOD_CALLS => inline_value_objects([ + new ArrayFuncCallToMethodCall('config', 'Illuminate\Contracts\Config\Repository', 'set', 'get'), + new ArrayFuncCallToMethodCall('session', 'Illuminate\Session\SessionManager', 'put', 'get'), + ]), + ]]); + $services->set(FuncCallToNewRector::class)->call('configure', [[ + FuncCallToNewRector::FUNCTION_TO_NEW => [ + 'collect' => 'Illuminate\Support\Collection', + ], + ]]); + $services->set(HelperFuncCallToFacadeClassRector::class); - $services->set(FuncCallToNewRector::class) + $services->set(RenameClassRector::class) ->call('configure', [[ - FuncCallToNewRector::FUNCTION_TO_NEW => [ - 'collect' => 'Illuminate\Support\Collection', + RenameClassRector::OLD_TO_NEW_CLASSES => [ + 'App' => 'Illuminate\Support\Facades\App', + 'Artisan' => 'Illuminate\Support\Facades\Artisan', + 'Auth' => 'Illuminate\Support\Facades\Auth', + 'Blade' => 'Illuminate\Support\Facades\Blade', + 'Broadcast' => 'Illuminate\Support\Facades\Broadcast', + 'Bus' => 'Illuminate\Support\Facades\Bus', + 'Cache' => 'Illuminate\Support\Facades\Cache', + 'Config' => 'Illuminate\Support\Facades\Config', + 'Cookie' => 'Illuminate\Support\Facades\Cookie', + 'Crypt' => 'Illuminate\Support\Facades\Crypt', + 'DB' => 'Illuminate\Support\Facades\DB', + 'Date' => 'Illuminate\Support\Facades\Date', + 'Event' => 'Illuminate\Support\Facades\Event', + 'Facade' => 'Illuminate\Support\Facades\Facade', + 'File' => 'Illuminate\Support\Facades\File', + 'Gate' => 'Illuminate\Support\Facades\Gate', + 'Hash' => 'Illuminate\Support\Facades\Hash', + 'Http' => 'Illuminate\Support\Facades\Http', + 'Lang' => 'Illuminate\Support\Facades\Lang', + 'Log' => 'Illuminate\Support\Facades\Log', + 'Mail' => 'Illuminate\Support\Facades\Mail', + 'Notification' => 'Illuminate\Support\Facades\Notification', + 'Password' => 'Illuminate\Support\Facades\Password', + 'Queue' => 'Illuminate\Support\Facades\Queue', + 'RateLimiter' => 'Illuminate\Support\Facades\RateLimiter', + 'Redirect' => 'Illuminate\Support\Facades\Redirect', + 'Redis' => 'Illuminate\Support\Facades\Redis', + 'Request' => 'Illuminate\Support\Facades\Request', + 'Response' => 'Illuminate\Support\Facades\Response', + 'Route' => 'Illuminate\Support\Facades\Route', + 'Schema' => 'Illuminate\Support\Facades\Schema', + 'Session' => 'Illuminate\Support\Facades\Session', + 'Storage' => 'Illuminate\Support\Facades\Storage', + 'URL' => 'Illuminate\Support\Facades\URL', + 'Validator' => 'Illuminate\Support\Facades\Validator', + 'View' => 'Illuminate\Support\Facades\View', ], ]]); }; diff --git a/docs/rector_rules_overview.md b/docs/rector_rules_overview.md index 6f7e9f4f452..ce91c791c34 100644 --- a/docs/rector_rules_overview.md +++ b/docs/rector_rules_overview.md @@ -6283,6 +6283,25 @@ return static function (ContainerConfigurator $containerConfigurator): void {
+## HelperFuncCallToFacadeClassRector + +Change `app()` func calls to facade calls + +- class: `Rector\Laravel\Rector\FuncCall\HelperFuncCallToFacadeClassRector` + +```diff + class SomeClass + { + public function run() + { +- return app('translator')->trans('value'); ++ return \Illuminate\Support\Facades\App::get('translator')->trans('value'); + } + } +``` + +
+ ## IfToSpaceshipRector Changes if/else to spaceship <=> where useful @@ -9440,7 +9459,7 @@ Changes pow(val, val2) to ** `(exp)` parameter ## PreferThisOrSelfMethodCallRector -Changes `$this->...` to self:: or vise versa for specific types +Changes `$this->...` and static:: to self:: or vise versa for given types :wrench: **configure it!** diff --git a/packages/post-rector/src/Rector/NameImportingPostRector.php b/packages/post-rector/src/Rector/NameImportingPostRector.php index 9da4f1175e5..cf1187787ad 100644 --- a/packages/post-rector/src/Rector/NameImportingPostRector.php +++ b/packages/post-rector/src/Rector/NameImportingPostRector.php @@ -17,11 +17,6 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; final class NameImportingPostRector extends AbstractPostRector { - /** - * @var bool - */ - private $importDocBlocks = false; - /** * @var ParameterProvider */ @@ -44,7 +39,6 @@ final class NameImportingPostRector extends AbstractPostRector ) { $this->parameterProvider = $parameterProvider; $this->nameImporter = $nameImporter; - $this->importDocBlocks = (bool) $parameterProvider->provideParameter(Option::IMPORT_DOC_BLOCKS); $this->docBlockNameImporter = $docBlockNameImporter; } @@ -59,7 +53,8 @@ final class NameImportingPostRector extends AbstractPostRector return $this->nameImporter->importName($node); } - if (! $this->importDocBlocks) { + $importDocBlocks = (bool) $this->parameterProvider->provideParameter(Option::IMPORT_DOC_BLOCKS); + if (! $importDocBlocks) { return null; } diff --git a/packages/post-rector/src/Rector/UseAddingPostRector.php b/packages/post-rector/src/Rector/UseAddingPostRector.php index e31561e4fb3..25d352cae46 100644 --- a/packages/post-rector/src/Rector/UseAddingPostRector.php +++ b/packages/post-rector/src/Rector/UseAddingPostRector.php @@ -11,6 +11,7 @@ use PhpParser\Node\Stmt\Namespace_; use Rector\CodingStyle\Application\UseImportsAdder; use Rector\CodingStyle\Application\UseImportsRemover; use Rector\Core\PhpParser\Node\BetterNodeFinder; +use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory; use Rector\PHPStan\Type\FullyQualifiedObjectType; @@ -101,6 +102,11 @@ final class UseAddingPostRector extends AbstractPostRector return $nodes; } + $firstNode = $nodes[0]; + if ($firstNode instanceof FileWithoutNamespace) { + $nodes = $firstNode->stmts; + } + // B. no namespace? add in the top // first clean $nodes = $this->useImportsRemover->removeImportsFromStmts($nodes, $removedShortUses); diff --git a/phpstan.neon b/phpstan.neon index cc4fc314f00..b558747cc00 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -733,3 +733,5 @@ parameters: paths: - packages/doctrine-annotation-generated/src/PhpDocNode/ConstantReferenceIdentifierRestorer.php # 61 - packages/doctrine-annotation-generated/src/PhpDocNode/ConstantReferenceIdentifierRestorer.php # 122 + + - '#Instanceof between PhpParser\\Node\\Stmt and Rector\\Core\\PhpParser\\Node\\CustomNode\\FileWithoutNamespace will always evaluate to false#' diff --git a/rules/coding-style/src/Application/UseImportsAdder.php b/rules/coding-style/src/Application/UseImportsAdder.php index e7a6fc01e2e..34897912b15 100644 --- a/rules/coding-style/src/Application/UseImportsAdder.php +++ b/rules/coding-style/src/Application/UseImportsAdder.php @@ -8,6 +8,7 @@ use Nette\Utils\Strings; use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Declare_; use PhpParser\Node\Stmt\Namespace_; +use PhpParser\Node\Stmt\Nop; use PhpParser\Node\Stmt\Use_; use PHPStan\Type\ObjectType; use Rector\CodingStyle\Imports\UsedImportsResolver; @@ -30,7 +31,7 @@ final class UseImportsAdder * @param Stmt[] $stmts * @param FullyQualifiedObjectType[] $useImportTypes * @param FullyQualifiedObjectType[] $functionUseImportTypes - * @return Stmt[] + * @return Stmt[] */ public function addImportsToStmts(array $stmts, array $useImportTypes, array $functionUseImportTypes): array { @@ -48,7 +49,8 @@ final class UseImportsAdder // place after declare strict_types foreach ($stmts as $key => $stmt) { if ($stmt instanceof Declare_) { - array_splice($stmts, $key + 1, 0, $newUses); + $nodesToAdd = array_merge([new Nop()], $newUses); + array_splice($stmts, $key + 1, 0, $nodesToAdd); return $stmts; } diff --git a/rules/coding-style/tests/Rector/Namespace_/ImportFullyQualifiedNamesRector/FixtureNonNamespaced/simple_with_strict_types.php.inc b/rules/coding-style/tests/Rector/Namespace_/ImportFullyQualifiedNamesRector/FixtureNonNamespaced/simple_with_strict_types.php.inc new file mode 100644 index 00000000000..95ee292bb66 --- /dev/null +++ b/rules/coding-style/tests/Rector/Namespace_/ImportFullyQualifiedNamesRector/FixtureNonNamespaced/simple_with_strict_types.php.inc @@ -0,0 +1,21 @@ + +----- + diff --git a/rules/laravel/src/Rector/FuncCall/HelperFuncCallToFacadeClassRector.php b/rules/laravel/src/Rector/FuncCall/HelperFuncCallToFacadeClassRector.php new file mode 100644 index 00000000000..cbb6a196b00 --- /dev/null +++ b/rules/laravel/src/Rector/FuncCall/HelperFuncCallToFacadeClassRector.php @@ -0,0 +1,72 @@ +trans('value'); + } +} +CODE_SAMPLE + + , + <<<'CODE_SAMPLE' +class SomeClass +{ + public function run() + { + return \Illuminate\Support\Facades\App::get('translator')->trans('value'); + } +} +CODE_SAMPLE + ), + ]); + } + + /** + * @return string[] + */ + public function getNodeTypes(): array + { + return [FuncCall::class]; + } + + /** + * @param FuncCall $node + */ + public function refactor(Node $node): ?Node + { + if (! $this->isName($node->name, 'app')) { + return null; + } + + if (count((array) $node->args) !== 1) { + return null; + } + + return $this->createStaticCall('Illuminate\Support\Facades\App', 'get', (array) $node->args); + } +} diff --git a/rules/laravel/tests/Rector/FuncCall/HelperFuncCallToFacadeClassRector/Fixture/fixture.php.inc b/rules/laravel/tests/Rector/FuncCall/HelperFuncCallToFacadeClassRector/Fixture/fixture.php.inc new file mode 100644 index 00000000000..1ff62cffda1 --- /dev/null +++ b/rules/laravel/tests/Rector/FuncCall/HelperFuncCallToFacadeClassRector/Fixture/fixture.php.inc @@ -0,0 +1,27 @@ +trans('value'); + } +} + +?> +----- +trans('value'); + } +} + +?> diff --git a/rules/laravel/tests/Rector/FuncCall/HelperFuncCallToFacadeClassRector/Fixture/skip_with_args.php.inc b/rules/laravel/tests/Rector/FuncCall/HelperFuncCallToFacadeClassRector/Fixture/skip_with_args.php.inc new file mode 100644 index 00000000000..98cf14bbdbd --- /dev/null +++ b/rules/laravel/tests/Rector/FuncCall/HelperFuncCallToFacadeClassRector/Fixture/skip_with_args.php.inc @@ -0,0 +1,11 @@ +doTestFileInfo($fileInfo); + } + + public function provideData(): Iterator + { + return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + protected function getRectorClass(): string + { + return HelperFuncCallToFacadeClassRector::class; + } +}