mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-28 23:10:51 +00:00
[Generic] Decouple rules to tailored sets (#5635)
Co-authored-by: kaizen-ci <info@kaizen-ci.org>
This commit is contained in:
parent
da535f7809
commit
13e33f0bff
|
@ -3,8 +3,8 @@
|
|||
declare(strict_types=1);
|
||||
|
||||
use Rector\Doctrine\Rector\Class_\AddEntityIdByConditionRector;
|
||||
use Rector\Generic\Rector\Class_\AddInterfaceByTraitRector;
|
||||
use Rector\Renaming\Rector\Name\RenameClassRector;
|
||||
use Rector\Transform\Rector\Class_\AddInterfaceByTraitRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
|
|
|
@ -6766,10 +6766,10 @@ Add interface by used trait
|
|||
|
||||
:wrench: **configure it!**
|
||||
|
||||
- class: `Rector\Generic\Rector\Class_\AddInterfaceByTraitRector`
|
||||
- class: `Rector\Transform\Rector\Class_\AddInterfaceByTraitRector`
|
||||
|
||||
```php
|
||||
use Rector\Generic\Rector\Class_\AddInterfaceByTraitRector;
|
||||
use Rector\Transform\Rector\Class_\AddInterfaceByTraitRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
|
@ -6840,7 +6840,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
Turns non-private properties with `@inject` to private properties and constructor injection
|
||||
|
||||
- class: `Rector\Generic\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector`
|
||||
- class: `Rector\DependencyInjection\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector`
|
||||
|
||||
```diff
|
||||
/**
|
||||
|
@ -6968,10 +6968,10 @@ Changes properties with specified annotations class to constructor injection
|
|||
|
||||
:wrench: **configure it!**
|
||||
|
||||
- class: `Rector\Generic\Rector\Property\InjectAnnotationClassRector`
|
||||
- class: `Rector\DependencyInjection\Rector\Property\InjectAnnotationClassRector`
|
||||
|
||||
```php
|
||||
use Rector\Generic\Rector\Property\InjectAnnotationClassRector;
|
||||
use Rector\DependencyInjection\Rector\Property\InjectAnnotationClassRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
|
@ -7015,10 +7015,10 @@ Merges old interface to a new one, that already has its methods
|
|||
|
||||
:wrench: **configure it!**
|
||||
|
||||
- class: `Rector\Generic\Rector\Class_\MergeInterfacesRector`
|
||||
- class: `Rector\Transform\Rector\Class_\MergeInterfacesRector`
|
||||
|
||||
```php
|
||||
use Rector\Generic\Rector\Class_\MergeInterfacesRector;
|
||||
use Rector\Transform\Rector\Class_\MergeInterfacesRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
|
|
|
@ -60,6 +60,11 @@ final class PhpDocInfoFactory
|
|||
*/
|
||||
private $rectorChangeCollector;
|
||||
|
||||
/**
|
||||
* @var array<string, PhpDocInfo>
|
||||
*/
|
||||
private $phpDocInfosByObjectHash = [];
|
||||
|
||||
public function __construct(
|
||||
AttributeAwareNodeFactory $attributeAwareNodeFactory,
|
||||
CurrentNodeProvider $currentNodeProvider,
|
||||
|
@ -96,6 +101,11 @@ final class PhpDocInfoFactory
|
|||
|
||||
public function createFromNode(Node $node): ?PhpDocInfo
|
||||
{
|
||||
$objectHash = spl_object_hash($node);
|
||||
if (isset($this->phpDocInfosByObjectHash[$objectHash])) {
|
||||
return $this->phpDocInfosByObjectHash[$objectHash];
|
||||
}
|
||||
|
||||
/** needed for @see PhpDocNodeFactoryInterface */
|
||||
$this->currentNodeProvider->setNode($node);
|
||||
|
||||
|
@ -112,6 +122,7 @@ final class PhpDocInfoFactory
|
|||
} else {
|
||||
$content = $docComment->getText();
|
||||
$tokens = $this->lexer->tokenize($content);
|
||||
|
||||
try {
|
||||
$phpDocNode = $this->parseTokensToPhpDocNode($tokens);
|
||||
} catch (ParserException $parserException) {
|
||||
|
@ -121,7 +132,10 @@ final class PhpDocInfoFactory
|
|||
$this->setPositionOfLastToken($phpDocNode);
|
||||
}
|
||||
|
||||
return $this->createFromPhpDocNode($phpDocNode, $content, $tokens, $node);
|
||||
$phpDocInfo = $this->createFromPhpDocNode($phpDocNode, $content, $tokens, $node);
|
||||
$this->phpDocInfosByObjectHash[$objectHash] = $phpDocInfo;
|
||||
|
||||
return $phpDocInfo;
|
||||
}
|
||||
|
||||
public function createEmpty(Node $node): PhpDocInfo
|
||||
|
|
|
@ -34,9 +34,10 @@ final class JMSInjectPhpDocNodeFactory extends AbstractPhpDocNodeFactory impleme
|
|||
private $tagValueNodePrinter;
|
||||
|
||||
public function __construct(
|
||||
NodeNameResolver $nodeNameResolver, ArrayPartPhpDocTagPrinter $arrayPartPhpDocTagPrinter,
|
||||
TagValueNodePrinter $tagValueNodePrinter)
|
||||
{
|
||||
NodeNameResolver $nodeNameResolver,
|
||||
ArrayPartPhpDocTagPrinter $arrayPartPhpDocTagPrinter,
|
||||
TagValueNodePrinter $tagValueNodePrinter
|
||||
) {
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->arrayPartPhpDocTagPrinter = $arrayPartPhpDocTagPrinter;
|
||||
$this->tagValueNodePrinter = $tagValueNodePrinter;
|
||||
|
|
|
@ -119,6 +119,7 @@ final class MultiPhpDocNodeFactory extends AbstractPhpDocNodeFactory implements
|
|||
SensioTemplateTagValueNode::class => 'Sensio\Bundle\FrameworkExtraBundle\Configuration\Template',
|
||||
SensioMethodTagValueNode::class => 'Sensio\Bundle\FrameworkExtraBundle\Configuration\Method',
|
||||
SensioRouteTagValueNode::class => 'Sensio\Bundle\FrameworkExtraBundle\Configuration\Route',
|
||||
|
||||
// JMS
|
||||
JMSInjectParamsTagValueNode::class => 'JMS\DiExtraBundle\Annotation\InjectParams',
|
||||
JMSServiceValueNode::class => 'JMS\DiExtraBundle\Annotation\Service',
|
||||
|
|
|
@ -140,7 +140,6 @@ final class BetterPhpDocParser extends PhpDocParser
|
|||
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_CLOSE_PHPDOC);
|
||||
|
||||
$phpDocNode = new PhpDocNode(array_values($children));
|
||||
|
||||
$docContent = $this->annotationContentResolver->resolveFromTokenIterator($originalTokenIterator);
|
||||
|
||||
return $this->attributeAwareNodeFactory->createFromNode($phpDocNode, $docContent);
|
||||
|
@ -160,6 +159,7 @@ final class BetterPhpDocParser extends PhpDocParser
|
|||
}
|
||||
|
||||
$phpDocTagValueNode = $this->parseTagValue($tokenIterator, $tag);
|
||||
|
||||
return new PhpDocTagNode($tag, $phpDocTagValueNode);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Nette\NetteInjectTagNode;
|
||||
use Rector\FamilyTree\NodeAnalyzer\ClassChildAnalyzer;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
final class NetteInjectPropertyAnalyzer
|
||||
{
|
||||
/**
|
||||
* @var ClassChildAnalyzer
|
||||
*/
|
||||
private $classChildAnalyzer;
|
||||
|
||||
public function __construct(ClassChildAnalyzer $classChildAnalyzer)
|
||||
{
|
||||
$this->classChildAnalyzer = $classChildAnalyzer;
|
||||
}
|
||||
|
||||
public function detect(Property $property, PhpDocInfo $phpDocInfo): bool
|
||||
{
|
||||
if (! $phpDocInfo->hasByType(NetteInjectTagNode::class)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$classLike = $property->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classLike instanceof Class_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($classLike->isAbstract()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->classChildAnalyzer->hasChildClassConstructor($classLike)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->classChildAnalyzer->hasParentClassConstructor($classLike)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// it needs @var tag as well, to get the type
|
||||
if ($phpDocInfo->getVarTagValueNode() !== null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $property->type !== null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Rector\Property;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\BetterPhpDocParser\Contract\PhpDocNode\ShortNameAwareTagInterface;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover;
|
||||
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\AbstractTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\JMS\JMSInjectTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Nette\NetteInjectTagNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\PHPDI\PHPDIInjectTagValueNode;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\DependencyInjection\NodeAnalyzer\NetteInjectPropertyAnalyzer;
|
||||
use Rector\DependencyInjection\TypeAnalyzer\InjectParameterAnalyzer;
|
||||
use Rector\DependencyInjection\TypeAnalyzer\InjectTagValueNodeToServiceTypeResolver;
|
||||
use Rector\FamilyTree\NodeAnalyzer\PropertyUsageAnalyzer;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* Can cover these cases:
|
||||
* - https://doc.nette.org/en/2.4/di-usage#toc-inject-annotations
|
||||
* - https://github.com/Kdyby/Autowired/blob/master/docs/en/index.md#autowired-properties
|
||||
* - http://jmsyst.com/bundles/JMSDiExtraBundle/master/annotations
|
||||
* - https://github.com/rectorphp/rector/issues/700#issue-370301169
|
||||
* - https://jmsyst.com/bundles/JMSDiExtraBundle/master/annotations#inject
|
||||
*
|
||||
* @see \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\AnnotatedPropertyInjectToConstructorInjectionRectorTest
|
||||
*/
|
||||
final class AnnotatedPropertyInjectToConstructorInjectionRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var array<class-string<ShortNameAwareTagInterface>>
|
||||
*/
|
||||
private const INJECT_TAG_VALUE_NODE_TYPES = [PHPDIInjectTagValueNode::class, JMSInjectTagValueNode::class];
|
||||
|
||||
/**
|
||||
* @var PropertyUsageAnalyzer
|
||||
*/
|
||||
private $propertyUsageAnalyzer;
|
||||
|
||||
/**
|
||||
* @var PhpDocTypeChanger
|
||||
*/
|
||||
private $phpDocTypeChanger;
|
||||
|
||||
/**
|
||||
* @var InjectParameterAnalyzer
|
||||
*/
|
||||
private $injectParameterAnalyzer;
|
||||
|
||||
/**
|
||||
* @var InjectTagValueNodeToServiceTypeResolver
|
||||
*/
|
||||
private $injectTagValueNodeToServiceTypeResolver;
|
||||
|
||||
/**
|
||||
* @var NetteInjectPropertyAnalyzer
|
||||
*/
|
||||
private $netteInjectPropertyAnalyzer;
|
||||
|
||||
/**
|
||||
* @var PhpDocTagRemover
|
||||
*/
|
||||
private $phpDocTagRemover;
|
||||
|
||||
public function __construct(
|
||||
PhpDocTypeChanger $phpDocTypeChanger,
|
||||
InjectParameterAnalyzer $injectParameterAnalyzer,
|
||||
InjectTagValueNodeToServiceTypeResolver $injectTagValueNodeToServiceTypeResolver,
|
||||
PropertyUsageAnalyzer $propertyUsageAnalyzer,
|
||||
NetteInjectPropertyAnalyzer $netteInjectPropertyAnalyzer,
|
||||
PhpDocTagRemover $phpDocTagRemover
|
||||
) {
|
||||
$this->propertyUsageAnalyzer = $propertyUsageAnalyzer;
|
||||
$this->phpDocTypeChanger = $phpDocTypeChanger;
|
||||
$this->injectParameterAnalyzer = $injectParameterAnalyzer;
|
||||
$this->injectTagValueNodeToServiceTypeResolver = $injectTagValueNodeToServiceTypeResolver;
|
||||
$this->netteInjectPropertyAnalyzer = $netteInjectPropertyAnalyzer;
|
||||
$this->phpDocTagRemover = $phpDocTagRemover;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
'Turns properties with `@inject` to private properties and constructor injection',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
/**
|
||||
* @var SomeService
|
||||
* @inject
|
||||
*/
|
||||
public $someService;
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
/**
|
||||
* @var SomeService
|
||||
*/
|
||||
private $someService;
|
||||
|
||||
public function __construct(SomeService $someService)
|
||||
{
|
||||
$this->someService = $someService;
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Property::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Property $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($node);
|
||||
if (! $phpDocInfo instanceof PhpDocInfo) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->netteInjectPropertyAnalyzer->detect($node, $phpDocInfo)) {
|
||||
return $this->refactorNetteInjectProperty($phpDocInfo, $node);
|
||||
}
|
||||
|
||||
foreach (self::INJECT_TAG_VALUE_NODE_TYPES as $tagValueNodeType) {
|
||||
$injectTagValueNode = $phpDocInfo->getByType($tagValueNodeType);
|
||||
if ($injectTagValueNode === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->injectParameterAnalyzer->isParameterInject($injectTagValueNode)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$serviceType = $this->injectTagValueNodeToServiceTypeResolver->resolve(
|
||||
$node,
|
||||
$phpDocInfo,
|
||||
$injectTagValueNode
|
||||
);
|
||||
if ($serviceType instanceof MixedType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->refactorPropertyWithAnnotation($node, $serviceType, $injectTagValueNode);
|
||||
|
||||
if ($this->isAtLeastPhpVersion(PhpVersionFeature::PROPERTY_PROMOTION)) {
|
||||
$this->removeNode($node);
|
||||
return null;
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function refactorPropertyWithAnnotation(
|
||||
Property $property,
|
||||
Type $type,
|
||||
AbstractTagValueNode $tagValueNode
|
||||
): void {
|
||||
$propertyName = $this->getName($property);
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
|
||||
$this->phpDocTypeChanger->changeVarType($phpDocInfo, $type);
|
||||
$this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $tagValueNode);
|
||||
|
||||
$classLike = $property->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classLike instanceof Class_) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->addConstructorDependencyToClass($classLike, $type, $propertyName, $property->flags);
|
||||
}
|
||||
|
||||
private function refactorNetteInjectProperty(PhpDocInfo $phpDocInfo, Property $property): ?Property
|
||||
{
|
||||
$phpDocInfo->removeByType(NetteInjectTagNode::class);
|
||||
|
||||
if ($this->propertyUsageAnalyzer->isPropertyFetchedInChildClass($property)) {
|
||||
$this->visibilityManipulator->makeProtected($property);
|
||||
} else {
|
||||
$this->visibilityManipulator->makePrivate($property);
|
||||
}
|
||||
|
||||
$this->addPropertyToCollector($property);
|
||||
|
||||
if ($this->isAtLeastPhpVersion(PhpVersionFeature::PROPERTY_PROMOTION)) {
|
||||
$this->removeNode($property);
|
||||
return null;
|
||||
}
|
||||
|
||||
return $property;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\TypeAnalyzer;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\JMS\JMSInjectTagValueNode;
|
||||
|
||||
final class InjectParameterAnalyzer
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/pjusUN/1
|
||||
*/
|
||||
private const BETWEEN_PERCENT_CHARS_REGEX = '#%(.*?)%#';
|
||||
|
||||
public function isParameterInject(PhpDocTagValueNode $phpDocTagValueNode): bool
|
||||
{
|
||||
if (! $phpDocTagValueNode instanceof JMSInjectTagValueNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$serviceName = $phpDocTagValueNode->getServiceName();
|
||||
if ($serviceName === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) Strings::match($serviceName, self::BETWEEN_PERCENT_CHARS_REGEX);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\TypeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\JMS\JMSInjectTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\PHPDI\PHPDIInjectTagValueNode;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
|
||||
final class InjectTagValueNodeToServiceTypeResolver
|
||||
{
|
||||
/**
|
||||
* @var JMSDITypeResolver
|
||||
*/
|
||||
private $jmsDITypeResolver;
|
||||
|
||||
public function __construct(JMSDITypeResolver $jmsDITypeResolver)
|
||||
{
|
||||
$this->jmsDITypeResolver = $jmsDITypeResolver;
|
||||
}
|
||||
|
||||
public function resolve(Property $property, PhpDocInfo $phpDocInfo, PhpDocTagValueNode $phpDocTagValueNode): Type
|
||||
{
|
||||
if ($phpDocTagValueNode instanceof JMSInjectTagValueNode) {
|
||||
return $this->jmsDITypeResolver->resolve($property, $phpDocTagValueNode);
|
||||
}
|
||||
|
||||
if ($phpDocTagValueNode instanceof PHPDIInjectTagValueNode) {
|
||||
return $phpDocInfo->getVarType();
|
||||
}
|
||||
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\TypeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\JMS\JMSInjectTagValueNode;
|
||||
use Rector\ChangesReporting\Application\ErrorAndDiffCollector;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\Symfony\ServiceMapProvider;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class JMSDITypeResolver
|
||||
{
|
||||
/**
|
||||
* @var ErrorAndDiffCollector
|
||||
*/
|
||||
private $errorAndDiffCollector;
|
||||
|
||||
/**
|
||||
* @var ServiceMapProvider
|
||||
*/
|
||||
private $serviceMapProvider;
|
||||
|
||||
/**
|
||||
* @var PhpDocInfoFactory
|
||||
*/
|
||||
private $phpDocInfoFactory;
|
||||
|
||||
public function __construct(
|
||||
ErrorAndDiffCollector $errorAndDiffCollector,
|
||||
ServiceMapProvider $serviceMapProvider,
|
||||
PhpDocInfoFactory $phpDocInfoFactory
|
||||
) {
|
||||
$this->errorAndDiffCollector = $errorAndDiffCollector;
|
||||
$this->serviceMapProvider = $serviceMapProvider;
|
||||
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||
}
|
||||
|
||||
public function resolve(Property $property, JMSInjectTagValueNode $jmsInjectTagValueNode): Type
|
||||
{
|
||||
$serviceMap = $this->serviceMapProvider->provide();
|
||||
$serviceName = $jmsInjectTagValueNode->getServiceName();
|
||||
|
||||
if ($serviceName) {
|
||||
if (class_exists($serviceName)) {
|
||||
// single class service
|
||||
return new ObjectType($serviceName);
|
||||
}
|
||||
|
||||
// 2. service name
|
||||
if ($serviceMap->hasService($serviceName)) {
|
||||
$serviceType = $serviceMap->getServiceType($serviceName);
|
||||
if ($serviceType !== null) {
|
||||
return $serviceType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. service is in @var annotation
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
|
||||
$varType = $phpDocInfo->getVarType();
|
||||
if (! $varType instanceof MixedType) {
|
||||
return $varType;
|
||||
}
|
||||
|
||||
// the @var is missing and service name was not found → report it
|
||||
$this->reportServiceNotFound($serviceName, $property);
|
||||
|
||||
return new MixedType();
|
||||
}
|
||||
|
||||
private function reportServiceNotFound(?string $serviceName, Property $property): void
|
||||
{
|
||||
if ($serviceName !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var SmartFileInfo $fileInfo */
|
||||
$fileInfo = $property->getAttribute(AttributeKey::FILE_INFO);
|
||||
|
||||
$errorMessage = sprintf('Service "%s" was not found in DI Container of your Symfony App.', $serviceName);
|
||||
|
||||
$this->errorAndDiffCollector->addErrorWithRectorClassMessageAndFileInfo(
|
||||
self::class,
|
||||
$errorMessage,
|
||||
$fileInfo
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Generic\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector;
|
||||
use Rector\DependencyInjection\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ChildPropertyCallProtected extends SomeParentWithInject
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return $this->someProductWith;
|
||||
}
|
||||
}
|
||||
|
||||
class SomeParentWithInject
|
||||
{
|
||||
/**
|
||||
* @inject
|
||||
* @var SomeProductWithInterface
|
||||
*/
|
||||
public $someProductWith;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ChildPropertyCallProtected extends SomeParentWithInject
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return $this->someProductWith;
|
||||
}
|
||||
}
|
||||
|
||||
class SomeParentWithInject
|
||||
{
|
||||
public function __construct(protected \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface $someProductWith)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use stdClass;
|
||||
use DateTimeInterface;
|
||||
|
@ -24,7 +24,7 @@ class ClassWithInjects
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use stdClass;
|
||||
use DateTimeInterface;
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ClassWithInjects4
|
||||
{
|
||||
/**
|
||||
* @var SomeProductWithInterface
|
||||
* @inject
|
||||
*/
|
||||
protected $property;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ClassWithInjects4
|
||||
{
|
||||
public function __construct(private \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface $property)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
class ClassWithInjects10ParentParent
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ class ClassWithInjects10 extends ClassWithInjects10Parent
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
class ClassWithInjects10ParentParent
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use DateTimeInterface;
|
||||
|
||||
|
@ -16,7 +16,7 @@ class ClassWithInjects8Parent
|
|||
class ClassWithInjects8 extends ClassWithInjects8Parent
|
||||
{
|
||||
/**
|
||||
* @var \Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct
|
||||
* @var \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct
|
||||
* @inject
|
||||
*/
|
||||
public $property;
|
||||
|
@ -26,7 +26,7 @@ class ClassWithInjects8 extends ClassWithInjects8Parent
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use DateTimeInterface;
|
||||
|
||||
|
@ -39,7 +39,7 @@ class ClassWithInjects8Parent
|
|||
|
||||
class ClassWithInjects8 extends ClassWithInjects8Parent
|
||||
{
|
||||
public function __construct(\DateTimeInterface $dateTime, private \Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct $property)
|
||||
public function __construct(\DateTimeInterface $dateTime, private \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct $property)
|
||||
{
|
||||
parent::__construct($dateTime);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithParent;
|
||||
|
||||
abstract class SkipAbstractClass
|
||||
{
|
||||
/**
|
||||
* @var SomeProductWithParent
|
||||
* @inject
|
||||
*/
|
||||
protected $property;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use DateTimeInterface;
|
||||
use stdClass;
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct;
|
||||
|
||||
class SkipIfHasChildren
|
||||
{
|
||||
/**
|
||||
* @var \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct
|
||||
* @inject
|
||||
*/
|
||||
public $someProduct;
|
||||
}
|
||||
|
||||
class ChildOfOneClass extends SkipIfHasChildren
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct;
|
||||
|
||||
class SkipIfHasParentWithConstructor extends ParentWithConstructor
|
||||
{
|
||||
/**
|
||||
* @var \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct
|
||||
* @inject
|
||||
*/
|
||||
public $someProduct;
|
||||
}
|
||||
|
||||
class ParentWithConstructor
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SkipPropertyWithoutDoc
|
||||
{
|
||||
public $property;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixturePhp74;
|
||||
|
||||
use stdClass;
|
||||
|
||||
class TypedProperty
|
||||
{
|
||||
/**
|
||||
* @inject
|
||||
*/
|
||||
public stdClass $property;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixturePhp74;
|
||||
|
||||
use stdClass;
|
||||
|
||||
class TypedProperty
|
||||
{
|
||||
public function __construct(private \stdClass $property)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
|
||||
|
@ -16,7 +16,7 @@ class ClassWithInjects35
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeInterface;
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ClassWithInjects7
|
||||
{
|
||||
/**
|
||||
* @var SomeInterface
|
||||
* @DI\Inject("irelevant")
|
||||
*/
|
||||
private $session;
|
||||
|
||||
/**
|
||||
* @var SomeProductWithInterface
|
||||
* @DI\Inject
|
||||
*/
|
||||
private $product;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeInterface;
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ClassWithInjects7
|
||||
{
|
||||
public function __construct(private \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeInterface $session, private \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface $product)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
|
||||
|
@ -16,7 +16,7 @@ class ClassWithPublicInjects
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromVar
|
||||
{
|
||||
/**
|
||||
* @Inject
|
||||
* @var \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\ExistingDependency
|
||||
*/
|
||||
private $someDependency;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromVar
|
||||
{
|
||||
public function __construct(private \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\ExistingDependency $someDependency)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromProtectedVar
|
||||
{
|
||||
/**
|
||||
* @Inject
|
||||
* @var \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\ExistingDependency
|
||||
*/
|
||||
protected $someDependency;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromProtectedVar
|
||||
{
|
||||
public function __construct(protected \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\ExistingDependency $someDependency)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\DifferntButFirstListed\Bar as FooBarFirst;
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\Bar;
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\Foo;
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\DifferntButFirstListed\Foo as BarFooLast;
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromVarWithTypeOfSameName
|
||||
{
|
||||
/**
|
||||
* @Inject
|
||||
*
|
||||
* @var Bar
|
||||
*/
|
||||
private $someBarDependency;
|
||||
|
||||
/**
|
||||
* @Inject
|
||||
*
|
||||
* @var Foo
|
||||
*/
|
||||
private $someFooDependency;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\DifferntButFirstListed\Bar as FooBarFirst;
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\Bar;
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\Foo;
|
||||
use Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\DifferntButFirstListed\Foo as BarFooLast;
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromVarWithTypeOfSameName
|
||||
{
|
||||
public function __construct(private \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\Bar $someBarDependency, private \Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\Foo $someFooDependency)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
|
||||
class SomeController
|
||||
final class SomeController
|
||||
{
|
||||
/**
|
||||
* @DI\Inject("entity.manager")
|
||||
|
@ -21,11 +21,11 @@ class SomeController
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
|
||||
class SomeController
|
||||
final class SomeController
|
||||
{
|
||||
public function __construct(private \Rector\Symfony\Tests\Rector\MethodCall\AbstractToConstructorInjectionRectorSource\SomeEntityManager $entityManager, private \Rector\Symfony\Tests\Rector\MethodCall\AbstractToConstructorInjectionRectorSource\Contract\SomeTranslatorInterface $translator)
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
|
||||
|
@ -16,7 +16,7 @@ class SomeController2
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixtureTagValueNodes;
|
||||
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Generic\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector;
|
||||
use Rector\DependencyInjection\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
final class Bar
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\DifferntButFirstListed;
|
||||
|
||||
final class Bar
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\DifferntButFirstListed;
|
||||
|
||||
final class Foo
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
final class ExistingDependency
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
final class Foo
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
interface SomeInterface
|
||||
{
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
class SomeParent
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
final class SomeProduct
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
final class SomeProductWithInterface implements SomeInterface
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
final class SomeProductWithParent extends SomeParent
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
final class SomeProductWithTrait
|
||||
{
|
||||
use SomeTrait;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
trait SomeTrait
|
||||
{
|
||||
}
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector;
|
||||
namespace Rector\DependencyInjection\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class InjectAnnotationClassRectorTest extends AbstractRectorTestCase
|
||||
final class TagValueNodesTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
|
@ -20,7 +20,7 @@ final class InjectAnnotationClassRectorTest extends AbstractRectorTestCase
|
|||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/FixtureTagValueNodes');
|
||||
}
|
||||
|
||||
protected function provideConfigFilePath(): string
|
|
@ -1,8 +1,9 @@
|
|||
<?php
|
||||
|
||||
use JMS\DiExtraBundle\Annotation\Inject;
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Generic\Rector\Property\InjectAnnotationClassRector;
|
||||
use Rector\DependencyInjection\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
|
@ -13,8 +14,5 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
);
|
||||
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(InjectAnnotationClassRector::class)
|
||||
->call('configure', [[
|
||||
InjectAnnotationClassRector::ANNOTATION_CLASSES => [Inject::class, \DI\Annotation\Inject::class],
|
||||
]]);
|
||||
$services->set(AnnotatedPropertyInjectToConstructorInjectionRector::class);
|
||||
};
|
|
@ -1,150 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Rector\Property;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\Nette\NetteInjectTagNode;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\FamilyTree\NodeAnalyzer\ClassChildAnalyzer;
|
||||
use Rector\FamilyTree\NodeAnalyzer\PropertyUsageAnalyzer;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* Can cover these cases:
|
||||
* - https://doc.nette.org/en/2.4/di-usage#toc-inject-annotations
|
||||
* - https://github.com/Kdyby/Autowired/blob/master/docs/en/index.md#autowired-properties
|
||||
* - http://jmsyst.com/bundles/JMSDiExtraBundle/master/annotations
|
||||
* - https://github.com/rectorphp/rector/issues/700#issue-370301169
|
||||
*
|
||||
* @see \Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\AnnotatedPropertyInjectToConstructorInjectionRectorTest
|
||||
*/
|
||||
final class AnnotatedPropertyInjectToConstructorInjectionRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var PropertyUsageAnalyzer
|
||||
*/
|
||||
private $propertyUsageAnalyzer;
|
||||
|
||||
/**
|
||||
* @var ClassChildAnalyzer
|
||||
*/
|
||||
private $classChildAnalyzer;
|
||||
|
||||
public function __construct(
|
||||
ClassChildAnalyzer $classChildAnalyzer,
|
||||
PropertyUsageAnalyzer $propertyUsageAnalyzer
|
||||
) {
|
||||
$this->propertyUsageAnalyzer = $propertyUsageAnalyzer;
|
||||
$this->classChildAnalyzer = $classChildAnalyzer;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
'Turns non-private properties with `@inject` to private properties and constructor injection',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
/**
|
||||
* @var SomeService
|
||||
* @inject
|
||||
*/
|
||||
public $someService;
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
/**
|
||||
* @var SomeService
|
||||
*/
|
||||
private $someService;
|
||||
|
||||
public function __construct(SomeService $someService)
|
||||
{
|
||||
$this->someService = $someService;
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Property::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Property $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($this->shouldSkipProperty($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||
$phpDocInfo->removeByType(NetteInjectTagNode::class);
|
||||
|
||||
if ($this->propertyUsageAnalyzer->isPropertyFetchedInChildClass($node)) {
|
||||
$this->visibilityManipulator->makeProtected($node);
|
||||
} else {
|
||||
$this->visibilityManipulator->makePrivate($node);
|
||||
}
|
||||
|
||||
$this->addPropertyToCollector($node);
|
||||
|
||||
if ($this->isAtLeastPhpVersion(PhpVersionFeature::PROPERTY_PROMOTION)) {
|
||||
$this->removeNode($node);
|
||||
return null;
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function shouldSkipProperty(Property $property): bool
|
||||
{
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
if (! $phpDocInfo->hasByType(NetteInjectTagNode::class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$classLike = $property->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classLike instanceof ClassLike) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! $classLike instanceof Class_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($classLike->isAbstract()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->classChildAnalyzer->hasChildClassConstructor($classLike)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->classChildAnalyzer->hasParentClassConstructor($classLike)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// it needs @var tag as well, to get the type
|
||||
if ($phpDocInfo->getVarTagValueNode() !== null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $property->type === null;
|
||||
}
|
||||
}
|
|
@ -1,294 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Rector\Property;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
|
||||
use PHPStan\Type\MixedType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\JMS\JMSInjectTagValueNode;
|
||||
use Rector\BetterPhpDocParser\ValueObject\PhpDocNode\PHPDI\PHPDIInjectTagValueNode;
|
||||
use Rector\ChangesReporting\Application\ErrorAndDiffCollector;
|
||||
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
|
||||
use Rector\Core\Exception\NotImplementedYetException;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\Symfony\ServiceMapProvider;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
/**
|
||||
* @see https://jmsyst.com/bundles/JMSDiExtraBundle/master/annotations#inject
|
||||
*
|
||||
* @see \Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\InjectAnnotationClassRectorTest
|
||||
*/
|
||||
final class InjectAnnotationClassRector extends AbstractRector implements ConfigurableRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const ANNOTATION_CLASSES = 'annotation_classes';
|
||||
|
||||
/**
|
||||
* @var array<string, class-string<JMSInjectTagValueNode>|class-string<PHPDIInjectTagValueNode>>
|
||||
*/
|
||||
private const ANNOTATION_TO_TAG_CLASS = [
|
||||
'DI\Annotation\Inject' => PHPDIInjectTagValueNode::class,
|
||||
'JMS\DiExtraBundle\Annotation\Inject' => JMSInjectTagValueNode::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/pjusUN/1
|
||||
*/
|
||||
private const BETWEEN_PERCENT_CHARS_REGEX = '#%(.*?)%#';
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $annotationClasses = [];
|
||||
|
||||
/**
|
||||
* @var ErrorAndDiffCollector
|
||||
*/
|
||||
private $errorAndDiffCollector;
|
||||
|
||||
/**
|
||||
* @var ServiceMapProvider
|
||||
*/
|
||||
private $serviceMapProvider;
|
||||
|
||||
/**
|
||||
* @var PhpDocTypeChanger
|
||||
*/
|
||||
private $phpDocTypeChanger;
|
||||
|
||||
public function __construct(
|
||||
ServiceMapProvider $serviceMapProvider,
|
||||
ErrorAndDiffCollector $errorAndDiffCollector,
|
||||
PhpDocTypeChanger $phpDocTypeChanger
|
||||
) {
|
||||
$this->errorAndDiffCollector = $errorAndDiffCollector;
|
||||
$this->serviceMapProvider = $serviceMapProvider;
|
||||
$this->phpDocTypeChanger = $phpDocTypeChanger;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
'Changes properties with specified annotations class to constructor injection',
|
||||
[
|
||||
new ConfiguredCodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
|
||||
class SomeController
|
||||
{
|
||||
/**
|
||||
* @DI\Inject("entity.manager")
|
||||
*/
|
||||
private $entityManager;
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
|
||||
class SomeController
|
||||
{
|
||||
/**
|
||||
* @var EntityManager
|
||||
*/
|
||||
private $entityManager;
|
||||
|
||||
public function __construct(EntityManager $entityManager)
|
||||
{
|
||||
$this->entityManager = entityManager;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
[
|
||||
self::ANNOTATION_CLASSES => ['DI\Annotation\Inject', 'JMS\DiExtraBundle\Annotation\Inject'],
|
||||
]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Property::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Property $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||
foreach ($this->annotationClasses as $annotationClass) {
|
||||
$this->ensureAnnotationClassIsSupported($annotationClass);
|
||||
|
||||
$tagClass = self::ANNOTATION_TO_TAG_CLASS[$annotationClass];
|
||||
|
||||
$injectTagValueNode = $phpDocInfo->getByType($tagClass);
|
||||
if ($injectTagValueNode === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isParameterInject($injectTagValueNode)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$type = $this->resolveType($node, $injectTagValueNode);
|
||||
|
||||
return $this->refactorPropertyWithAnnotation($node, $type, $tagClass);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function configure(array $configuration): void
|
||||
{
|
||||
$this->annotationClasses = $configuration[self::ANNOTATION_CLASSES] ?? [];
|
||||
}
|
||||
|
||||
private function ensureAnnotationClassIsSupported(string $annotationClass): void
|
||||
{
|
||||
if (isset(self::ANNOTATION_TO_TAG_CLASS[$annotationClass])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$availableAnnotations = array_keys(self::ANNOTATION_TO_TAG_CLASS);
|
||||
$errorMessage = sprintf(
|
||||
'Annotation class "%s" is not implemented yet. Use one of "%s" or add custom tag for it to Rector.',
|
||||
$annotationClass,
|
||||
implode('", "', $availableAnnotations)
|
||||
);
|
||||
|
||||
throw new NotImplementedYetException($errorMessage);
|
||||
}
|
||||
|
||||
private function isParameterInject(PhpDocTagValueNode $phpDocTagValueNode): bool
|
||||
{
|
||||
if (! $phpDocTagValueNode instanceof JMSInjectTagValueNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$serviceName = $phpDocTagValueNode->getServiceName();
|
||||
|
||||
if ($serviceName === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) Strings::match($serviceName, self::BETWEEN_PERCENT_CHARS_REGEX);
|
||||
}
|
||||
|
||||
private function resolveType(Property $property, PhpDocTagValueNode $phpDocTagValueNode): Type
|
||||
{
|
||||
if ($phpDocTagValueNode instanceof JMSInjectTagValueNode) {
|
||||
return $this->resolveJMSDIInjectType($property, $phpDocTagValueNode);
|
||||
}
|
||||
|
||||
if ($phpDocTagValueNode instanceof PHPDIInjectTagValueNode) {
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
return $phpDocInfo->getVarType();
|
||||
}
|
||||
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
private function refactorPropertyWithAnnotation(Property $property, Type $type, string $tagClass): ?Property
|
||||
{
|
||||
if ($type instanceof MixedType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$propertyName = $this->getName($property);
|
||||
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
|
||||
$this->phpDocTypeChanger->changeVarType($phpDocInfo, $type);
|
||||
$phpDocInfo->removeByType($tagClass);
|
||||
|
||||
$classLike = $property->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $classLike instanceof Class_) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$this->addConstructorDependencyToClass($classLike, $type, $propertyName, $property->flags);
|
||||
|
||||
if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::PROPERTY_PROMOTION)) {
|
||||
$this->removeNode($property);
|
||||
return null;
|
||||
}
|
||||
|
||||
return $property;
|
||||
}
|
||||
|
||||
private function resolveJMSDIInjectType(Property $property, JMSInjectTagValueNode $jmsInjectTagValueNode): Type
|
||||
{
|
||||
$serviceMap = $this->serviceMapProvider->provide();
|
||||
$serviceName = $jmsInjectTagValueNode->getServiceName();
|
||||
|
||||
if ($serviceName) {
|
||||
if (class_exists($serviceName)) {
|
||||
// single class service
|
||||
return new ObjectType($serviceName);
|
||||
}
|
||||
|
||||
// 2. service name
|
||||
if ($serviceMap->hasService($serviceName)) {
|
||||
$serviceType = $serviceMap->getServiceType($serviceName);
|
||||
if ($serviceType !== null) {
|
||||
return $serviceType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. service is in @var annotation
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
|
||||
|
||||
$varType = $phpDocInfo->getVarType();
|
||||
if (! $varType instanceof MixedType) {
|
||||
return $varType;
|
||||
}
|
||||
|
||||
// the @var is missing and service name was not found → report it
|
||||
$this->reportServiceNotFound($serviceName, $property);
|
||||
|
||||
return new MixedType();
|
||||
}
|
||||
|
||||
private function reportServiceNotFound(?string $serviceName, Property $property): void
|
||||
{
|
||||
if ($serviceName !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var SmartFileInfo $fileInfo */
|
||||
$fileInfo = $property->getAttribute(AttributeKey::FILE_INFO);
|
||||
|
||||
$errorMessage = sprintf('Service "%s" was not found in DI Container of your Symfony App.', $serviceName);
|
||||
|
||||
$this->errorAndDiffCollector->addErrorWithRectorClassMessageAndFileInfo(
|
||||
self::class,
|
||||
$errorMessage,
|
||||
$fileInfo
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeTrait;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
use SomeTrait;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeTrait;
|
||||
|
||||
class SomeClass implements \Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeInterface
|
||||
{
|
||||
use SomeTrait;
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeInterface;
|
||||
use Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeTrait;
|
||||
|
||||
class SkipExisting implements SomeInterface
|
||||
{
|
||||
use SomeTrait;
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Source;
|
||||
|
||||
interface SomeInterface
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Source;
|
||||
|
||||
trait SomeTrait
|
||||
{
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeInterface;
|
||||
use Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeOldInterface;
|
||||
|
||||
class SomeClass implements SomeInterface, SomeOldInterface
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeInterface;
|
||||
use Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeOldInterface;
|
||||
|
||||
class SomeClass implements SomeInterface
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeOldInterface;
|
||||
|
||||
class SomeClass2 implements SomeOldInterface
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeOldInterface;
|
||||
|
||||
class SomeClass2 implements Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeInterface
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Source;
|
||||
|
||||
interface SomeInterface
|
||||
{
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Source;
|
||||
|
||||
interface SomeOldInterface
|
||||
{
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ChildPropertyCallProtected extends SomeParentWithInject
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return $this->someProductWith;
|
||||
}
|
||||
}
|
||||
|
||||
class SomeParentWithInject
|
||||
{
|
||||
/**
|
||||
* @inject
|
||||
* @var SomeProductWithInterface
|
||||
*/
|
||||
public $someProductWith;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ChildPropertyCallProtected extends SomeParentWithInject
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return $this->someProductWith;
|
||||
}
|
||||
}
|
||||
|
||||
class SomeParentWithInject
|
||||
{
|
||||
public function __construct(protected \Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface $someProductWith)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ClassWithInjects4
|
||||
{
|
||||
/**
|
||||
* @var SomeProductWithInterface
|
||||
* @inject
|
||||
*/
|
||||
protected $property;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ClassWithInjects4
|
||||
{
|
||||
public function __construct(private \Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface $property)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithParent;
|
||||
|
||||
abstract class SkipAbstractClass
|
||||
{
|
||||
/**
|
||||
* @var SomeProductWithParent
|
||||
* @inject
|
||||
*/
|
||||
protected $property;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct;
|
||||
|
||||
class SkipIfHasChildren
|
||||
{
|
||||
/**
|
||||
* @var \Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct
|
||||
* @inject
|
||||
*/
|
||||
public $someProduct;
|
||||
}
|
||||
|
||||
class ChildOfOneClass extends SkipIfHasChildren
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct;
|
||||
|
||||
class SkipIfHasParentWithConstructor extends ParentWithConstructor
|
||||
{
|
||||
/**
|
||||
* @var \Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProduct
|
||||
* @inject
|
||||
*/
|
||||
public $someProduct;
|
||||
}
|
||||
|
||||
class ParentWithConstructor
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Fixture;
|
||||
|
||||
class SkipPropertyWithoutDoc
|
||||
{
|
||||
public $property;
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixturePhp74;
|
||||
|
||||
use stdClass;
|
||||
|
||||
class TypedProperty
|
||||
{
|
||||
/**
|
||||
* @inject
|
||||
*/
|
||||
public stdClass $property;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\FixturePhp74;
|
||||
|
||||
use stdClass;
|
||||
|
||||
class TypedProperty
|
||||
{
|
||||
public function __construct(private \stdClass $property)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
interface SomeInterface
|
||||
{
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
class SomeParent
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
final class SomeProduct
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
final class SomeProductWithInterface implements SomeInterface
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
final class SomeProductWithParent extends SomeParent
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
final class SomeProductWithTrait
|
||||
{
|
||||
use SomeTrait;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source;
|
||||
|
||||
trait SomeTrait
|
||||
{
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeInterface;
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
use Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ClassWithInjects7
|
||||
{
|
||||
/**
|
||||
* @var SomeInterface
|
||||
* @DI\Inject("irelevant")
|
||||
*/
|
||||
private $session;
|
||||
|
||||
/**
|
||||
* @var SomeProductWithInterface
|
||||
* @DI\Inject
|
||||
*/
|
||||
private $product;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeInterface;
|
||||
use JMS\DiExtraBundle\Annotation as DI;
|
||||
use Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface;
|
||||
|
||||
class ClassWithInjects7
|
||||
{
|
||||
public function __construct(private \Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeInterface $session, private \Rector\Generic\Tests\Rector\Property\AnnotatedPropertyInjectToConstructorInjectionRector\Source\SomeProductWithInterface $product)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromVar
|
||||
{
|
||||
/**
|
||||
* @Inject
|
||||
* @var \Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\ExistingDependency
|
||||
*/
|
||||
private $someDependency;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromVar
|
||||
{
|
||||
public function __construct(private \Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\ExistingDependency $someDependency)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromProtectedVar
|
||||
{
|
||||
/**
|
||||
* @Inject
|
||||
* @var \Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\ExistingDependency
|
||||
*/
|
||||
protected $someDependency;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromProtectedVar
|
||||
{
|
||||
public function __construct(protected \Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\ExistingDependency $someDependency)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\DifferntButFirstListed\Bar as FooBarFirst;
|
||||
use Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\Bar;
|
||||
use Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\Foo;
|
||||
use Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\DifferntButFirstListed\Foo as BarFooLast;
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromVarWithTypeOfSameName
|
||||
{
|
||||
/**
|
||||
* @Inject
|
||||
*
|
||||
* @var Bar
|
||||
*/
|
||||
private $someBarDependency;
|
||||
|
||||
/**
|
||||
* @Inject
|
||||
*
|
||||
* @var Foo
|
||||
*/
|
||||
private $someFooDependency;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Fixture;
|
||||
|
||||
use Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\DifferntButFirstListed\Bar as FooBarFirst;
|
||||
use Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\Bar;
|
||||
use Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\Foo;
|
||||
use Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\DifferntButFirstListed\Foo as BarFooLast;
|
||||
use DI\Annotation\Inject;
|
||||
|
||||
class InjectFromVarWithTypeOfSameName
|
||||
{
|
||||
public function __construct(private \Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\Bar $someBarDependency, private \Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\Foo $someFooDependency)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source;
|
||||
|
||||
final class Bar
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\DifferntButFirstListed;
|
||||
|
||||
final class Bar
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source\DifferntButFirstListed;
|
||||
|
||||
final class Foo
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source;
|
||||
|
||||
final class ExistingDependency
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Property\InjectAnnotationClassRector\Source;
|
||||
|
||||
final class Foo
|
||||
{
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Rector\Class_;
|
||||
namespace Rector\Transform\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
|
@ -14,14 +14,14 @@ use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
|||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\AddInterfaceByTraitRectorTest
|
||||
* @see \Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\AddInterfaceByTraitRectorTest
|
||||
*/
|
||||
final class AddInterfaceByTraitRector extends AbstractRector implements ConfigurableRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const INTERFACE_BY_TRAIT = '$interfaceByTrait';
|
||||
public const INTERFACE_BY_TRAIT = 'interface_by_trait';
|
||||
|
||||
/**
|
||||
* @var string[]
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Rector\Class_;
|
||||
namespace Rector\Transform\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name;
|
||||
|
@ -17,7 +17,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
* - https://github.com/FriendsOfPHP/PHP-CS-Fixer/commit/a1cdb4d2dd8f45d731244eed406e1d537218cc66
|
||||
* - https://github.com/FriendsOfPHP/PHP-CS-Fixer/commit/614d2e6f7af5a5b0be5363ff536aed2b7ee5a31d
|
||||
*
|
||||
* @see \Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\MergeInterfacesRectorTest
|
||||
* @see \Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\MergeInterfacesRectorTest
|
||||
*/
|
||||
final class MergeInterfacesRector extends AbstractRector implements ConfigurableRectorInterface
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector;
|
||||
namespace Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Fixture;
|
||||
|
||||
use Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeTrait;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
use SomeTrait;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Fixture;
|
||||
|
||||
use Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeTrait;
|
||||
|
||||
class SomeClass implements \Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeInterface
|
||||
{
|
||||
use SomeTrait;
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Fixture;
|
||||
|
||||
use Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeInterface;
|
||||
use Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeTrait;
|
||||
|
||||
class SkipExisting implements SomeInterface
|
||||
{
|
||||
use SomeTrait;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Source;
|
||||
|
||||
interface SomeInterface
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Source;
|
||||
|
||||
trait SomeTrait
|
||||
{
|
||||
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
use Rector\Generic\Rector\Class_\AddInterfaceByTraitRector;
|
||||
use Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeInterface;
|
||||
use Rector\Generic\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeTrait;
|
||||
use Rector\Transform\Rector\Class_\AddInterfaceByTraitRector;
|
||||
use Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeInterface;
|
||||
use Rector\Transform\Tests\Rector\Class_\AddInterfaceByTraitRector\Source\SomeTrait;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Fixture;
|
||||
|
||||
use Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeInterface;
|
||||
use Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeOldInterface;
|
||||
|
||||
class SomeClass implements SomeInterface, SomeOldInterface
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Fixture;
|
||||
|
||||
use Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeInterface;
|
||||
use Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeOldInterface;
|
||||
|
||||
class SomeClass implements SomeInterface
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Fixture;
|
||||
|
||||
use Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeOldInterface;
|
||||
|
||||
class SomeClass2 implements SomeOldInterface
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Fixture;
|
||||
|
||||
use Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeOldInterface;
|
||||
|
||||
class SomeClass2 implements Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeInterface
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector;
|
||||
namespace Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Source;
|
||||
|
||||
interface SomeInterface
|
||||
{
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Source;
|
||||
|
||||
interface SomeOldInterface
|
||||
{
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
use Rector\Generic\Rector\Class_\MergeInterfacesRector;
|
||||
use Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeInterface;
|
||||
use Rector\Generic\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeOldInterface;
|
||||
use Rector\Transform\Rector\Class_\MergeInterfacesRector;
|
||||
use Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeInterface;
|
||||
use Rector\Transform\Tests\Rector\Class_\MergeInterfacesRector\Source\SomeOldInterface;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
Loading…
Reference in New Issue
Block a user