Skip to content

Commit

Permalink
[TypeDeclaration] Remove AstResolver usage on ReturnedNodesReturnType…
Browse files Browse the repository at this point in the history
…InfererTypeInferer (#5108)
  • Loading branch information
samsonasik committed Oct 2, 2023
1 parent 8c9fe9a commit 6a89b43
Showing 1 changed file with 0 additions and 93 deletions.
Expand Up @@ -6,20 +6,14 @@

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrowFunction;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Return_;
use PhpParser\NodeTraverser;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\ArrayType;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use PHPStan\Type\VoidType;
use Rector\Core\PhpParser\AstResolver;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
Expand All @@ -38,8 +32,6 @@ public function __construct(
private readonly SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
private readonly TypeFactory $typeFactory,
private readonly SplArrayFixedTypeNarrower $splArrayFixedTypeNarrower,
private readonly AstResolver $reflectionAstResolver,
private readonly BetterStandardPrinter $betterStandardPrinter,
private readonly ReflectionResolver $reflectionResolver,
) {
}
Expand All @@ -66,7 +58,6 @@ public function inferFunctionLike(FunctionLike $functionLike): Type
$returnedExprType = $localReturnNode->expr instanceof Expr
? $this->nodeTypeResolver->getNativeType($localReturnNode->expr)
: new VoidType();
$returnedExprType = $this->correctWithNestedType($returnedExprType, $localReturnNode, $functionLike);

$types[] = $this->splArrayFixedTypeNarrower->narrow($returnedExprType);
}
Expand Down Expand Up @@ -129,88 +120,4 @@ private function isAbstractMethod(ClassReflection $classReflection, FunctionLike

return $classReflection->isAbstract();
}

private function inferFromReturnedMethodCall(Return_ $return, FunctionLike $originalFunctionLike): Type
{
if (! $return->expr instanceof MethodCall) {
return new MixedType();
}

$methodReflection = $this->reflectionResolver->resolveMethodReflectionFromMethodCall($return->expr);
if (! $methodReflection instanceof MethodReflection) {
return new MixedType();
}

$isReturnScoped = false;

$this->simpleCallableNodeTraverser->traverseNodesWithCallable(
(array) $originalFunctionLike->getStmts(),
static function (Node $subNode) use ($return, &$isReturnScoped): ?int {
if ($subNode instanceof FunctionLike && ! $subNode instanceof ArrowFunction) {
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
}

if (! $subNode instanceof Return_) {
return null;
}

if ($return === $subNode) {
$isReturnScoped = true;
return NodeTraverser::STOP_TRAVERSAL;
}

return null;
}
);

if ($isReturnScoped) {
return new MixedType();
}

return $this->resolveClassMethod($methodReflection, $originalFunctionLike);
}

private function isArrayTypeMixed(Type $type): bool
{
if (! $type instanceof ArrayType) {
return false;
}

if (! $type->getItemType() instanceof MixedType) {
return false;
}

return $type->getKeyType() instanceof MixedType;
}

private function correctWithNestedType(Type $resolvedType, Return_ $return, FunctionLike $functionLike): Type
{
if ($resolvedType instanceof MixedType || $this->isArrayTypeMixed($resolvedType)) {
$correctedType = $this->inferFromReturnedMethodCall($return, $functionLike);

// override only if has some extra value
if (! $correctedType instanceof MixedType && ! $correctedType->isVoid()->yes()) {
return $correctedType;
}
}

return $resolvedType;
}

private function resolveClassMethod(MethodReflection $methodReflection, FunctionLike $originalFunctionLike): Type
{
$classMethod = $this->reflectionAstResolver->resolveClassMethodFromMethodReflection($methodReflection);
if (! $classMethod instanceof ClassMethod) {
return new MixedType();
}

$classMethodCacheKey = $this->betterStandardPrinter->print($classMethod);
$functionLikeCacheKey = $this->betterStandardPrinter->print($originalFunctionLike);

if ($classMethodCacheKey === $functionLikeCacheKey) {
return new MixedType();
}

return $this->inferFunctionLike($classMethod);
}
}

0 comments on commit 6a89b43

Please sign in to comment.