rector/rules/DependencyInjection/NodeFactory/InjectMethodFactory.php
2021-05-10 22:10:16 +00:00

75 lines
2.8 KiB
PHP

<?php
declare (strict_types=1);
namespace Rector\DependencyInjection\NodeFactory;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\Type\ObjectType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\CodingStyle\Naming\ClassNaming;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\Core\ValueObject\FrameworkName;
use Rector\Naming\Naming\PropertyNaming;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use RectorPrefix20210510\Symplify\Astral\ValueObject\NodeBuilder\MethodBuilder;
use RectorPrefix20210510\Symplify\Astral\ValueObject\NodeBuilder\ParamBuilder;
final class InjectMethodFactory
{
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
/**
* @var PropertyNaming
*/
private $propertyNaming;
/**
* @var ClassNaming
*/
private $classNaming;
/**
* @var TypeFactory
*/
private $typeFactory;
/**
* @var NodeFactory
*/
private $nodeFactory;
public function __construct(ClassNaming $classNaming, NodeFactory $nodeFactory, PhpDocInfoFactory $phpDocInfoFactory, PropertyNaming $propertyNaming, TypeFactory $typeFactory)
{
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->propertyNaming = $propertyNaming;
$this->classNaming = $classNaming;
$this->typeFactory = $typeFactory;
$this->nodeFactory = $nodeFactory;
}
/**
* @param ObjectType[] $objectTypes
*/
public function createFromTypes(array $objectTypes, string $className, string $framework) : ClassMethod
{
$objectTypes = $this->typeFactory->uniquateTypes($objectTypes);
$shortClassName = $this->classNaming->getShortName($className);
$methodBuilder = new MethodBuilder('inject' . $shortClassName);
$methodBuilder->makePublic();
foreach ($objectTypes as $objectType) {
/** @var ObjectType $objectType */
$propertyName = $this->propertyNaming->fqnToVariableName($objectType);
$paramBuilder = new ParamBuilder($propertyName);
$paramBuilder->setType(new FullyQualified($objectType->getClassName()));
$methodBuilder->addParam($paramBuilder);
$assign = $this->nodeFactory->createPropertyAssignment($propertyName);
$methodBuilder->addStmt($assign);
}
$classMethod = $methodBuilder->getNode();
if ($framework === FrameworkName::SYMFONY) {
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
$phpDocInfo->addPhpDocTagNode(new PhpDocTagNode('@required', new GenericTagValueNode('')));
}
return $classMethod;
}
}