mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-30 06:33:31 +00:00
decouple ParamTypeInferer
This commit is contained in:
parent
f9c44ec25e
commit
328fb06ee2
|
@ -12,8 +12,8 @@ use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
|||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
use Rector\TypeDeclaration\Contract\TypeInferer\ParamTypeInfererInterface;
|
||||
use Rector\TypeDeclaration\PhpDocParser\ParamPhpDocNodeFactory;
|
||||
use Rector\TypeDeclaration\TypeInferer\ParamTypeInferer;
|
||||
|
||||
/**
|
||||
* @sponsor Thanks https://spaceflow.io/ for sponsoring this rule - visit them on https://github.com/SpaceFlow-app
|
||||
|
@ -26,27 +26,24 @@ final class AddArrayParamDocTypeRector extends AbstractRector
|
|||
*/
|
||||
private $docBlockManipulator;
|
||||
|
||||
/**
|
||||
* @var ParamTypeInfererInterface[]
|
||||
*/
|
||||
private $paramTypeInferers = [];
|
||||
|
||||
/**
|
||||
* @var ParamPhpDocNodeFactory
|
||||
*/
|
||||
private $paramPhpDocNodeFactory;
|
||||
|
||||
/**
|
||||
* @param ParamTypeInfererInterface[] $paramTypeInferers
|
||||
* @var ParamTypeInferer
|
||||
*/
|
||||
private $paramTypeInferer;
|
||||
|
||||
public function __construct(
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
array $paramTypeInferers,
|
||||
ParamPhpDocNodeFactory $paramPhpDocNodeFactory
|
||||
ParamPhpDocNodeFactory $paramPhpDocNodeFactory,
|
||||
ParamTypeInferer $paramTypeInferer
|
||||
) {
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->paramTypeInferers = $paramTypeInferers;
|
||||
$this->paramPhpDocNodeFactory = $paramPhpDocNodeFactory;
|
||||
$this->paramTypeInferer = $paramTypeInferer;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
|
@ -114,15 +111,7 @@ CODE_SAMPLE
|
|||
return null;
|
||||
}
|
||||
|
||||
$types = [];
|
||||
foreach ($this->paramTypeInferers as $paramTypeInferer) {
|
||||
$types = $paramTypeInferer->inferParam($param);
|
||||
if ($types !== []) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// no types :/
|
||||
$types = $this->paramTypeInferer->inferParam($param);
|
||||
if ($types === []) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
|||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
use Rector\TypeDeclaration\Contract\TypeInferer\ReturnTypeInfererInterface;
|
||||
use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer;
|
||||
|
||||
/**
|
||||
|
@ -27,9 +26,6 @@ final class AddArrayReturnDocTypeRector extends AbstractRector
|
|||
*/
|
||||
private $returnTypeInferer;
|
||||
|
||||
/**
|
||||
* @param ReturnTypeInfererInterface[] $docBlockManipulator
|
||||
*/
|
||||
public function __construct(DocBlockManipulator $docBlockManipulator, ReturnTypeInferer $returnTypeInferer)
|
||||
{
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
|
|
|
@ -10,6 +10,7 @@ use PhpParser\Node\Stmt\Function_;
|
|||
use Rector\Exception\ShouldNotHappenException;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\Php\ReturnTypeInfo;
|
||||
use Rector\Php\TypeAnalyzer;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
use Rector\TypeDeclaration\ReturnTypeResolver\ReturnTypeResolver;
|
||||
|
@ -32,10 +33,19 @@ final class ReturnTypeDeclarationRector extends AbstractTypeDeclarationRector
|
|||
*/
|
||||
private $returnTypeInferer;
|
||||
|
||||
public function __construct(ReturnTypeResolver $returnTypeResolver, ReturnTypeInferer $returnTypeInferer)
|
||||
{
|
||||
/**
|
||||
* @var TypeAnalyzer
|
||||
*/
|
||||
private $typeAnalyzer;
|
||||
|
||||
public function __construct(
|
||||
ReturnTypeResolver $returnTypeResolver,
|
||||
ReturnTypeInferer $returnTypeInferer,
|
||||
TypeAnalyzer $typeAnalyzer
|
||||
) {
|
||||
$this->returnTypeResolver = $returnTypeResolver;
|
||||
$this->returnTypeInferer = $returnTypeInferer;
|
||||
$this->typeAnalyzer = $typeAnalyzer;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
|
@ -128,11 +138,12 @@ CODE_SAMPLE
|
|||
}
|
||||
}
|
||||
} else {
|
||||
$inferedTypes = $this->returnTypeInferer->inferFunctionLike($node);
|
||||
dump($inferedTypes);
|
||||
|
||||
dump($returnTypeInfo->getTypeNode());
|
||||
die;
|
||||
if ($returnTypeInfo->getTypeNode() === null) {
|
||||
$inferedTypes = $this->returnTypeInferer->inferFunctionLike($node);
|
||||
if ($inferedTypes) {
|
||||
$returnTypeInfo = new ReturnTypeInfo($inferedTypes, $this->typeAnalyzer, $inferedTypes);
|
||||
}
|
||||
}
|
||||
|
||||
$node->returnType = $returnTypeInfo->getTypeNode();
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@ use PhpParser\Node\Stmt\Property;
|
|||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
use Rector\TypeDeclaration\Contract\TypeInferer\PropertyTypeInfererInterface;
|
||||
use Rector\TypeDeclaration\Exception\ConflictingPriorityException;
|
||||
use Rector\TypeDeclaration\TypeInferer\PropertyTypeInferer;
|
||||
use Rector\TypeDeclaration\ValueObject\IdentifierValueObject;
|
||||
|
||||
/**
|
||||
|
@ -24,18 +23,14 @@ final class PropertyTypeDeclarationRector extends AbstractRector
|
|||
private $docBlockManipulator;
|
||||
|
||||
/**
|
||||
* @var PropertyTypeInfererInterface[]
|
||||
* @var PropertyTypeInferer
|
||||
*/
|
||||
private $propertyTypeInferers = [];
|
||||
private $propertyTypeInferer;
|
||||
|
||||
/**
|
||||
* @param PropertyTypeInfererInterface[] $propertyTypeInferers
|
||||
*/
|
||||
public function __construct(DocBlockManipulator $docBlockManipulator, array $propertyTypeInferers = [])
|
||||
public function __construct(DocBlockManipulator $docBlockManipulator, PropertyTypeInferer $propertyTypeInferer)
|
||||
{
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
|
||||
$this->sortAndSetPropertyTypeInferers($propertyTypeInferers);
|
||||
$this->propertyTypeInferer = $propertyTypeInferer;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
|
@ -64,12 +59,10 @@ final class PropertyTypeDeclarationRector extends AbstractRector
|
|||
return null;
|
||||
}
|
||||
|
||||
foreach ($this->propertyTypeInferers as $propertyTypeInferer) {
|
||||
$types = $propertyTypeInferer->inferProperty($node);
|
||||
if ($types) {
|
||||
$this->setNodeVarTypes($node, $types);
|
||||
return $node;
|
||||
}
|
||||
$types = $this->propertyTypeInferer->inferProperty($node);
|
||||
if ($types) {
|
||||
$this->setNodeVarTypes($node, $types);
|
||||
return $node;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -84,28 +77,4 @@ final class PropertyTypeDeclarationRector extends AbstractRector
|
|||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PropertyTypeInfererInterface[] $propertyTypeInferers
|
||||
*/
|
||||
private function sortAndSetPropertyTypeInferers(array $propertyTypeInferers): void
|
||||
{
|
||||
foreach ($propertyTypeInferers as $propertyTypeInferer) {
|
||||
$this->ensurePriorityIsUnique($propertyTypeInferer);
|
||||
$this->propertyTypeInferers[$propertyTypeInferer->getPriority()] = $propertyTypeInferer;
|
||||
}
|
||||
|
||||
krsort($this->propertyTypeInferers);
|
||||
}
|
||||
|
||||
private function ensurePriorityIsUnique(PropertyTypeInfererInterface $propertyTypeInferer): void
|
||||
{
|
||||
if (! isset($this->propertyTypeInferers[$propertyTypeInferer->getPriority()])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$alreadySetPropertyTypeInferer = $this->propertyTypeInferers[$propertyTypeInferer->getPriority()];
|
||||
|
||||
throw new ConflictingPriorityException($propertyTypeInferer, $alreadySetPropertyTypeInferer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\TypeDeclaration\TypeInferer;
|
||||
|
||||
use PhpParser\Node\Param;
|
||||
use Rector\TypeDeclaration\Contract\TypeInferer\ParamTypeInfererInterface;
|
||||
|
||||
final class ParamTypeInferer
|
||||
{
|
||||
/**
|
||||
* @var ParamTypeInfererInterface[]
|
||||
*/
|
||||
private $paramTypeInferers = [];
|
||||
|
||||
/**
|
||||
* @param ParamTypeInfererInterface[] $paramTypeInferers
|
||||
*/
|
||||
public function __construct(array $paramTypeInferers)
|
||||
{
|
||||
$this->paramTypeInferers = $paramTypeInferers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function inferParam(Param $param): array
|
||||
{
|
||||
foreach ($this->paramTypeInferers as $paramTypeInferers) {
|
||||
$types = $paramTypeInferers->inferParam($param);
|
||||
if ($types !== []) {
|
||||
return $types;
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
|
@ -4,6 +4,8 @@ namespace Rector\TypeDeclaration\TypeInferer;
|
|||
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use Rector\TypeDeclaration\Contract\TypeInferer\PropertyTypeInfererInterface;
|
||||
use Rector\TypeDeclaration\Exception\ConflictingPriorityException;
|
||||
use Rector\TypeDeclaration\ValueObject\IdentifierValueObject;
|
||||
|
||||
final class PropertyTypeInferer
|
||||
{
|
||||
|
@ -17,16 +19,16 @@ final class PropertyTypeInferer
|
|||
*/
|
||||
public function __construct(array $propertyTypeInferers)
|
||||
{
|
||||
$this->propertyTypeInferers = $propertyTypeInferers;
|
||||
$this->sortAndSetPropertyTypeInferers($propertyTypeInferers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @property string[]
|
||||
* @return string[]|IdentifierValueObject[]
|
||||
*/
|
||||
public function inferProperty(Property $property): array
|
||||
{
|
||||
foreach ($this->propertyTypeInferers as $propertyTypeInferers) {
|
||||
$types = $propertyTypeInferers->inferFunctionLike($property);
|
||||
$types = $propertyTypeInferers->inferProperty($property);
|
||||
if ($types !== []) {
|
||||
return $types;
|
||||
}
|
||||
|
@ -34,4 +36,28 @@ final class PropertyTypeInferer
|
|||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PropertyTypeInfererInterface[] $propertyTypeInferers
|
||||
*/
|
||||
private function sortAndSetPropertyTypeInferers(array $propertyTypeInferers): void
|
||||
{
|
||||
foreach ($propertyTypeInferers as $propertyTypeInferer) {
|
||||
$this->ensurePriorityIsUnique($propertyTypeInferer);
|
||||
$this->propertyTypeInferers[$propertyTypeInferer->getPriority()] = $propertyTypeInferer;
|
||||
}
|
||||
|
||||
krsort($this->propertyTypeInferers);
|
||||
}
|
||||
|
||||
private function ensurePriorityIsUnique(PropertyTypeInfererInterface $propertyTypeInferer): void
|
||||
{
|
||||
if (! isset($this->propertyTypeInferers[$propertyTypeInferer->getPriority()])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$alreadySetPropertyTypeInferer = $this->propertyTypeInferers[$propertyTypeInferer->getPriority()];
|
||||
|
||||
throw new ConflictingPriorityException($propertyTypeInferer, $alreadySetPropertyTypeInferer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,16 +5,19 @@ namespace Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer;
|
|||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use PhpParser\Node\Stmt\Trait_;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\TypeDeclaration\Contract\TypeInferer\ReturnTypeInfererInterface;
|
||||
use Rector\TypeDeclaration\TypeInferer\AbstractTypeInferer;
|
||||
use Rector\TypeDeclaration\TypeInferer\PropertyTypeInferer;
|
||||
use Rector\TypeDeclaration\ValueObject\IdentifierValueObject;
|
||||
|
||||
/**
|
||||
* Infer return type from $this->variable → and get type $this->variable from @var annotation
|
||||
|
@ -33,7 +36,7 @@ final class ReturnedPropertyReturnTypeInferer extends AbstractTypeInferer implem
|
|||
|
||||
/**
|
||||
* @param ClassMethod|Closure|Function_ $functionLike
|
||||
* @return string[]
|
||||
* @return string[]|IdentifierValueObject[]
|
||||
*/
|
||||
public function inferFunctionLike(FunctionLike $functionLike): array
|
||||
{
|
||||
|
@ -56,7 +59,7 @@ final class ReturnedPropertyReturnTypeInferer extends AbstractTypeInferer implem
|
|||
|
||||
private function matchSingleStmtReturnPropertyFetch(ClassMethod $classMethod): ?PropertyFetch
|
||||
{
|
||||
if (count($classMethod->stmts) !== 1) {
|
||||
if (count((array) $classMethod->stmts) !== 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -84,18 +87,21 @@ final class ReturnedPropertyReturnTypeInferer extends AbstractTypeInferer implem
|
|||
|
||||
private function getPropertyByPropertyFetch(PropertyFetch $propertyFetch): ?Property
|
||||
{
|
||||
/** @var Class_|Trait_|Interface_|null $class */
|
||||
$class = $propertyFetch->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if ($class instanceof ClassLike) {
|
||||
if ($class === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var string $propertyName */
|
||||
$propertyName = $this->nameResolver->getName($propertyFetch->name);
|
||||
|
||||
foreach ($class->stmts as $stmt) {
|
||||
if (!$stmt instanceof Property) {
|
||||
if (! $stmt instanceof Property) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$this->nameResolver->isName($stmt, $propertyName)) {
|
||||
if (! $this->nameResolver->isName($stmt, $propertyName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user