mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-21 01:41:00 +01:00
remove ReturnTypeResolver
This commit is contained in:
parent
8b6331bc01
commit
87e4c5e0a8
@ -6,21 +6,29 @@ use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Closure;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PhpParser\Node\Manipulator\FunctionLikeManipulator;
|
||||
use Rector\NodeTypeResolver\Php\ReturnTypeInfo;
|
||||
use Rector\Php\TypeAnalyzer;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer;
|
||||
|
||||
final class AddClosureReturnTypeRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var FunctionLikeManipulator
|
||||
* @var ReturnTypeInferer
|
||||
*/
|
||||
private $functionLikeManipulator;
|
||||
private $returnTypeInferer;
|
||||
|
||||
public function __construct(FunctionLikeManipulator $functionLikeManipulator)
|
||||
/**
|
||||
* @var TypeAnalyzer
|
||||
*/
|
||||
private $typeAnalyzer;
|
||||
|
||||
public function __construct(ReturnTypeInferer $returnTypeInferer, TypeAnalyzer $typeAnalyzer)
|
||||
{
|
||||
$this->functionLikeManipulator = $functionLikeManipulator;
|
||||
$this->returnTypeInferer = $returnTypeInferer;
|
||||
$this->typeAnalyzer = $typeAnalyzer;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
@ -81,12 +89,10 @@ CODE_SAMPLE
|
||||
return null;
|
||||
}
|
||||
|
||||
$staticReturnType = $this->functionLikeManipulator->resolveStaticReturnTypeInfo($node);
|
||||
if ($staticReturnType === null) {
|
||||
return null;
|
||||
}
|
||||
$inferedReturnTypes = $this->returnTypeInferer->inferFunctionLike($node);
|
||||
$returnTypeInfo = new ReturnTypeInfo($inferedReturnTypes, $this->typeAnalyzer, $inferedReturnTypes);
|
||||
|
||||
$returnTypeNode = $staticReturnType->getFqnTypeNode();
|
||||
$returnTypeNode = $returnTypeInfo->getFqnTypeNode();
|
||||
if ($returnTypeNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\TypeDeclaration\ReturnTypeResolver;
|
||||
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use Rector\NodeTypeResolver\Php\ReturnTypeInfo;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\PhpParser\Node\Manipulator\FunctionLikeManipulator;
|
||||
|
||||
final class ReturnTypeResolver
|
||||
{
|
||||
/**
|
||||
* @var DocBlockManipulator
|
||||
*/
|
||||
private $docBlockManipulator;
|
||||
|
||||
/**
|
||||
* @var FunctionLikeManipulator
|
||||
*/
|
||||
private $functionLikeManipulator;
|
||||
|
||||
public function __construct(
|
||||
DocBlockManipulator $docBlockManipulator,
|
||||
FunctionLikeManipulator $functionLikeManipulator
|
||||
) {
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->functionLikeManipulator = $functionLikeManipulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMethod|Function_ $functionLike
|
||||
*/
|
||||
public function resolveFunctionLikeReturnType(FunctionLike $functionLike): ?ReturnTypeInfo
|
||||
{
|
||||
$docReturnTypeInfo = $this->docBlockManipulator->getReturnTypeInfo($functionLike);
|
||||
$codeReturnTypeInfo = $this->functionLikeManipulator->resolveStaticReturnTypeInfo($functionLike);
|
||||
|
||||
// code has priority over docblock
|
||||
if ($docReturnTypeInfo === null) {
|
||||
return $codeReturnTypeInfo;
|
||||
}
|
||||
|
||||
if ($codeReturnTypeInfo && $codeReturnTypeInfo->getTypeNode()) {
|
||||
return $codeReturnTypeInfo;
|
||||
}
|
||||
|
||||
return $docReturnTypeInfo;
|
||||
}
|
||||
}
|
@ -44,6 +44,6 @@ final class AllAssignNodePropertyTypeInferer extends AbstractTypeInferer impleme
|
||||
|
||||
public function getPriority(): int
|
||||
{
|
||||
return 500;
|
||||
return 610;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,150 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\TypeDeclaration\TypeInferer\PropertyTypeInferer;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\TypeDeclaration\Contract\TypeInferer\PropertyTypeInfererInterface;
|
||||
use Rector\TypeDeclaration\TypeInferer\AbstractTypeInferer;
|
||||
use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer\ReturnedNodesReturnTypeInferer;
|
||||
use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer\ReturnTagReturnTypeInferer;
|
||||
|
||||
final class GetterPropertyTypeInferer extends AbstractTypeInferer implements PropertyTypeInfererInterface
|
||||
{
|
||||
/**
|
||||
* @var ReturnedNodesReturnTypeInferer
|
||||
*/
|
||||
private $returnedNodesReturnTypeInferer;
|
||||
|
||||
/**
|
||||
* @var ReturnTagReturnTypeInferer
|
||||
*/
|
||||
private $returnTagReturnTypeInferer;
|
||||
|
||||
public function __construct(
|
||||
ReturnedNodesReturnTypeInferer $returnedNodesReturnTypeInferer,
|
||||
ReturnTagReturnTypeInferer $returnTagReturnTypeInferer
|
||||
) {
|
||||
$this->returnedNodesReturnTypeInferer = $returnedNodesReturnTypeInferer;
|
||||
$this->returnTagReturnTypeInferer = $returnTagReturnTypeInferer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function inferProperty(Property $property): array
|
||||
{
|
||||
/** @var Class_ $class */
|
||||
$class = $property->getAttribute(AttributeKey::CLASS_NODE);
|
||||
|
||||
/** @var string $propertyName */
|
||||
$propertyName = $this->nameResolver->getName($property);
|
||||
|
||||
foreach ($class->getMethods() as $classMethod) {
|
||||
if (! $this->hasClassMethodOnlyStatementReturnOfPropertyFetch($classMethod, $propertyName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$returnTypes = $this->inferClassMethodReturnTypes($classMethod);
|
||||
if ($returnTypes !== []) {
|
||||
return $returnTypes;
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function getPriority(): int
|
||||
{
|
||||
return 600;
|
||||
}
|
||||
|
||||
private function hasClassMethodOnlyStatementReturnOfPropertyFetch(
|
||||
ClassMethod $classMethod,
|
||||
string $propertyName
|
||||
): bool {
|
||||
if (count((array) $classMethod->stmts) !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$onlyClassMethodStmt = $classMethod->stmts[0];
|
||||
if (! $onlyClassMethodStmt instanceof Return_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var Return_ $return */
|
||||
$return = $onlyClassMethodStmt;
|
||||
|
||||
if (! $return->expr instanceof PropertyFetch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->nameResolver->isName($return->expr, $propertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Intentionally local method ↓
|
||||
* @todo possible move to ReturnTypeInferer, but allow to disable/enable in case of override returnType (99 %)
|
||||
*
|
||||
* @param ClassMethod|Function_|Closure $functionLike
|
||||
* @return string[]
|
||||
*/
|
||||
private function resolveFunctionLikeReturnTypeDeclaration(FunctionLike $functionLike): array
|
||||
{
|
||||
if ($functionLike->returnType === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->resolveReturnTypeToString($functionLike->returnType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
private function inferClassMethodReturnTypes(ClassMethod $classMethod): array
|
||||
{
|
||||
$returnTypeDeclarationTypes = $this->resolveFunctionLikeReturnTypeDeclaration($classMethod);
|
||||
if ($returnTypeDeclarationTypes) {
|
||||
return $returnTypeDeclarationTypes;
|
||||
}
|
||||
|
||||
$inferedTypes = $this->returnedNodesReturnTypeInferer->inferFunctionLike($classMethod);
|
||||
if ($inferedTypes) {
|
||||
return $inferedTypes;
|
||||
}
|
||||
|
||||
return $this->returnTagReturnTypeInferer->inferFunctionLike($classMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Identifier|Name|NullableType $node
|
||||
* @return string[]
|
||||
*/
|
||||
private function resolveReturnTypeToString(Node $node): array
|
||||
{
|
||||
$types = [];
|
||||
|
||||
$type = $node instanceof NullableType ? $node->type : $node;
|
||||
$result = $this->nameResolver->getName($type);
|
||||
if ($result !== null) {
|
||||
$types[] = $result;
|
||||
}
|
||||
|
||||
if ($node instanceof NullableType) {
|
||||
$types[] = 'null';
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
}
|
@ -2,28 +2,21 @@
|
||||
|
||||
namespace Rector\TypeDeclaration\TypeInferer\PropertyTypeInferer;
|
||||
|
||||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\TypeDeclaration\Contract\TypeInferer\PropertyTypeInfererInterface;
|
||||
use Rector\TypeDeclaration\ReturnTypeResolver\ReturnTypeResolver;
|
||||
use Rector\TypeDeclaration\TypeInferer\AbstractTypeInferer;
|
||||
|
||||
final class GetterOrSetterPropertyTypeInferer extends AbstractTypeInferer implements PropertyTypeInfererInterface
|
||||
final class GetterTypeDeclarationPropertyTypeInferer extends AbstractTypeInferer implements PropertyTypeInfererInterface
|
||||
{
|
||||
/**
|
||||
* @var ReturnTypeResolver
|
||||
*/
|
||||
private $returnTypeResolver;
|
||||
|
||||
public function __construct(ReturnTypeResolver $returnTypeResolver)
|
||||
{
|
||||
$this->returnTypeResolver = $returnTypeResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
@ -40,7 +33,12 @@ final class GetterOrSetterPropertyTypeInferer extends AbstractTypeInferer implem
|
||||
continue;
|
||||
}
|
||||
|
||||
$returnTypes = $this->resolveClassMethodReturnTypes($classMethod);
|
||||
$returnTypes = $this->resolveReturnTypeToString($classMethod);
|
||||
// let PhpDoc solve that later for more precise type
|
||||
if ($returnTypes === ['array']) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($returnTypes !== []) {
|
||||
return $returnTypes;
|
||||
}
|
||||
@ -51,7 +49,7 @@ final class GetterOrSetterPropertyTypeInferer extends AbstractTypeInferer implem
|
||||
|
||||
public function getPriority(): int
|
||||
{
|
||||
return 600;
|
||||
return 630;
|
||||
}
|
||||
|
||||
private function hasClassMethodOnlyStatementReturnOfPropertyFetch(
|
||||
@ -78,15 +76,29 @@ final class GetterOrSetterPropertyTypeInferer extends AbstractTypeInferer implem
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Function_|ClassMethod|Closure $functionLike
|
||||
* @return string[]
|
||||
*/
|
||||
private function resolveClassMethodReturnTypes(ClassMethod $classMethod): array
|
||||
private function resolveReturnTypeToString(FunctionLike $functionLike): array
|
||||
{
|
||||
$returnType = $this->returnTypeResolver->resolveFunctionLikeReturnType($classMethod);
|
||||
if ($returnType === null) {
|
||||
if ($functionLike->getReturnType() === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $returnType->getDocTypes();
|
||||
$returnType = $functionLike->getReturnType();
|
||||
|
||||
$types = [];
|
||||
|
||||
$type = $returnType instanceof NullableType ? $returnType->type : $returnType;
|
||||
$result = $this->nameResolver->getName($type);
|
||||
if ($result !== null) {
|
||||
$types[] = $result;
|
||||
}
|
||||
|
||||
if ($returnType instanceof NullableType) {
|
||||
$types[] = 'null';
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer;
|
||||
|
||||
use PhpParser\Node\Expr\Closure;
|
||||
use PhpParser\Node\FunctionLike;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use Rector\PhpParser\Node\Manipulator\FunctionLikeManipulator;
|
||||
use Rector\TypeDeclaration\Contract\TypeInferer\ReturnTypeInfererInterface;
|
||||
use Rector\TypeDeclaration\TypeInferer\AbstractTypeInferer;
|
||||
|
||||
final class ReturnedNodeReturnTypeInferer extends AbstractTypeInferer implements ReturnTypeInfererInterface
|
||||
{
|
||||
/**
|
||||
* @var FunctionLikeManipulator
|
||||
*/
|
||||
private $functionLikeManipulator;
|
||||
|
||||
public function __construct(FunctionLikeManipulator $functionLikeManipulator)
|
||||
{
|
||||
$this->functionLikeManipulator = $functionLikeManipulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMethod|Closure|Function_ $functionLike
|
||||
* @return string[]
|
||||
*/
|
||||
public function inferFunctionLike(FunctionLike $functionLike): array
|
||||
{
|
||||
$resolvedReturnTypeInfo = $this->functionLikeManipulator->resolveStaticReturnTypeInfo($functionLike);
|
||||
|
||||
return $resolvedReturnTypeInfo ? $resolvedReturnTypeInfo->getDocTypes() : [];
|
||||
}
|
||||
|
||||
public function getPriority(): int
|
||||
{
|
||||
return 500;
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ final class AddArrayReturnDocTypeRectorTest extends AbstractRectorTestCase
|
||||
__DIR__ . '/Fixture/simple_array.php.inc',
|
||||
__DIR__ . '/Fixture/add_without_return_type_declaration.php.inc',
|
||||
__DIR__ . '/Fixture/fix_incorrect_array.php.inc',
|
||||
// skip
|
||||
// skip
|
||||
__DIR__ . '/Fixture/skip_constructor.php.inc',
|
||||
__DIR__ . '/Fixture/skip_array_after_array_type.php.inc',
|
||||
__DIR__ . '/Fixture/skip_shorten_class_name.php.inc',
|
||||
|
@ -26,7 +26,7 @@ final class PropertyTypeDeclarationRectorTest extends AbstractRectorTestCase
|
||||
__DIR__ . '/Fixture/single_nullable_return.php.inc',
|
||||
__DIR__ . '/Fixture/getter_type.php.inc',
|
||||
__DIR__ . '/Fixture/setter_type.php.inc',
|
||||
// skip
|
||||
// skip
|
||||
__DIR__ . '/Fixture/skip_multi_vars.php.inc',
|
||||
]);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user