mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-04 02:10:51 +00:00
migrate to ServiceNameToTypeProvider that better maches use case
This commit is contained in:
parent
b749d3f5e1
commit
0b86554364
|
@ -9,36 +9,38 @@ rectors:
|
|||
Rector\Rector\Contrib\Nette\Environment\GetServiceToConstructorInjectionRector: ~
|
||||
```
|
||||
|
||||
requires `Rector\Contract\Bridge\ServiceNameToTypeProviderInterface` service that provides **service type for certain service name**.
|
||||
requires `Rector\Contract\Bridge\ServiceTypeForNameProviderInterface` service that provides **service type for certain service name**.
|
||||
|
||||
|
||||
**Why Interface?**
|
||||
**Why Should You Implement the Interface?**
|
||||
|
||||
This operation could be automated to some level, but Kernel and Container API vary over time, so the implementation is left up to you and your specific case. This allows any framework and container to use these rectors and gives you freedom to provide own types.
|
||||
This operation could be automated on some level, but Kernel and Container API vary too much over frameworks and their versions. The implementation is left up to you and your specific case. **This allows any framework and container to use these rectors and gives you freedom to provide own desired types if needed**.
|
||||
|
||||
|
||||
## How to Add it?
|
||||
|
||||
1. Implement `Rector\Contract\Bridge\ServiceNameToTypeProviderInterface`
|
||||
1. Implement `Rector\Contract\Bridge\ServiceTypeForNameProviderInterface`
|
||||
2. And add *name* to *type* map.
|
||||
|
||||
**Static implementation** would look like this:
|
||||
|
||||
```yaml
|
||||
```php
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
use Rector\Contract\Bridge\ServiceNameToTypeProviderInterface;
|
||||
use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
|
||||
|
||||
final class StaticProvidero implements ServiceNameToTypeProviderInterface
|
||||
final class StaticProvidero implements ServiceTypeForNameProviderInterface
|
||||
{
|
||||
/**
|
||||
* @return string[]
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
public function provide(): array
|
||||
private $nameToTypeMap = [
|
||||
'eventDispatcher' => 'Symfony\Component\EventDispatcher\EventDispatcherInterface',
|
||||
];
|
||||
|
||||
public function provideTypeForName(string $name): ?string
|
||||
{
|
||||
return [
|
||||
'eventDispatcher' => 'Symfony\Component\EventDispatcher\EventDispatcherInterface',
|
||||
];
|
||||
return $this->nameToTypeMap[$name] ?? null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -50,7 +52,7 @@ This operation could be automated to some level, but Kernel and Container API va
|
|||
StaticProvider: ~
|
||||
|
||||
# this allows autowiring via interface
|
||||
Rector\Contract\Bridge\ServiceNameToTypeProviderInterface:
|
||||
Rector\Contract\Bridge\ServiceTypeForNameProviderInterface:
|
||||
alias: StaticProvider
|
||||
```
|
||||
|
||||
|
@ -65,36 +67,35 @@ Of couse we have some prepared examples for Kernel, don't you worry.
|
|||
|
||||
```php
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Rector\Contract\Bridge\ServiceNameToTypeProviderInterface;
|
||||
use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
|
||||
use Symfony\Component\HttpKernel\Kernel;
|
||||
|
||||
final class AppKernelProvider implements ServiceNameToTypeProviderInterface
|
||||
final class AppKernelProvider implements ServiceTypeForNameProviderInterface
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
private $container;
|
||||
|
||||
// @todo: modify API so it matches
|
||||
|
||||
// https://github.com/RectorPHP/Rector/pull/86/commits/0e375e713b3fea3a990762d5f117a019d317e67e#diff-4f9e06675af869311a8729c450e01d2eL26
|
||||
|
||||
public function getTypeForName(string $name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function provide(): array
|
||||
public function provideTypeForName(string $name): ?string
|
||||
{
|
||||
}
|
||||
|
||||
private function getContainer(): ContainerInterface
|
||||
{
|
||||
// @todo: cache it
|
||||
if ($this->container) {
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
/** @var Kernel $kernel */
|
||||
$kernel = new $kernelClass('rector_dev', true);
|
||||
$kernel->boot();
|
||||
|
||||
return $kernel->getContainer();
|
||||
return $this->container = $kernel->getContainer();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Contract\Bridge;
|
||||
|
||||
interface ServiceNameToTypeProviderInterface
|
||||
{
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function provide(): array;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Contract\Bridge;
|
||||
|
||||
interface ServiceTypeForNameProviderInterface
|
||||
{
|
||||
public function provideTypeForName(string $name): ?string;
|
||||
}
|
|
@ -6,7 +6,7 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Expr\MethodCall;
|
||||
use Rector\Builder\Class_\ClassPropertyCollector;
|
||||
use Rector\Builder\Naming\NameResolver;
|
||||
use Rector\Contract\Bridge\ServiceNameToTypeProviderInterface;
|
||||
use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
|
||||
use Rector\Node\Attribute;
|
||||
use Rector\NodeAnalyzer\MethodCallAnalyzer;
|
||||
use Rector\NodeFactory\NodeFactory;
|
||||
|
@ -42,25 +42,22 @@ final class GetServiceToConstructorInjectionRector extends AbstractRector
|
|||
private $methodCallAnalyzer;
|
||||
|
||||
/**
|
||||
* @var ServiceNameToTypeProviderInterface
|
||||
* @var ServiceTypeForNameProviderInterface
|
||||
*/
|
||||
private $serviceNameToTypeProvider;
|
||||
|
||||
// @todo: service to type map - any manuall implementation works, use interface
|
||||
// and register to rector.yml
|
||||
private $serviceTypeForNameProvider;
|
||||
|
||||
public function __construct(
|
||||
NameResolver $nameResolver,
|
||||
ClassPropertyCollector $classPropertyCollector,
|
||||
NodeFactory $nodeFactory,
|
||||
MethodCallAnalyzer $methodCallAnalyzer,
|
||||
ServiceNameToTypeProviderInterface $serviceNameToTypeProvider
|
||||
ServiceTypeForNameProviderInterface $serviceTypeForNameProvider
|
||||
) {
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->classPropertyCollector = $classPropertyCollector;
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
$this->methodCallAnalyzer = $methodCallAnalyzer;
|
||||
$this->serviceNameToTypeProvider = $serviceNameToTypeProvider;
|
||||
$this->serviceTypeForNameProvider = $serviceTypeForNameProvider;
|
||||
}
|
||||
|
||||
public function isCandidate(Node $node): bool
|
||||
|
@ -75,13 +72,11 @@ final class GetServiceToConstructorInjectionRector extends AbstractRector
|
|||
{
|
||||
$serviceName = $methodCallNode->args[0]->value->value;
|
||||
|
||||
$serviceToTypeMap = $this->serviceNameToTypeProvider->provide();
|
||||
if (! isset($serviceToTypeMap[$serviceName])) {
|
||||
$serviceType = $this->serviceTypeForNameProvider->provideTypeForName($serviceName);
|
||||
if ($serviceType === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$serviceType = $serviceToTypeMap[$serviceName];
|
||||
|
||||
$propertyName = $this->nameResolver->resolvePropertyNameFromType($serviceType);
|
||||
|
||||
$this->classPropertyCollector->addPropertyForClass(
|
||||
|
|
|
@ -8,7 +8,7 @@ use PhpParser\Node\Expr\MethodCall;
|
|||
use PhpParser\Node\Name\FullyQualified;
|
||||
use Rector\Builder\Class_\ClassPropertyCollector;
|
||||
use Rector\Builder\Naming\NameResolver;
|
||||
use Rector\Contract\Bridge\ServiceNameToTypeProviderInterface;
|
||||
use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
|
||||
use Rector\Node\Attribute;
|
||||
use Rector\NodeAnalyzer\SymfonyContainerCallsAnalyzer;
|
||||
use Rector\NodeFactory\NodeFactory;
|
||||
|
@ -62,22 +62,22 @@ final class CommandToConstructorInjectionRector extends AbstractRector
|
|||
private $symfonyContainerCallsAnalyzer;
|
||||
|
||||
/**
|
||||
* @var ServiceNameToTypeProviderInterface
|
||||
* @var ServiceTypeForNameProviderInterface
|
||||
*/
|
||||
private $serviceNameToTypeProvider;
|
||||
private $serviceTypeForNameProvider;
|
||||
|
||||
public function __construct(
|
||||
ClassPropertyCollector $classPropertyCollector,
|
||||
NameResolver $nameResolver,
|
||||
NodeFactory $nodeFactory,
|
||||
ServiceNameToTypeProviderInterface $serviceNameToTypeProvider,
|
||||
SymfonyContainerCallsAnalyzer $symfonyContainerCallsAnalyzer
|
||||
SymfonyContainerCallsAnalyzer $symfonyContainerCallsAnalyzer,
|
||||
ServiceTypeForNameProviderInterface $serviceTypeForNameProvider
|
||||
) {
|
||||
$this->classPropertyCollector = $classPropertyCollector;
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
$this->serviceNameToTypeProvider = $serviceNameToTypeProvider;
|
||||
$this->symfonyContainerCallsAnalyzer = $symfonyContainerCallsAnalyzer;
|
||||
$this->serviceTypeForNameProvider = $serviceTypeForNameProvider;
|
||||
}
|
||||
|
||||
public function isCandidate(Node $node): bool
|
||||
|
@ -103,15 +103,11 @@ final class CommandToConstructorInjectionRector extends AbstractRector
|
|||
$this->replaceParentContainerAwareCommandWithCommand($methodCallNode);
|
||||
|
||||
$serviceName = $methodCallNode->args[0]->value->value;
|
||||
|
||||
$serviceNameToTypeMap = $this->serviceNameToTypeProvider->provide();
|
||||
|
||||
if (! isset($serviceNameToTypeMap[$serviceName])) {
|
||||
$serviceType = $this->serviceTypeForNameProvider->provideTypeForName($serviceName);
|
||||
if ($serviceType === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$serviceType = $serviceNameToTypeMap[$serviceName];
|
||||
|
||||
$propertyName = $this->nameResolver->resolvePropertyNameFromType($serviceType);
|
||||
|
||||
$this->classPropertyCollector->addPropertyForClass(
|
||||
|
|
|
@ -6,7 +6,7 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Expr\MethodCall;
|
||||
use Rector\Builder\Class_\ClassPropertyCollector;
|
||||
use Rector\Builder\Naming\NameResolver;
|
||||
use Rector\Contract\Bridge\ServiceNameToTypeProviderInterface;
|
||||
use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
|
||||
use Rector\Node\Attribute;
|
||||
use Rector\NodeAnalyzer\SymfonyContainerCallsAnalyzer;
|
||||
use Rector\NodeFactory\NodeFactory;
|
||||
|
@ -42,22 +42,22 @@ final class GetterToPropertyRector extends AbstractRector
|
|||
private $symfonyContainerCallsAnalyzer;
|
||||
|
||||
/**
|
||||
* @var ServiceNameToTypeProviderInterface
|
||||
* @var ServiceTypeForNameProviderInterface
|
||||
*/
|
||||
private $serviceNameToTypeProvider;
|
||||
private $serviceTypeForNameProvider;
|
||||
|
||||
public function __construct(
|
||||
NameResolver $nameResolver,
|
||||
ClassPropertyCollector $classPropertyCollector,
|
||||
NodeFactory $nodeFactory,
|
||||
SymfonyContainerCallsAnalyzer $symfonyContainerCallsAnalyzer,
|
||||
ServiceNameToTypeProviderInterface $serviceNameToTypeProvider
|
||||
ServiceTypeForNameProviderInterface $serviceTypeForNameProvider
|
||||
) {
|
||||
$this->nameResolver = $nameResolver;
|
||||
$this->classPropertyCollector = $classPropertyCollector;
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
$this->symfonyContainerCallsAnalyzer = $symfonyContainerCallsAnalyzer;
|
||||
$this->serviceNameToTypeProvider = $serviceNameToTypeProvider;
|
||||
$this->serviceTypeForNameProvider = $serviceTypeForNameProvider;
|
||||
}
|
||||
|
||||
public function isCandidate(Node $node): bool
|
||||
|
@ -75,15 +75,11 @@ final class GetterToPropertyRector extends AbstractRector
|
|||
public function refactor(Node $methodCallNode): ?Node
|
||||
{
|
||||
$serviceName = $methodCallNode->args[0]->value->value;
|
||||
|
||||
$serviceNameToTypeMap = $this->serviceNameToTypeProvider->provide();
|
||||
|
||||
if (! isset($serviceNameToTypeMap[$serviceName])) {
|
||||
$serviceType = $this->serviceTypeForNameProvider->provideTypeForName($serviceName);
|
||||
if ($serviceType === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$serviceType = $serviceNameToTypeMap[$serviceName];
|
||||
|
||||
$propertyName = $this->nameResolver->resolvePropertyNameFromType($serviceType);
|
||||
|
||||
$this->classPropertyCollector->addPropertyForClass(
|
||||
|
|
|
@ -2,17 +2,19 @@
|
|||
|
||||
namespace Rector\Tests\Rector\Contrib\Nette\Environment\GetServiceToConstructorInjectionRector\Source;
|
||||
|
||||
use Rector\Contract\Bridge\ServiceNameToTypeProviderInterface;
|
||||
use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
|
||||
|
||||
final class DummyProvider implements ServiceNameToTypeProviderInterface
|
||||
final class DummyProvider implements ServiceTypeForNameProviderInterface
|
||||
{
|
||||
/**
|
||||
* @return string[]
|
||||
* @var string[]
|
||||
*/
|
||||
public function provide(): array
|
||||
private $nameToTypeMap = [
|
||||
'someService' => 'someType',
|
||||
];
|
||||
|
||||
public function provideTypeForName(string $name): ?string
|
||||
{
|
||||
return [
|
||||
'someService' => 'someType',
|
||||
];
|
||||
return $this->nameToTypeMap[$name] ?? null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,17 +2,19 @@
|
|||
|
||||
namespace Rector\Tests\Rector\Contrib\Symfony\Console\CommandToConstructorInjectionRector\Source;
|
||||
|
||||
use Rector\Contract\Bridge\ServiceNameToTypeProviderInterface;
|
||||
use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
|
||||
|
||||
final class DummyProvider implements ServiceNameToTypeProviderInterface
|
||||
final class DummyProvider implements ServiceTypeForNameProviderInterface
|
||||
{
|
||||
/**
|
||||
* @return string[]
|
||||
* @var string[]
|
||||
*/
|
||||
public function provide(): array
|
||||
private $nameToTypeMap = [
|
||||
'some_service' => 'stdClass',
|
||||
];
|
||||
|
||||
public function provideTypeForName(string $name): ?string
|
||||
{
|
||||
return [
|
||||
'some_service' => 'stdClass',
|
||||
];
|
||||
return $this->nameToTypeMap[$name] ?? null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,17 +2,19 @@
|
|||
|
||||
namespace Rector\Tests\Rector\Contrib\Symfony\HttpKernel\GetterToPropertyRector\Source;
|
||||
|
||||
use Rector\Contract\Bridge\ServiceNameToTypeProviderInterface;
|
||||
use Rector\Contract\Bridge\ServiceTypeForNameProviderInterface;
|
||||
|
||||
final class DummyProvider implements ServiceNameToTypeProviderInterface
|
||||
final class DummyProvider implements ServiceTypeForNameProviderInterface
|
||||
{
|
||||
/**
|
||||
* @return string[]
|
||||
* @var string[]
|
||||
*/
|
||||
public function provide(): array
|
||||
private $nameToTypeMap = [
|
||||
'some_service' => 'stdClass',
|
||||
];
|
||||
|
||||
public function provideTypeForName(string $name): ?string
|
||||
{
|
||||
return [
|
||||
'some_service' => 'stdClass',
|
||||
];
|
||||
return $this->nameToTypeMap[$name] ?? null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user