mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-01 08:50:50 +00:00
[Doctrine] Add constructor getRepository to service (#3954)
This commit is contained in:
parent
4fce95c509
commit
33d992497a
|
@ -6,13 +6,12 @@ use Rector\Architecture\Rector\Class_\MoveRepositoryFromParentToConstructorRecto
|
|||
use Rector\Architecture\Rector\MethodCall\ReplaceParentRepositoryCallsByRepositoryPropertyRector;
|
||||
use Rector\Architecture\Rector\MethodCall\ServiceLocatorToDIRector;
|
||||
use Rector\Doctrine\Rector\Class_\RemoveRepositoryFromEntityAnnotationRector;
|
||||
use Rector\Doctrine\Rector\ClassMethod\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector;
|
||||
use Rector\Generic\Rector\Class_\AddPropertyByParentRector;
|
||||
use Rector\Generic\Rector\Class_\RemoveParentRector;
|
||||
use Rector\Generic\Rector\ClassLike\RemoveAnnotationRector;
|
||||
use Rector\Generic\Rector\ClassMethod\RemoveConstructorDependencyByParentRector;
|
||||
use Rector\Generic\Rector\MethodCall\MethodCallToPropertyFetchRector;
|
||||
use Rector\Generic\Rector\MethodCall\ReplaceParentCallByPropertyCallRector;
|
||||
use Rector\Generic\Rector\StaticCall\RemoveParentCallByParentRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
/**
|
||||
|
@ -32,6 +31,8 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
// covers "extends ServiceEntityRepository"
|
||||
// @see https://github.com/doctrine/DoctrineBundle/pull/727/files
|
||||
$services->set(ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector::class);
|
||||
|
||||
$services->set(RemoveAnnotationRector::class)
|
||||
->call('configure', [[
|
||||
RemoveAnnotationRector::ANNOTATIONS_TO_REMOVE => ['method'],
|
||||
|
@ -71,23 +72,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
],
|
||||
]]);
|
||||
|
||||
$services->set(RemoveParentCallByParentRector::class)
|
||||
->call('configure', [[
|
||||
RemoveParentCallByParentRector::PARENT_CLASSES => [
|
||||
'Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository',
|
||||
],
|
||||
]]);
|
||||
|
||||
$services->set(RemoveConstructorDependencyByParentRector::class)
|
||||
->call('configure', [[
|
||||
RemoveConstructorDependencyByParentRector::PARENT_TYPE_TO_PARAM_TYPES_TO_REMOVE => [
|
||||
'Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository' => [
|
||||
'Doctrine\Common\Persistence\ManagerRegistry',
|
||||
'Doctrine\Persistence\ManagerRegistry',
|
||||
],
|
||||
],
|
||||
]]);
|
||||
|
||||
$services->set(RemoveParentRector::class)
|
||||
->call('configure', [[
|
||||
RemoveParentRector::PARENT_TYPES_TO_REMOVE => [
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# All 558 Rectors Overview
|
||||
# All 557 Rectors Overview
|
||||
|
||||
- [Projects](#projects)
|
||||
---
|
||||
|
@ -13,13 +13,13 @@
|
|||
- [DeadCode](#deadcode) (40)
|
||||
- [Decomplex](#decomplex) (1)
|
||||
- [Decouple](#decouple) (1)
|
||||
- [Doctrine](#doctrine) (16)
|
||||
- [Doctrine](#doctrine) (17)
|
||||
- [DoctrineCodeQuality](#doctrinecodequality) (2)
|
||||
- [DoctrineGedmoToKnplabs](#doctrinegedmotoknplabs) (7)
|
||||
- [Downgrade](#downgrade) (1)
|
||||
- [DynamicTypeAnalysis](#dynamictypeanalysis) (3)
|
||||
- [FileSystemRector](#filesystemrector) (1)
|
||||
- [Generic](#generic) (49)
|
||||
- [Generic](#generic) (47)
|
||||
- [Guzzle](#guzzle) (1)
|
||||
- [Injection](#injection) (1)
|
||||
- [JMS](#jms) (2)
|
||||
|
@ -3876,6 +3876,41 @@ Remove temporary *Uuid relation properties
|
|||
|
||||
<br><br>
|
||||
|
||||
### `ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector`
|
||||
|
||||
- class: [`Rector\Doctrine\Rector\ClassMethod\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector`](/../master/rules/doctrine/src/Rector/ClassMethod/ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector.php)
|
||||
- [test fixtures](/../master/rules/doctrine/tests/Rector/ClassMethod/ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector/Fixture)
|
||||
|
||||
Change ServiceEntityRepository to dependency injection, with repository property
|
||||
|
||||
```diff
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
final class ProjectRepository extends ServiceEntityRepository
|
||||
{
|
||||
- public function __construct(ManagerRegistry $registry)
|
||||
+ /**
|
||||
+ * @var \Doctrine\ORM\EntityManagerInterface
|
||||
+ */
|
||||
+ private $entityManager;
|
||||
+
|
||||
+ /**
|
||||
+ * @var \Doctrine\ORM\EntityRepository<Project>
|
||||
+ */
|
||||
+ private $repository;
|
||||
+
|
||||
+ public function __construct(\Doctrine\ORM\EntityManagerInterface $entityManager)
|
||||
{
|
||||
- parent::__construct($registry, Project::class);
|
||||
+ $this->repository = $entityManager->getRepository(Project::class);
|
||||
+ $this->entityManager = $entityManager;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
## DoctrineCodeQuality
|
||||
|
||||
### `ChangeQuerySetParametersMethodParameterFromArrayToArrayCollectionRector`
|
||||
|
@ -5491,40 +5526,6 @@ return function (ContainerConfigurator $containerConfigurator) : void {
|
|||
|
||||
<br><br>
|
||||
|
||||
### `RemoveConstructorDependencyByParentRector`
|
||||
|
||||
- class: [`Rector\Generic\Rector\ClassMethod\RemoveConstructorDependencyByParentRector`](/../master/rules/generic/src/Rector/ClassMethod/RemoveConstructorDependencyByParentRector.php)
|
||||
- [test fixtures](/../master/rules/generic/tests/Rector/ClassMethod/RemoveConstructorDependencyByParentRector/Fixture)
|
||||
|
||||
Removes params in constructor by parent type and param names
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
use Rector\Generic\Rector\ClassMethod\RemoveConstructorDependencyByParentRector;
|
||||
|
||||
return function (ContainerConfigurator $containerConfigurator) : void {
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(RemoveConstructorDependencyByParentRector::class)
|
||||
->call('configure', [[RemoveConstructorDependencyByParentRector::PARENT_TYPE_TO_PARAM_TYPES_TO_REMOVE, ['SomeParentClass' => ['someType']]]]);
|
||||
};
|
||||
```
|
||||
|
||||
↓
|
||||
|
||||
```diff
|
||||
class SomeClass extends SomeParentClass
|
||||
{
|
||||
- public function __construct(SomeType $someType)
|
||||
+ public function __construct()
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `RemoveFuncCallArgRector`
|
||||
|
||||
- class: [`Rector\Generic\Rector\FuncCall\RemoveFuncCallArgRector`](/../master/rules/generic/src/Rector/FuncCall/RemoveFuncCallArgRector.php)
|
||||
|
@ -5614,40 +5615,6 @@ return function (ContainerConfigurator $containerConfigurator) : void {
|
|||
|
||||
<br><br>
|
||||
|
||||
### `RemoveParentCallByParentRector`
|
||||
|
||||
- class: [`Rector\Generic\Rector\StaticCall\RemoveParentCallByParentRector`](/../master/rules/generic/src/Rector/StaticCall/RemoveParentCallByParentRector.php)
|
||||
- [test fixtures](/../master/rules/generic/tests/Rector/StaticCall/RemoveParentCallByParentRector/Fixture)
|
||||
|
||||
Remove parent call by parent class
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
use Rector\Generic\Rector\StaticCall\RemoveParentCallByParentRector;
|
||||
|
||||
return function (ContainerConfigurator $containerConfigurator) : void {
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(RemoveParentCallByParentRector::class)
|
||||
->call('configure', [[RemoveParentCallByParentRector::PARENT_CLASSES, ['SomeParentClass']]]);
|
||||
};
|
||||
```
|
||||
|
||||
↓
|
||||
|
||||
```diff
|
||||
final class SomeClass extends SomeParentClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
- parent::someCall();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `RemoveParentRector`
|
||||
|
||||
- class: [`Rector\Generic\Rector\Class_\RemoveParentRector`](/../master/rules/generic/src/Rector/Class_/RemoveParentRector.php)
|
||||
|
@ -11590,8 +11557,8 @@ Rename "*Spec.php" file to "*Test.php" file
|
|||
|
||||
### `UnwrapFutureCompatibleIfFunctionExistsRector`
|
||||
|
||||
- class: [`Rector\Polyfill\Rector\If_\UnwrapFutureCompatibleIfFunctionExistsRector`](/../master/packages/polyfill/src/Rector/If_/UnwrapFutureCompatibleIfFunctionExistsRector.php)
|
||||
- [test fixtures](/../master/packages/polyfill/tests/Rector/If_/UnwrapFutureCompatibleIfFunctionExistsRector/Fixture)
|
||||
- class: [`Rector\Polyfill\Rector\If_\UnwrapFutureCompatibleIfFunctionExistsRector`](/../master/rules/polyfill/src/Rector/If_/UnwrapFutureCompatibleIfFunctionExistsRector.php)
|
||||
- [test fixtures](/../master/rules/polyfill/tests/Rector/If_/UnwrapFutureCompatibleIfFunctionExistsRector/Fixture)
|
||||
|
||||
Remove functions exists if with else for always existing
|
||||
|
||||
|
@ -11615,8 +11582,8 @@ Remove functions exists if with else for always existing
|
|||
|
||||
### `UnwrapFutureCompatibleIfPhpVersionRector`
|
||||
|
||||
- class: [`Rector\Polyfill\Rector\If_\UnwrapFutureCompatibleIfPhpVersionRector`](/../master/packages/polyfill/src/Rector/If_/UnwrapFutureCompatibleIfPhpVersionRector.php)
|
||||
- [test fixtures](/../master/packages/polyfill/tests/Rector/If_/UnwrapFutureCompatibleIfPhpVersionRector/Fixture)
|
||||
- class: [`Rector\Polyfill\Rector\If_\UnwrapFutureCompatibleIfPhpVersionRector`](/../master/rules/polyfill/src/Rector/If_/UnwrapFutureCompatibleIfPhpVersionRector.php)
|
||||
- [test fixtures](/../master/rules/polyfill/tests/Rector/If_/UnwrapFutureCompatibleIfPhpVersionRector/Fixture)
|
||||
|
||||
Remove php version checks if they are passed
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PHPStanStaticTypeMapper\Contract;
|
||||
|
||||
use Rector\PHPStanStaticTypeMapper\PHPStanStaticTypeMapper;
|
||||
|
||||
interface PHPStanStaticTypeMapperAwareInterface
|
||||
{
|
||||
public function setPHPStanStaticTypeMapper(PHPStanStaticTypeMapper $phpStanStaticTypeMapper): void;
|
||||
}
|
|
@ -11,6 +11,7 @@ use PhpParser\Node\UnionType as PhpParserUnionType;
|
|||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\Core\Exception\NotImplementedException;
|
||||
use Rector\PHPStanStaticTypeMapper\Contract\PHPStanStaticTypeMapperAwareInterface;
|
||||
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
|
||||
|
||||
final class PHPStanStaticTypeMapper
|
||||
|
@ -35,6 +36,12 @@ final class PHPStanStaticTypeMapper
|
|||
*/
|
||||
public function __construct(array $typeMappers)
|
||||
{
|
||||
foreach ($typeMappers as $typeMapper) {
|
||||
if ($typeMapper instanceof PHPStanStaticTypeMapperAwareInterface) {
|
||||
$typeMapper->setPHPStanStaticTypeMapper($this);
|
||||
}
|
||||
}
|
||||
|
||||
$this->typeMappers = $typeMappers;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Rector\PHPStanStaticTypeMapper\TypeMapper;
|
|||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
|
||||
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
|
||||
use PHPStan\Type\Generic\GenericObjectType;
|
||||
|
@ -18,10 +19,17 @@ use Rector\PHPStan\Type\AliasedObjectType;
|
|||
use Rector\PHPStan\Type\FullyQualifiedObjectType;
|
||||
use Rector\PHPStan\Type\SelfObjectType;
|
||||
use Rector\PHPStan\Type\ShortenedObjectType;
|
||||
use Rector\PHPStanStaticTypeMapper\Contract\PHPStanStaticTypeMapperAwareInterface;
|
||||
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;
|
||||
use Rector\PHPStanStaticTypeMapper\PHPStanStaticTypeMapper;
|
||||
|
||||
final class ObjectTypeMapper implements TypeMapperInterface
|
||||
final class ObjectTypeMapper implements TypeMapperInterface, PHPStanStaticTypeMapperAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var PHPStanStaticTypeMapper
|
||||
*/
|
||||
private $phpStanStaticTypeMapper;
|
||||
|
||||
public function getNodeClass(): string
|
||||
{
|
||||
return ObjectType::class;
|
||||
|
@ -40,6 +48,18 @@ final class ObjectTypeMapper implements TypeMapperInterface
|
|||
return new IdentifierTypeNode($type->getClassName());
|
||||
}
|
||||
|
||||
if ($type instanceof GenericObjectType) {
|
||||
$identifierTypeNode = new IdentifierTypeNode('\\' . $type->getClassName());
|
||||
|
||||
$genericTypeNodes = [];
|
||||
foreach ($type->getTypes() as $genericType) {
|
||||
$typeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode($genericType);
|
||||
$genericTypeNodes[] = $typeNode;
|
||||
}
|
||||
|
||||
return new GenericTypeNode($identifierTypeNode, $genericTypeNodes);
|
||||
}
|
||||
|
||||
return new IdentifierTypeNode('\\' . $type->getClassName());
|
||||
}
|
||||
|
||||
|
@ -98,4 +118,9 @@ final class ObjectTypeMapper implements TypeMapperInterface
|
|||
|
||||
return $type->getClassName();
|
||||
}
|
||||
|
||||
public function setPHPStanStaticTypeMapper(PHPStanStaticTypeMapper $phpStanStaticTypeMapper): void
|
||||
{
|
||||
$this->phpStanStaticTypeMapper = $phpStanStaticTypeMapper;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use PHPStan\Type\ObjectType;
|
|||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\ChangesReporting\Collector\RectorChangeCollector;
|
||||
use Rector\Naming\Naming\PropertyNaming;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PHPStan\Type\AliasedObjectType;
|
||||
use Rector\PHPStan\Type\FullyQualifiedObjectType;
|
||||
|
@ -59,6 +60,11 @@ trait NodeCommandersTrait
|
|||
*/
|
||||
private $rectorChangeCollector;
|
||||
|
||||
/**
|
||||
* @var PropertyNaming
|
||||
*/
|
||||
private $propertyNaming;
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
|
@ -68,7 +74,8 @@ trait NodeCommandersTrait
|
|||
UseNodesToAddCollector $useNodesToAddCollector,
|
||||
NodesToAddCollector $nodesToAddCollector,
|
||||
NodesToReplaceCollector $nodesToReplaceCollector,
|
||||
RectorChangeCollector $rectorChangeCollector
|
||||
RectorChangeCollector $rectorChangeCollector,
|
||||
PropertyNaming $propertyNaming
|
||||
): void {
|
||||
$this->nodesToRemoveCollector = $nodesToRemoveCollector;
|
||||
$this->propertyToAddCollector = $propertyToAddCollector;
|
||||
|
@ -76,6 +83,7 @@ trait NodeCommandersTrait
|
|||
$this->nodesToReplaceCollector = $nodesToReplaceCollector;
|
||||
$this->nodesToAddCollector = $nodesToAddCollector;
|
||||
$this->rectorChangeCollector = $rectorChangeCollector;
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,10 +144,18 @@ trait NodeCommandersTrait
|
|||
/** @var string $propertyName */
|
||||
$propertyName = $this->getName($property);
|
||||
|
||||
$this->addPropertyToClass($classNode, $propertyType, $propertyName);
|
||||
$this->addConstructorDependencyToClass($classNode, $propertyType, $propertyName);
|
||||
}
|
||||
|
||||
protected function addPropertyToClass(Class_ $class, ?Type $propertyType, string $propertyName): void
|
||||
protected function addServiceConstructorDependencyToClass(Class_ $class, string $className): void
|
||||
{
|
||||
$serviceObjectType = new ObjectType($className);
|
||||
|
||||
$propertyName = $this->propertyNaming->fqnToVariableName($serviceObjectType);
|
||||
$this->addConstructorDependencyToClass($class, $serviceObjectType, $propertyName);
|
||||
}
|
||||
|
||||
protected function addConstructorDependencyToClass(Class_ $class, ?Type $propertyType, string $propertyName): void
|
||||
{
|
||||
$this->propertyToAddCollector->addPropertyToClass($propertyName, $propertyType, $class);
|
||||
$this->rectorChangeCollector->notifyNodeFileInfo($class);
|
||||
|
@ -151,11 +167,8 @@ trait NodeCommandersTrait
|
|||
$this->rectorChangeCollector->notifyNodeFileInfo($class);
|
||||
}
|
||||
|
||||
protected function addPropertyWithoutConstructorToClass(
|
||||
Class_ $class,
|
||||
?Type $propertyType,
|
||||
string $propertyName
|
||||
): void {
|
||||
protected function addPropertyToClass(Class_ $class, ?Type $propertyType, string $propertyName): void
|
||||
{
|
||||
$this->propertyToAddCollector->addPropertyWithoutConstructorToClass($propertyName, $propertyType, $class);
|
||||
$this->rectorChangeCollector->notifyNodeFileInfo($class);
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ PHP
|
|||
|
||||
$repositoryObjectType = new ObjectType($repositoryFqn);
|
||||
|
||||
$this->addPropertyToClass(
|
||||
$this->addConstructorDependencyToClass(
|
||||
$classLike,
|
||||
$repositoryObjectType,
|
||||
$this->propertyNaming->fqnToVariableName($repositoryObjectType)
|
||||
|
|
32
rules/doctrine/src/NodeFactory/RepositoryNodeFactory.php
Normal file
32
rules/doctrine/src/NodeFactory/RepositoryNodeFactory.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Doctrine\NodeFactory;
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
|
||||
final class RepositoryNodeFactory
|
||||
{
|
||||
public function createRepositoryAssign(Expr $entityReferenceExpr): Expression
|
||||
{
|
||||
$propertyFetch = new PropertyFetch(new Variable('this'), new Identifier('repository'));
|
||||
$assign = new Assign($propertyFetch, $this->createGetRepositoryMethodCall($entityReferenceExpr));
|
||||
|
||||
return new Expression($assign);
|
||||
}
|
||||
|
||||
private function createGetRepositoryMethodCall(Expr $entityReferenceExpr): MethodCall
|
||||
{
|
||||
$args = [new Arg($entityReferenceExpr)];
|
||||
|
||||
return new MethodCall(new Variable('entityManager'), 'getRepository', $args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Doctrine\Rector\ClassMethod;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\Doctrine\NodeFactory\RepositoryNodeFactory;
|
||||
use Rector\Doctrine\Type\RepositoryTypeFactory;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
* @sponsor Thanks https://www.luzanky.cz/ for sponsoring this rule
|
||||
*
|
||||
* @see https://tomasvotruba.com/blog/2017/10/16/how-to-use-repository-with-doctrine-as-service-in-symfony/
|
||||
*
|
||||
* @see \Rector\Doctrine\Tests\Rector\ClassMethod\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRectorTest
|
||||
*/
|
||||
final class ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const SERVICE_ENTITY_REPOSITORY_CLASS = 'Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository';
|
||||
|
||||
/**
|
||||
* @var RepositoryNodeFactory
|
||||
*/
|
||||
private $repositoryNodeFactory;
|
||||
|
||||
/**
|
||||
* @var RepositoryTypeFactory
|
||||
*/
|
||||
private $repositoryTypeFactory;
|
||||
|
||||
public function __construct(
|
||||
RepositoryNodeFactory $repositoryNodeFactory,
|
||||
RepositoryTypeFactory $repositoryTypeFactory
|
||||
) {
|
||||
$this->repositoryNodeFactory = $repositoryNodeFactory;
|
||||
$this->repositoryTypeFactory = $repositoryTypeFactory;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition(
|
||||
'Change ServiceEntityRepository to dependency injection, with repository property',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'PHP'
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
final class ProjectRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Project::class);
|
||||
}
|
||||
}
|
||||
PHP
|
||||
,
|
||||
<<<'PHP'
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
final class ProjectRepository extends ServiceEntityRepository
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityManagerInterface
|
||||
*/
|
||||
private $entityManager;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityRepository<Project>
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
public function __construct(\Doctrine\ORM\EntityManagerInterface $entityManager)
|
||||
{
|
||||
$this->repository = $entityManager->getRepository(Project::class);
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
}
|
||||
PHP
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [ClassMethod::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMethod $node
|
||||
*
|
||||
* For reference, possible manager registry param types:
|
||||
* - Doctrine\Common\Persistence\ManagerRegistry
|
||||
* - Doctrine\Persistence\ManagerRegistry
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($this->shouldSkip($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var ClassLike|null $classLike */
|
||||
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classLike instanceof Class_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 1. remove params
|
||||
$node->params = [];
|
||||
|
||||
// 2. remove parent::__construct()
|
||||
$entityReferenceExpr = $this->removeParentConstructAndCollectEntityReference($node);
|
||||
|
||||
// 3. add $entityManager->getRepository() fetch assign
|
||||
$node->stmts[] = $this->repositoryNodeFactory->createRepositoryAssign($entityReferenceExpr);
|
||||
|
||||
// 4. add $repository property
|
||||
$this->addRepositoryProperty($classLike, $entityReferenceExpr);
|
||||
|
||||
// 5. add param + add property, dependency
|
||||
$this->addServiceConstructorDependencyToClass($classLike, 'Doctrine\ORM\EntityManagerInterface');
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function shouldSkip(ClassMethod $classMethod): bool
|
||||
{
|
||||
/** @var string|null $parentClassName */
|
||||
$parentClassName = $classMethod->getAttribute(AttributeKey::PARENT_CLASS_NAME);
|
||||
if ($parentClassName === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $parentClassName !== self::SERVICE_ENTITY_REPOSITORY_CLASS;
|
||||
}
|
||||
|
||||
private function removeParentConstructAndCollectEntityReference(ClassMethod $classMethod): Expr
|
||||
{
|
||||
$entityReferenceExpr = null;
|
||||
|
||||
$this->traverseNodesWithCallable((array) $classMethod->stmts, function (Node $node) use (
|
||||
&$entityReferenceExpr
|
||||
) {
|
||||
if (! $node instanceof StaticCall) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isName($node->class, 'parent')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$entityReferenceExpr = $node->args[1]->value;
|
||||
$this->removeNode($node);
|
||||
});
|
||||
|
||||
if ($entityReferenceExpr === null) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
return $entityReferenceExpr;
|
||||
}
|
||||
|
||||
private function addRepositoryProperty(Class_ $class, Expr $entityReferenceExpr): void
|
||||
{
|
||||
$repositoryPropertyType = $this->repositoryTypeFactory->createRepositoryPropertyType($entityReferenceExpr);
|
||||
$this->addPropertyToClass($class, $repositoryPropertyType, 'repository');
|
||||
}
|
||||
}
|
|
@ -252,7 +252,7 @@ PHP
|
|||
$assign = $this->nodeFactory->createPropertyAssignment($name);
|
||||
$classMethod->stmts[] = new Expression($assign);
|
||||
|
||||
$this->addPropertyToClass($class, $objectType, $name);
|
||||
$this->addConstructorDependencyToClass($class, $objectType, $name);
|
||||
}
|
||||
|
||||
private function createEntityManagerParam(): Param
|
||||
|
|
36
rules/doctrine/src/Type/RepositoryTypeFactory.php
Normal file
36
rules/doctrine/src/Type/RepositoryTypeFactory.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Doctrine\Type;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PHPStan\Type\Generic\GenericObjectType;
|
||||
use Rector\Core\Exception\NotImplementedYetException;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\PHPStan\Type\FullyQualifiedObjectType;
|
||||
|
||||
final class RepositoryTypeFactory
|
||||
{
|
||||
/**
|
||||
* @var NodeNameResolver
|
||||
*/
|
||||
private $nodeNameResolver;
|
||||
|
||||
public function __construct(NodeNameResolver $nodeNameResolver)
|
||||
{
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
|
||||
public function createRepositoryPropertyType(Expr $entityReferenceExpr): GenericObjectType
|
||||
{
|
||||
if (! $entityReferenceExpr instanceof Expr\ClassConstFetch) {
|
||||
throw new NotImplementedYetException();
|
||||
}
|
||||
|
||||
/** @var string $className */
|
||||
$className = $this->nodeNameResolver->getName($entityReferenceExpr->class);
|
||||
|
||||
return new GenericObjectType('Doctrine\ORM\EntityRepository', [new FullyQualifiedObjectType($className)]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Doctrine\Tests\Rector\ClassMethod\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector\Fixture;
|
||||
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Rector\Doctrine\Tests\Rector\ClassMethod\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector\Source\Project;
|
||||
|
||||
final class ProjectRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Project::class);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Doctrine\Tests\Rector\ClassMethod\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector\Fixture;
|
||||
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Rector\Doctrine\Tests\Rector\ClassMethod\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector\Source\Project;
|
||||
|
||||
final class ProjectRepository extends ServiceEntityRepository
|
||||
{
|
||||
private \Doctrine\ORM\EntityManagerInterface $entityManager;
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityRepository<\Rector\Doctrine\Tests\Rector\ClassMethod\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector\Source\Project>
|
||||
*/
|
||||
private \Doctrine\ORM\EntityRepository $repository;
|
||||
public function __construct(\Doctrine\ORM\EntityManagerInterface $entityManager)
|
||||
{
|
||||
$this->repository = $entityManager->getRepository(Project::class);
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Doctrine\Tests\Rector\ClassMethod\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\Doctrine\Rector\ClassMethod\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector::class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Doctrine\Tests\Rector\ClassMethod\ServiceEntityRepositoryConstructorToDependencyInjectionWithRepositoryPropertyRector\Source;
|
||||
|
||||
class Project
|
||||
{
|
||||
|
||||
}
|
|
@ -82,7 +82,7 @@ abstract class AbstractToMethodCallRector extends AbstractRector implements Conf
|
|||
{
|
||||
$fullyQualifiedObjectType = new FullyQualifiedObjectType($type);
|
||||
$propertyName = $this->propertyNaming->fqnToVariableName($fullyQualifiedObjectType);
|
||||
$this->addPropertyToClass($class, $fullyQualifiedObjectType, $propertyName);
|
||||
$this->addConstructorDependencyToClass($class, $fullyQualifiedObjectType, $propertyName);
|
||||
}
|
||||
|
||||
private function createPropertyFetchFromClass(string $type): PropertyFetch
|
||||
|
|
|
@ -113,7 +113,7 @@ PHP
|
|||
|
||||
/** @var string $paramName */
|
||||
$paramName = $this->getName($paramNode->var);
|
||||
$this->addPropertyToClass($class, $paramNodeType, $paramName);
|
||||
$this->addConstructorDependencyToClass($class, $paramNodeType, $paramName);
|
||||
|
||||
$this->removeParam($classMethod, $key);
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ PHP
|
|||
|
||||
$factoryObjectType = new ObjectType($factoryClass);
|
||||
|
||||
$this->addPropertyToClass($classNode, $factoryObjectType, $propertyName);
|
||||
$this->addConstructorDependencyToClass($classNode, $factoryObjectType, $propertyName);
|
||||
}
|
||||
|
||||
return new MethodCall(
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Rector\ClassMethod;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\ConfiguredCodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
* @see \Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\RemoveConstructorDependencyByParentRectorTest
|
||||
*/
|
||||
final class RemoveConstructorDependencyByParentRector extends AbstractRector implements ConfigurableRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @api
|
||||
*/
|
||||
public const PARENT_TYPE_TO_PARAM_TYPES_TO_REMOVE = '$parentsDependenciesToRemove';
|
||||
|
||||
/**
|
||||
* @var array<string, string[]>
|
||||
*/
|
||||
private $parentsDependenciesToRemove = [];
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Removes params in constructor by parent type and param names', [
|
||||
new ConfiguredCodeSample(
|
||||
<<<'PHP'
|
||||
class SomeClass extends SomeParentClass
|
||||
{
|
||||
public function __construct(SomeType $someType)
|
||||
{
|
||||
}
|
||||
}
|
||||
PHP
|
||||
,
|
||||
<<<'PHP'
|
||||
class SomeClass extends SomeParentClass
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
}
|
||||
PHP
|
||||
, [
|
||||
self::PARENT_TYPE_TO_PARAM_TYPES_TO_REMOVE => [
|
||||
'SomeParentClass' => ['someType'],
|
||||
],
|
||||
]
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [ClassMethod::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMethod $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$parentClassName = $node->getAttribute(AttributeKey::PARENT_CLASS_NAME);
|
||||
if ($parentClassName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isName($node, MethodName::CONSTRUCT)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($this->parentsDependenciesToRemove as $parentClass => $paramsToRemove) {
|
||||
$parentClassName = $node->getAttribute(AttributeKey::PARENT_CLASS_NAME);
|
||||
if ($parentClassName !== $parentClass) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->removeClassMethodParameterByName($node, $paramsToRemove);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
public function configure(array $configuration): void
|
||||
{
|
||||
$this->parentsDependenciesToRemove = $configuration[self::PARENT_TYPE_TO_PARAM_TYPES_TO_REMOVE] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $paramNamesToRemove
|
||||
*/
|
||||
private function removeClassMethodParameterByName(ClassMethod $classMethod, array $paramNamesToRemove): void
|
||||
{
|
||||
foreach ($paramNamesToRemove as $paramNameToRemove) {
|
||||
foreach ($classMethod->params as $param) {
|
||||
if ($param->type === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $this->isName($param->type, $paramNameToRemove)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->removeNode($param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -101,7 +101,7 @@ CODE_SAMPLE
|
|||
$propertyType = new ObjectType($typeToAdd);
|
||||
/** @var string $propertyName */
|
||||
$propertyName = $this->propertyNaming->getExpectedNameFromType($propertyType);
|
||||
$this->addPropertyToClass($node, $propertyType, $propertyName);
|
||||
$this->addConstructorDependencyToClass($node, $propertyType, $propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ PHP
|
|||
$propertyName = $this->propertyNaming->fqnToVariableName($serviceObjectType);
|
||||
|
||||
/** @var Class_ $classLike */
|
||||
$this->addPropertyToClass($classLike, $serviceObjectType, $propertyName);
|
||||
$this->addConstructorDependencyToClass($classLike, $serviceObjectType, $propertyName);
|
||||
|
||||
return new PropertyFetch(new Variable('this'), new Identifier($propertyName));
|
||||
}
|
||||
|
|
|
@ -224,7 +224,7 @@ PHP
|
|||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->addPropertyToClass($classLike, $type, $name);
|
||||
$this->addConstructorDependencyToClass($classLike, $type, $name);
|
||||
|
||||
return $property;
|
||||
}
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Rector\StaticCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\ConfiguredCodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
* @see \Rector\Generic\Tests\Rector\StaticCall\RemoveParentCallByParentRector\RemoveParentCallByParentRectorTest
|
||||
*/
|
||||
final class RemoveParentCallByParentRector extends AbstractRector implements ConfigurableRectorInterface
|
||||
{
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PARENT_CLASSES = 'parent_classes';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $parentClasses = [];
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Remove parent call by parent class', [
|
||||
new ConfiguredCodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeClass extends SomeParentClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
parent::someCall();
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
final class SomeClass extends SomeParentClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
[
|
||||
self::PARENT_CLASSES => ['SomeParentClass'],
|
||||
]
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [StaticCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param StaticCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classLike instanceof Class_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isName($node->class, 'parent')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$parentClassName = $node->getAttribute(AttributeKey::PARENT_CLASS_NAME);
|
||||
|
||||
foreach ($this->parentClasses as $parentClass) {
|
||||
if ($parentClassName !== $parentClass) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->removeNode($node);
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function configure(array $configuration): void
|
||||
{
|
||||
$this->parentClasses = $configuration[self::PARENT_CLASSES] ?? [];
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source\ParentClassToRemoveConstructorParamsBy;
|
||||
use Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source\SomeDependencyToBeRemoved;
|
||||
|
||||
final class ClassWithExternalConstant extends ParentClassToRemoveConstructorParamsBy
|
||||
{
|
||||
/**
|
||||
* @var SomeDependencyToBeRemoved
|
||||
*/
|
||||
private $someDependencyToBeRemoved;
|
||||
|
||||
public function __construct(SomeDependencyToBeRemoved $someDependencyToBeRemoved)
|
||||
{
|
||||
$this->someDependencyToBeRemoved = $someDependencyToBeRemoved;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source\ParentClassToRemoveConstructorParamsBy;
|
||||
use Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source\SomeDependencyToBeRemoved;
|
||||
|
||||
final class ClassWithExternalConstant extends ParentClassToRemoveConstructorParamsBy
|
||||
{
|
||||
/**
|
||||
* @var SomeDependencyToBeRemoved
|
||||
*/
|
||||
private $someDependencyToBeRemoved;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->someDependencyToBeRemoved = $someDependencyToBeRemoved;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source\ParentClassToRemoveConstructorParamsBy;
|
||||
use Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source\SomeDependencyToBeRemoved;
|
||||
|
||||
final class TypeFirst extends ParentClassToRemoveConstructorParamsBy
|
||||
{
|
||||
/**
|
||||
* @var SomeDependencyToBeRemoved
|
||||
*/
|
||||
private $whatever;
|
||||
|
||||
public function __construct(SomeDependencyToBeRemoved $whatever)
|
||||
{
|
||||
$this->whatever = $whatever;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source\ParentClassToRemoveConstructorParamsBy;
|
||||
use Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source\SomeDependencyToBeRemoved;
|
||||
|
||||
final class TypeFirst extends ParentClassToRemoveConstructorParamsBy
|
||||
{
|
||||
/**
|
||||
* @var SomeDependencyToBeRemoved
|
||||
*/
|
||||
private $whatever;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->whatever = $whatever;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\Generic\Rector\ClassMethod\RemoveConstructorDependencyByParentRector;
|
||||
use Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source\ParentClassToRemoveConstructorParamsBy;
|
||||
use Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source\SomeDependencyToBeRemoved;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class RemoveConstructorDependencyByParentRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
return [
|
||||
RemoveConstructorDependencyByParentRector::class => [
|
||||
RemoveConstructorDependencyByParentRector::PARENT_TYPE_TO_PARAM_TYPES_TO_REMOVE => [
|
||||
ParentClassToRemoveConstructorParamsBy::class => [SomeDependencyToBeRemoved::class],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source;
|
||||
|
||||
abstract class ParentClassToRemoveConstructorParamsBy
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\ClassMethod\RemoveConstructorDependencyByParentRector\Source;
|
||||
|
||||
final class SomeDependencyToBeRemoved
|
||||
{
|
||||
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\StaticCall\RemoveParentCallByParentRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\StaticCall\RemoveParentCallByParentRector\Source\ParentClassToRemoveParentStaticCallBy;
|
||||
|
||||
final class SomeClass extends ParentClassToRemoveParentStaticCallBy
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
parent::run();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\StaticCall\RemoveParentCallByParentRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\StaticCall\RemoveParentCallByParentRector\Source\ParentClassToRemoveParentStaticCallBy;
|
||||
|
||||
final class SomeClass extends ParentClassToRemoveParentStaticCallBy
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\StaticCall\RemoveParentCallByParentRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\Generic\Rector\StaticCall\RemoveParentCallByParentRector;
|
||||
use Rector\Generic\Tests\Rector\StaticCall\RemoveParentCallByParentRector\Source\ParentClassToRemoveParentStaticCallBy;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class RemoveParentCallByParentRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
protected function getRectorsWithConfiguration(): array
|
||||
{
|
||||
return [
|
||||
RemoveParentCallByParentRector::class => [
|
||||
RemoveParentCallByParentRector::PARENT_CLASSES => [ParentClassToRemoveParentStaticCallBy::class],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\StaticCall\RemoveParentCallByParentRector\Source;
|
||||
|
||||
abstract class ParentClassToRemoveParentStaticCallBy
|
||||
{
|
||||
|
||||
}
|
|
@ -108,7 +108,7 @@ PHP
|
|||
}
|
||||
|
||||
$fullyQualifiedObjectType = new FullyQualifiedObjectType($functionChange->getClass());
|
||||
$this->addPropertyToClass($classLike, $fullyQualifiedObjectType, $functionChange->getProperty());
|
||||
$this->addConstructorDependencyToClass($classLike, $fullyQualifiedObjectType, $functionChange->getProperty());
|
||||
|
||||
$propertyFetchNode = $this->createPropertyFetch('this', $functionChange->getProperty());
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ PHP
|
|||
$serviceObjectType = new FullyQualifiedObjectType($serviceClass);
|
||||
|
||||
$propertyName = $this->propertyNaming->fqnToVariableName($serviceObjectType);
|
||||
$this->addPropertyToClass($classLike, $serviceObjectType, $propertyName);
|
||||
$this->addConstructorDependencyToClass($classLike, $serviceObjectType, $propertyName);
|
||||
|
||||
$propertyFetchNode = $this->createPropertyFetch('this', $propertyName);
|
||||
return new MethodCall($propertyFetchNode, $node->name, $node->args);
|
||||
|
|
|
@ -118,7 +118,7 @@ PHP
|
|||
|
||||
/** @var Class_ $classLike */
|
||||
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
|
||||
$this->addPropertyToClass(
|
||||
$this->addConstructorDependencyToClass(
|
||||
$classLike,
|
||||
new FullyQualifiedObjectType(EventDispatcherInterface::class),
|
||||
'eventDispatcher'
|
||||
|
|
|
@ -185,7 +185,11 @@ PHP
|
|||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->addPropertyToClass($classLike, new FullyQualifiedObjectType('Nette\Http\Session'), 'session');
|
||||
$this->addConstructorDependencyToClass(
|
||||
$classLike,
|
||||
new FullyQualifiedObjectType('Nette\Http\Session'),
|
||||
'session'
|
||||
);
|
||||
|
||||
return $node;
|
||||
});
|
||||
|
|
|
@ -89,7 +89,7 @@ PHP
|
|||
$this->collectGlobalVariableNamesAndRefactorToPropertyFetch($node);
|
||||
|
||||
foreach ($this->globalVariableNames as $globalVariableName) {
|
||||
$this->addPropertyWithoutConstructorToClass($classLike, null, $globalVariableName);
|
||||
$this->addPropertyToClass($classLike, null, $globalVariableName);
|
||||
}
|
||||
|
||||
return $node;
|
||||
|
|
|
@ -165,7 +165,7 @@ PHP
|
|||
$propertyName = $this->propertyNaming->fqnToVariableName($matchedObjectType) . self::FACTORY;
|
||||
$propertyType = new FullyQualifiedObjectType($matchedObjectType->getClassName() . self::FACTORY);
|
||||
|
||||
$this->addPropertyToClass($node, $propertyType, $propertyName);
|
||||
$this->addConstructorDependencyToClass($node, $propertyType, $propertyName);
|
||||
}
|
||||
|
||||
return $node;
|
||||
|
|
|
@ -178,7 +178,7 @@ PHP
|
|||
// add via constructor
|
||||
foreach ($newPropertyTypes as $newPropertyType) {
|
||||
$newPropertyName = $this->propertyNaming->fqnToVariableName($newPropertyType);
|
||||
$this->addPropertyToClass($class, $newPropertyType, $newPropertyName);
|
||||
$this->addConstructorDependencyToClass($class, $newPropertyType, $newPropertyName);
|
||||
}
|
||||
|
||||
return $class;
|
||||
|
|
|
@ -200,7 +200,7 @@ PHP
|
|||
|
||||
foreach ($staticTypesInClass as $staticType) {
|
||||
$variableName = $this->propertyNaming->fqnToVariableName($staticType);
|
||||
$this->addPropertyToClass($class, $staticType, $variableName);
|
||||
$this->addConstructorDependencyToClass($class, $staticType, $variableName);
|
||||
|
||||
// is this an object? create factory for it next to this :)
|
||||
if ($this->uniqueObjectOrServiceDetector->isUniqueObject()) {
|
||||
|
|
|
@ -55,7 +55,7 @@ abstract class AbstractToConstructorInjectionRector extends AbstractRector
|
|||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->addPropertyToClass($classLike, $serviceType, $propertyName);
|
||||
$this->addConstructorDependencyToClass($classLike, $serviceType, $propertyName);
|
||||
|
||||
return $this->createPropertyFetch('this', $propertyName);
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ PHP
|
|||
return null;
|
||||
}
|
||||
|
||||
$this->addPropertyToClass($classLike, new StringType(), $propertyName);
|
||||
$this->addConstructorDependencyToClass($classLike, new StringType(), $propertyName);
|
||||
|
||||
return $this->createPropertyFetch('this', $propertyName);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ use PhpParser\Node\Stmt\ClassMethod;
|
|||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use PhpParser\Node\UnionType;
|
||||
use PHPStan\Type\Generic\GenericObjectType;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
|
@ -234,7 +235,6 @@ final class NodeFactory
|
|||
$propertyBuilder->makePrivate();
|
||||
|
||||
$property = $propertyBuilder->getNode();
|
||||
|
||||
$this->addPropertyType($property, $type);
|
||||
|
||||
$this->decorateParentPropertyProperty($property);
|
||||
|
@ -485,6 +485,11 @@ final class NodeFactory
|
|||
|
||||
if ($phpParserType !== null) {
|
||||
$property->type = $phpParserType;
|
||||
|
||||
if ($type instanceof GenericObjectType) {
|
||||
$phpDocInfo->changeVarType($type);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\Repository;
|
||||
|
||||
if (class_exists('Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository')) {
|
||||
return;
|
||||
}
|
||||
|
||||
abstract class ServiceEntityRepository
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue
Block a user