Skip to content

Commit

Permalink
add MethodCall to ExclusiveNativeCallLikeReturnMatcher
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Jul 9, 2022
1 parent 91ce295 commit 34be2ee
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace Rector\TypeDeclaration\NodeAnalyzer\ReturnFilter;

use PhpParser\Node\Expr;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\MethodReflection;
use Rector\Core\Reflection\ReflectionResolver;

final class ExclusiveNativeCallLikeReturnMatcher
{
public function __construct(
private readonly ReflectionResolver $reflectionResolver,
) {
}

/**
* @param Return_[] $returns
* @return array<StaticCall|FuncCall|MethodCall>|null
*/
public function match(array $returns): array|null
{
$callLikes = [];

foreach ($returns as $return) {
// we need exact expr return
$returnExpr = $return->expr;
if (! $returnExpr instanceof StaticCall && ! $returnExpr instanceof MethodCall && ! $returnExpr instanceof FuncCall) {
return null;
}

$functionLikeReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($returnExpr);

if (! $functionLikeReflection instanceof FunctionReflection && ! $functionLikeReflection instanceof MethodReflection) {
return null;
}

// is native func call?
if (! $this->isNativeCallLike($functionLikeReflection)) {
return null;
}

$callLikes[] = $returnExpr;
}

return $callLikes;
}

private function isNativeCallLike(MethodReflection|FunctionReflection $functionLikeReflection): bool
{
if ($functionLikeReflection instanceof FunctionReflection) {
return $functionLikeReflection->isBuiltin();
}

// is native method call?
$classReflection = $functionLikeReflection->getDeclaringClass();
return $classReflection->isBuiltin();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,27 @@
namespace Rector\TypeDeclaration\NodeAnalyzer\ReturnTypeAnalyzer;

use PhpParser\Node\Expr;
use PhpParser\Node\Expr\CallLike;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Yield_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\TypeDeclaration\NodeAnalyzer\ReturnFilter\ExclusiveNativeFuncCallReturnMatcher;
use Rector\TypeDeclaration\NodeAnalyzer\ReturnFilter\ExclusiveNativeCallLikeReturnMatcher;

final class StrictNativeFunctionReturnTypeAnalyzer
{
public function __construct(
private readonly BetterNodeFinder $betterNodeFinder,
private readonly ExclusiveNativeFuncCallReturnMatcher $exclusiveNativeFuncCallReturnMatcher
private readonly ExclusiveNativeCallLikeReturnMatcher $exclusiveNativeCallLikeReturnMatcher
) {
}

/**
* @return FuncCall[]|null
* @return CallLike[]|null
*/
public function matchAlwaysReturnNativeFuncCalls(ClassMethod|Closure|Function_ $functionLike): ?array
public function matchAlwaysReturnNativeCallLikes(ClassMethod|Closure|Function_ $functionLike): ?array
{
if ($functionLike->stmts === null) {
return null;
Expand All @@ -51,12 +51,12 @@ public function matchAlwaysReturnNativeFuncCalls(ClassMethod|Closure|Function_ $
return null;
}

$nativeFuncCalls = $this->exclusiveNativeFuncCallReturnMatcher->match($returns);
if ($nativeFuncCalls === null) {
$nativeCalls = $this->exclusiveNativeCallLikeReturnMatcher->match($returns);
if ($nativeCalls === null) {
return null;
}

return $nativeFuncCalls;
return $nativeCalls;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,17 @@ public function refactor(Node $node): ?Node
return null;
}

$nativeFuncCalls = $this->strictNativeFunctionReturnTypeAnalyzer->matchAlwaysReturnNativeFuncCalls($node);
if ($nativeFuncCalls === null) {
$nativeCallLikes = $this->strictNativeFunctionReturnTypeAnalyzer->matchAlwaysReturnNativeCallLikes($node);
if ($nativeCallLikes === null) {
return null;
}

$funcCallTypes = [];
foreach ($nativeFuncCalls as $nativeFuncCall) {
$funcCallTypes[] = $this->getType($nativeFuncCall);
$callLikeTypes = [];
foreach ($nativeCallLikes as $nativeCallLike) {
$callLikeTypes[] = $this->getType($nativeCallLike);
}

$returnType = $this->typeFactory->createMixedPassedOrUnionType($funcCallTypes);
$returnType = $this->typeFactory->createMixedPassedOrUnionType($callLikeTypes);
if ($returnType instanceof MixedType) {
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Reflection/ReflectionResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public function resolveMethodReflectionFromMethodCall(MethodCall $methodCall): ?
}

public function resolveFunctionLikeReflectionFromCall(
MethodCall | StaticCall | FuncCall $call
MethodCall|FuncCall|StaticCall $call
): MethodReflection | FunctionReflection | null {
if ($call instanceof MethodCall) {
return $this->resolveMethodReflectionFromMethodCall($call);
Expand Down

0 comments on commit 34be2ee

Please sign in to comment.