mirror of
https://github.com/rectorphp/rector.git
synced 2024-09-06 15:41:59 +00:00
[Laravel] Add HelperFunctionToConstructorInjectionRector
This commit is contained in:
parent
8bf7bfb12f
commit
b22d8921d7
@ -5,6 +5,7 @@ imports:
|
||||
services:
|
||||
Rector\Laravel\Rector\StaticCall\FacadeStaticCallToConstructorInjectionRector: ~
|
||||
Rector\Laravel\Rector\StaticCall\RequestStaticValidateToInjectRector: ~
|
||||
Rector\Laravel\Rector\FuncCall\HelperFunctionToConstructorInjectionRector: ~
|
||||
|
||||
Rector\Rector\FuncCall\FunctionToNewRector:
|
||||
collect: 'Illuminate\Support\Collection'
|
||||
|
1
ecs.yml
1
ecs.yml
@ -104,6 +104,7 @@ parameters:
|
||||
- 'packages/ContributorTools/src/Command/DumpNodesCommand.php'
|
||||
- 'packages/CodeQuality/src/Rector/Identical/SimplifyBoolIdenticalTrueRector.php'
|
||||
- 'packages/BetterPhpDocParser/src/Attributes/Ast/AttributeAwareNodeFactory.php'
|
||||
- 'packages/Laravel/src/Rector/FuncCall/HelperFunctionToConstructorInjectionRector.php'
|
||||
|
||||
# copied 3rd party logic
|
||||
- 'packages/Php/src/EregToPcreTransformer.php'
|
||||
|
@ -0,0 +1,254 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Laravel\Rector\FuncCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Exception\ShouldNotHappenException;
|
||||
use Rector\NodeTypeResolver\Node\Attribute;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
|
||||
/**
|
||||
* @see https://github.com/laravel/framework/blob/78828bc779e410e03cc6465f002b834eadf160d2/src/Illuminate/Foundation/helpers.php#L959
|
||||
* @see https://gist.github.com/barryvdh/bb6ffc5d11e0a75dba67
|
||||
*/
|
||||
final class HelperFunctionToConstructorInjectionRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var string[][]
|
||||
*/
|
||||
private $functionToService = [
|
||||
// set/get
|
||||
'config' => [
|
||||
'type' => 'Illuminate\Contracts\Config\Repository',
|
||||
'array_method' => 'set',
|
||||
'non_array_method' => 'get',
|
||||
],
|
||||
'session' => [
|
||||
'type' => 'Illuminate\Session\SessionManager',
|
||||
'property' => 'sessionManager',
|
||||
'array_method' => 'put',
|
||||
'non_array_method' => 'get',
|
||||
],
|
||||
|
||||
// methods if args/property fetch
|
||||
'policy' => [
|
||||
'type' => 'Illuminate\Contracts\Auth\Access\Gate',
|
||||
'property' => 'policy',
|
||||
'method_if_args' => 'getPolicyFor',
|
||||
],
|
||||
'cookie' => [
|
||||
'type' => 'Illuminate\Contracts\Cookie\Factory',
|
||||
'property' => 'cookieFactory',
|
||||
'method_if_args' => 'make',
|
||||
],
|
||||
// router
|
||||
'put' => [
|
||||
'type' => 'Illuminate\Routing\Router',
|
||||
'property' => 'router',
|
||||
'method_if_args' => 'put',
|
||||
],
|
||||
'get' => [
|
||||
'type' => 'Illuminate\Routing\Router',
|
||||
'property' => 'router',
|
||||
'method_if_args' => 'get',
|
||||
],
|
||||
'post' => [
|
||||
'type' => 'Illuminate\Routing\Router',
|
||||
'property' => 'router',
|
||||
'method_if_args' => 'post',
|
||||
],
|
||||
'patch' => [
|
||||
'type' => 'Illuminate\Routing\Router',
|
||||
'property' => 'router',
|
||||
'method_if_args' => 'patch',
|
||||
],
|
||||
'delete' => [
|
||||
'type' => 'Illuminate\Routing\Router',
|
||||
'property' => 'router',
|
||||
'method_if_args' => 'delete',
|
||||
],
|
||||
'resource' => [
|
||||
'type' => 'Illuminate\Routing\Router',
|
||||
'property' => 'router',
|
||||
'method_if_args' => 'resource',
|
||||
],
|
||||
'response' => [
|
||||
'type' => 'Illuminate\Contracts\Routing\ResponseFactory',
|
||||
'property' => 'responseFactory',
|
||||
'method_if_args' => 'make',
|
||||
],
|
||||
|
||||
'info' => [
|
||||
'type' => 'Illuminate\Log\Writer',
|
||||
'property' => 'logWriter',
|
||||
'method_if_args' => 'info',
|
||||
],
|
||||
'view' => [
|
||||
'type' => 'Illuminate\Contracts\View\Factory',
|
||||
'property' => 'viewFactory',
|
||||
'method_if_args' => 'make',
|
||||
],
|
||||
'bcrypt' => [
|
||||
'type' => 'Illuminate\Hashing\BcryptHasher',
|
||||
'property' => 'bcryptHasher',
|
||||
'method_if_args' => 'make',
|
||||
],
|
||||
'redirect' => [
|
||||
'type' => 'Illuminate\Routing\Redirector',
|
||||
'property' => 'redirector',
|
||||
'method_if_args' => 'back',
|
||||
],
|
||||
'back' => [
|
||||
'type' => 'Illuminate\Routing\Redirector',
|
||||
'property' => 'redirector',
|
||||
'method_if_args' => 'back',
|
||||
],
|
||||
'broadcast' => [
|
||||
'type' => 'Illuminate\Contracts\Broadcasting\Factory',
|
||||
'property' => 'broadcastFactory',
|
||||
'method_if_args' => 'event',
|
||||
],
|
||||
'event' => [
|
||||
'type' => 'Illuminate\Events\Dispatcher',
|
||||
'property' => 'eventDispatcher',
|
||||
'method_if_args' => 'fire',
|
||||
],
|
||||
'dispatch' => [
|
||||
'type' => 'Illuminate\Events\Dispatcher',
|
||||
'property' => 'eventDispatcher',
|
||||
'method_if_args' => 'dispatch',
|
||||
],
|
||||
'route' => [
|
||||
'type' => 'Illuminate\Routing\UrlGenerator',
|
||||
'property' => 'urlGenerator',
|
||||
'method_if_args' => 'route',
|
||||
],
|
||||
'auth' => [
|
||||
'type' => 'Illuminate\Contracts\Auth\Guard',
|
||||
'property' => 'guard',
|
||||
],
|
||||
'asset' => [
|
||||
'type' => 'Illuminate\Routing\UrlGenerator',
|
||||
'property' => 'urlGenerator',
|
||||
'method_if_args' => 'asset',
|
||||
],
|
||||
'url' => [
|
||||
'type' => 'Illuminate\Contracts\Routing\UrlGenerator',
|
||||
'property' => 'urlGenerator',
|
||||
'method_if_args' => 'to',
|
||||
],
|
||||
'action' => [
|
||||
'type' => 'Illuminate\Routing\UrlGenerator',
|
||||
'property' => 'urlGenerator',
|
||||
'method_if_args' => 'action',
|
||||
],
|
||||
'trans' => [
|
||||
'type' => 'Illuminate\Translation\Translator',
|
||||
'property' => 'translator',
|
||||
'method_if_args' => 'trans',
|
||||
],
|
||||
'trans_choice' => [
|
||||
'type' => 'Illuminate\Translation\Translator',
|
||||
'property' => 'translator',
|
||||
'method_if_args' => 'transChoice',
|
||||
],
|
||||
'logger' => [
|
||||
'type' => 'Illuminate\Log\Writer',
|
||||
'property' => 'logWriter',
|
||||
'method_if_args' => 'debug',
|
||||
],
|
||||
];
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Move help facade-like function calls to constructor injection', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeController
|
||||
{
|
||||
public function action()
|
||||
{
|
||||
$template = view('template.blade');
|
||||
$viewFactory = view();
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeController
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
private $viewFactory;
|
||||
|
||||
public function __construct(\Illuminate\Contracts\View\Factory $viewFactory)
|
||||
{
|
||||
$this->viewFactory = $viewFactory;
|
||||
}
|
||||
|
||||
public function action()
|
||||
{
|
||||
$template = $this->viewFactory->make('template.blade');
|
||||
$viewFactory = $this->viewFactory;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [FuncCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FuncCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
// we can inject only in class context
|
||||
$classNode = $node->getAttribute(Attribute::CLASS_NODE);
|
||||
if (! $classNode instanceof Class_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($this->functionToService as $function => $service) {
|
||||
if (! $this->isName($node, $function)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->addPropertyToClass($classNode, $service['type'], $service['property']);
|
||||
$propertyFetchNode = $this->createPropertyFetch('this', $service['property']);
|
||||
|
||||
if (count($node->args) === 0) {
|
||||
return $propertyFetchNode;
|
||||
}
|
||||
|
||||
if (isset($service['method_if_args']) && count($node->args) >= 1) {
|
||||
return new MethodCall($propertyFetchNode, $service['method_if_args'], $node->args);
|
||||
}
|
||||
|
||||
if (isset($service['array_method']) && $this->isArrayType($node->args[0]->value)) {
|
||||
return new MethodCall($propertyFetchNode, $service['array_method'], $node->args);
|
||||
}
|
||||
|
||||
if (isset($service['non_array_method']) && ! $this->isArrayType($node->args[0]->value)) {
|
||||
return new MethodCall($propertyFetchNode, $service['non_array_method'], $node->args);
|
||||
}
|
||||
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Laravel\Tests\Rector\FuncCall\HelperFunctionToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SomeBackController
|
||||
{
|
||||
public function action()
|
||||
{
|
||||
return back('template.blade');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Laravel\Tests\Rector\FuncCall\HelperFunctionToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SomeBackController
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Routing\UrlGenerator
|
||||
*/
|
||||
private $urlGenerator;
|
||||
public function __construct(\Illuminate\Routing\UrlGenerator $urlGenerator)
|
||||
{
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
}
|
||||
public function action()
|
||||
{
|
||||
return $this->urlGenerator->route('template.blade');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Laravel\Tests\Rector\FuncCall\HelperFunctionToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SomeBroadcastController
|
||||
{
|
||||
public function action()
|
||||
{
|
||||
return broadcast('template.blade');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Laravel\Tests\Rector\FuncCall\HelperFunctionToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SomeBroadcastController
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Broadcasting\Factory
|
||||
*/
|
||||
private $broadcastFactory;
|
||||
public function __construct(\Illuminate\Contracts\Broadcasting\Factory $broadcastFactory)
|
||||
{
|
||||
$this->broadcastFactory = $broadcastFactory;
|
||||
}
|
||||
public function action()
|
||||
{
|
||||
return $this->broadcastFactory->event('template.blade');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Laravel\Tests\Rector\FuncCall\HelperFunctionToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SomeRouteController
|
||||
{
|
||||
public function action()
|
||||
{
|
||||
return route('template.blade');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Laravel\Tests\Rector\FuncCall\HelperFunctionToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SomeRouteController
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Routing\UrlGenerator
|
||||
*/
|
||||
private $urlGenerator;
|
||||
public function __construct(\Illuminate\Routing\UrlGenerator $urlGenerator)
|
||||
{
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
}
|
||||
public function action()
|
||||
{
|
||||
return $this->urlGenerator->route('template.blade');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Laravel\Tests\Rector\FuncCall\HelperFunctionToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SomeSessionController
|
||||
{
|
||||
public function action()
|
||||
{
|
||||
$session = session();
|
||||
session(['key']);
|
||||
session('key', 'value');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Laravel\Tests\Rector\FuncCall\HelperFunctionToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SomeSessionController
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Session\SessionManager
|
||||
*/
|
||||
private $sessionManager;
|
||||
public function __construct(\Illuminate\Session\SessionManager $sessionManager)
|
||||
{
|
||||
$this->sessionManager = $sessionManager;
|
||||
}
|
||||
public function action()
|
||||
{
|
||||
$session = $this->sessionManager;
|
||||
$this->sessionManager->put(['key']);
|
||||
$this->sessionManager->get('key', 'value');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Laravel\Tests\Rector\FuncCall\HelperFunctionToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SomeViewController
|
||||
{
|
||||
public function action()
|
||||
{
|
||||
$template = view('template.blade');
|
||||
$viewFactory = view();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Laravel\Tests\Rector\FuncCall\HelperFunctionToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SomeViewController
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
private $viewFactory;
|
||||
public function __construct(\Illuminate\Contracts\View\Factory $viewFactory)
|
||||
{
|
||||
$this->viewFactory = $viewFactory;
|
||||
}
|
||||
public function action()
|
||||
{
|
||||
$template = $this->viewFactory->make('template.blade');
|
||||
$viewFactory = $this->viewFactory;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,24 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Laravel\Tests\Rector\FuncCall\HelperFunctionToConstructorInjectionRector;
|
||||
|
||||
use Rector\Laravel\Rector\FuncCall\HelperFunctionToConstructorInjectionRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
|
||||
final class HelperFunctionToConstructorInjectionRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
public function test(): void
|
||||
{
|
||||
$this->doTestFiles([
|
||||
__DIR__ . '/Fixture/view.php.inc',
|
||||
__DIR__ . '/Fixture/broadcast.php.inc',
|
||||
__DIR__ . '/Fixture/session.php.inc',
|
||||
__DIR__ . '/Fixture/route.php.inc',
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return HelperFunctionToConstructorInjectionRector::class;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user