From 4b0cf31a82b11f6708b695063f4cac1dbe7455d1 Mon Sep 17 00:00:00 2001 From: Zing Date: Fri, 1 Oct 2021 15:26:18 +0800 Subject: [PATCH] Add AnonymousMigrationsRector (#17) * Add AnonymousMigrationsRector * Add reference link * Re-trigger github action * Re-Generate Rules Documentation --- docs/rector_rules_overview.md | 236 +++++++++++++++--- .../Class_/AnonymousMigrationsRector.php | 85 +++++++ .../Database/Migrations/Migration.php | 11 + .../AnonymousMigrationsRectorTest.php | 33 +++ .../Fixture/fixture.php.inc | 25 ++ .../Fixture/skip_anonymous_migration.php.inc | 10 + .../config/configured_rule.php | 13 + 7 files changed, 384 insertions(+), 29 deletions(-) create mode 100644 src/Rector/Class_/AnonymousMigrationsRector.php create mode 100644 stubs/Illuminate/Database/Migrations/Migration.php create mode 100644 tests/Rector/Class_/AnonymousMigrationsRector/AnonymousMigrationsRectorTest.php create mode 100644 tests/Rector/Class_/AnonymousMigrationsRector/Fixture/fixture.php.inc create mode 100644 tests/Rector/Class_/AnonymousMigrationsRector/Fixture/skip_anonymous_migration.php.inc create mode 100644 tests/Rector/Class_/AnonymousMigrationsRector/config/configured_rule.php diff --git a/docs/rector_rules_overview.md b/docs/rector_rules_overview.md index be8f2fb5..173cd947 100644 --- a/docs/rector_rules_overview.md +++ b/docs/rector_rules_overview.md @@ -1,4 +1,44 @@ -# 11 Rules Overview +# 19 Rules Overview + +## AddArgumentDefaultValueRector + +Adds default value for arguments in defined methods. + +:wrench: **configure it!** + +- class: [`Rector\Laravel\Rector\ClassMethod\AddArgumentDefaultValueRector`](../src/Rector/ClassMethod/AddArgumentDefaultValueRector.php) + +```php +use Rector\Laravel\Rector\ClassMethod\AddArgumentDefaultValueRector; +use Rector\Laravel\ValueObject\AddArgumentDefaultValue; +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +use Symplify\SymfonyPhpConfig\ValueObjectInliner; + +return static function (ContainerConfigurator $containerConfigurator): void { + $services = $containerConfigurator->services(); + + $services->set(AddArgumentDefaultValueRector::class) + ->call('configure', [[ + AddArgumentDefaultValueRector::ADDED_ARGUMENTS => ValueObjectInliner::inline([ + new AddArgumentDefaultValue('SomeClass', 'someMethod', 0, false), + ]), + ]]); +}; +``` + +↓ + +```diff + class SomeClass + { +- public function someMethod($value) ++ public function someMethod($value = false) + { + } + } +``` + +
## AddGuardToLoginEventRector @@ -70,6 +110,45 @@ Add `parent::boot();` call to `boot()` class method in child of `Illuminate\Data
+## AddParentRegisterToEventServiceProviderRector + +Add `parent::register();` call to `register()` class method in child of `Illuminate\Foundation\Support\Providers\EventServiceProvider` + +- class: [`Rector\Laravel\Rector\ClassMethod\AddParentRegisterToEventServiceProviderRector`](../src/Rector/ClassMethod/AddParentRegisterToEventServiceProviderRector.php) + +```diff + use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; + + class EventServiceProvider extends ServiceProvider + { + public function register() + { ++ parent::register(); + } + } +``` + +
+ +## AnonymousMigrationsRector + +Convert migrations to anonymous classes. + +- class: [`Rector\Laravel\Rector\Class_\AnonymousMigrationsRector`](../src/Rector/Class_/AnonymousMigrationsRector.php) + +```diff + use Illuminate\Database\Migrations\Migration; + +-class CreateUsersTable extends Migration ++return new class extends Migration + { + // ... +-} ++}; +``` + +
+ ## CallOnAppArrayAccessToStandaloneAssignRector Replace magical call on `$this->app["something"]` to standalone type assign variable @@ -119,51 +198,77 @@ Add `parent::boot();` call to `boot()` class method in child of `Illuminate\Data
-## HelperFuncCallToFacadeClassRector +## FactoryApplyingStatesRector -Change `app()` func calls to facade calls +Call the state methods directly instead of specify the name of state. -- class: [`Rector\Laravel\Rector\FuncCall\HelperFuncCallToFacadeClassRector`](../src/Rector/FuncCall/HelperFuncCallToFacadeClassRector.php) +- class: [`Rector\Laravel\Rector\MethodCall\FactoryApplyingStatesRector`](../src/Rector/MethodCall/FactoryApplyingStatesRector.php) ```diff - class SomeClass - { - public function run() - { -- return app('translator')->trans('value'); -+ return \Illuminate\Support\Facades\App::get('translator')->trans('value'); - } - } +-$factory->state('delinquent'); +-$factory->states('premium', 'delinquent'); ++$factory->delinquent(); ++$factory->premium()->delinquent(); ```
-## MakeTaggedPassedToParameterIterableTypeRector +## FactoryDefinitionRector -Change param type to iterable, if passed one +Upgrade legacy factories to support classes. -- class: [`Rector\Laravel\Rector\New_\MakeTaggedPassedToParameterIterableTypeRector`](../src/Rector/New_/MakeTaggedPassedToParameterIterableTypeRector.php) +- class: [`Rector\Laravel\Rector\Namespace_\FactoryDefinitionRector`](../src/Rector/Namespace_/FactoryDefinitionRector.php) ```diff - class AnotherClass - { - /** - * @var \Illuminate\Contracts\Foundation\Application - */ - private $app; + use Faker\Generator as Faker; + +-$factory->define(App\User::class, function (Faker $faker) { +- return [ +- 'name' => $faker->name, +- 'email' => $faker->unique()->safeEmail, +- ]; +-}); ++class UserFactory extends \Illuminate\Database\Eloquent\Factories\Factory ++{ ++ protected $model = App\User::class; ++ public function definition() ++ { ++ return [ ++ 'name' => $this->faker->name, ++ 'email' => $this->faker->unique()->safeEmail, ++ ]; ++ } ++} +``` - public function create() - { - $tagged = $this->app->tagged('some_tagged'); - return new SomeClass($tagged); - } - } +
+ +## FactoryFuncCallToStaticCallRector + +Use the static factory method instead of global factory function. +- class: [`Rector\Laravel\Rector\FuncCall\FactoryFuncCallToStaticCallRector`](../src/Rector/FuncCall/FactoryFuncCallToStaticCallRector.php) + +```diff +-factory(User::class); ++User::factory(); +``` + +
+ +## HelperFuncCallToFacadeClassRector + +Change `app()` func calls to facade calls + +- class: [`Rector\Laravel\Rector\FuncCall\HelperFuncCallToFacadeClassRector`](../src/Rector/FuncCall/HelperFuncCallToFacadeClassRector.php) + +```diff class SomeClass { -- public function __construct(array $items) -+ public function __construct(iterable $items) + public function run() { +- return app('translator')->trans('value'); ++ return \Illuminate\Support\Facades\App::get('translator')->trans('value'); } } ``` @@ -230,6 +335,26 @@ Change "redirect" call with 301 to "permanentRedirect"
+## RemoveAllOnDispatchingMethodsWithJobChainingRector + +Remove `allOnQueue()` and `allOnConnection()` methods used with job chaining, use the `onQueue()` and `onConnection()` methods instead. + +- class: [`Rector\Laravel\Rector\MethodCall\RemoveAllOnDispatchingMethodsWithJobChainingRector`](../src/Rector/MethodCall/RemoveAllOnDispatchingMethodsWithJobChainingRector.php) + +```diff + Job::withChain([ + new ChainJob(), + ]) +- ->dispatch() +- ->allOnConnection('redis') +- ->allOnQueue('podcasts'); ++ ->onQueue('podcasts') ++ ->onConnection('redis') ++ ->dispatch(); +``` + +
+ ## RequestStaticValidateToInjectRector Change static `validate()` method to `$request->validate()` @@ -251,3 +376,56 @@ Change static `validate()` method to `$request->validate()` ```
+ +## RouteActionCallableRector + +Use PHP callable syntax instead of string syntax for controller route declarations. + +:wrench: **configure it!** + +- class: [`Rector\Laravel\Rector\StaticCall\RouteActionCallableRector`](../src/Rector/StaticCall/RouteActionCallableRector.php) + +```php +use Rector\Laravel\Rector\StaticCall\RouteActionCallableRector; +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; + +return static function (ContainerConfigurator $containerConfigurator): void { + $services = $containerConfigurator->services(); + + $services->set(RouteActionCallableRector::class) + ->call('configure', [[ + RouteActionCallableRector::NAMESPACE => 'App\Http\Controllers', + ]]); +}; +``` + +↓ + +```diff +-Route::get('/users', 'UserController@index'); ++Route::get('/users', [\App\Http\Controllers\UserController::class, 'index']); +``` + +
+ +## UnifyModelDatesWithCastsRector + +Unify Model `$dates` property with `$casts` + +- class: [`Rector\Laravel\Rector\Class_\UnifyModelDatesWithCastsRector`](../src/Rector/Class_/UnifyModelDatesWithCastsRector.php) + +```diff + use Illuminate\Database\Eloquent\Model; + + class Person extends Model + { + protected $casts = [ +- 'age' => 'integer', ++ 'age' => 'integer', 'birthday' => 'datetime', + ]; +- +- protected $dates = ['birthday']; + } +``` + +
diff --git a/src/Rector/Class_/AnonymousMigrationsRector.php b/src/Rector/Class_/AnonymousMigrationsRector.php new file mode 100644 index 00000000..dffb1a19 --- /dev/null +++ b/src/Rector/Class_/AnonymousMigrationsRector.php @@ -0,0 +1,85 @@ +> + */ + public function getNodeTypes(): array + { + return [Class_::class]; + } + + /** + * @param Class_ $node + */ + public function refactor(Node $node): ?Node + { + if (! $this->isObjectType($node, new ObjectType('Illuminate\Database\Migrations\Migration'))) { + return null; + } + + if ($this->classAnalyzer->isAnonymousClass($node)) { + return null; + } + + return new Return_(new New_(new Class_(null, [ + 'flags' => $node->flags, + 'extends' => $node->extends, + 'implements' => $node->implements, + 'stmts' => $node->stmts, + 'attrGroups' => $node->attrGroups, + ]))); + } +} diff --git a/stubs/Illuminate/Database/Migrations/Migration.php b/stubs/Illuminate/Database/Migrations/Migration.php new file mode 100644 index 00000000..e706854b --- /dev/null +++ b/stubs/Illuminate/Database/Migrations/Migration.php @@ -0,0 +1,11 @@ +doTestFileInfo($fileInfo); + } + + /** + * @return Iterator + */ + public function provideData(): Iterator + { + return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/tests/Rector/Class_/AnonymousMigrationsRector/Fixture/fixture.php.inc b/tests/Rector/Class_/AnonymousMigrationsRector/Fixture/fixture.php.inc new file mode 100644 index 00000000..f41248d6 --- /dev/null +++ b/tests/Rector/Class_/AnonymousMigrationsRector/Fixture/fixture.php.inc @@ -0,0 +1,25 @@ + +----- + diff --git a/tests/Rector/Class_/AnonymousMigrationsRector/Fixture/skip_anonymous_migration.php.inc b/tests/Rector/Class_/AnonymousMigrationsRector/Fixture/skip_anonymous_migration.php.inc new file mode 100644 index 00000000..aa98e4bf --- /dev/null +++ b/tests/Rector/Class_/AnonymousMigrationsRector/Fixture/skip_anonymous_migration.php.inc @@ -0,0 +1,10 @@ +import(__DIR__ . '/../../../../../config/config.php'); + + $services = $containerConfigurator->services(); + $services->set(AnonymousMigrationsRector::class); +};