mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-02 09:20:52 +00:00
Unite any extra reflection parsing to single ReflectionResolver service (#313)
This commit is contained in:
parent
9d4c4ff6ed
commit
a435716072
|
@ -2,14 +2,11 @@
|
|||
|
||||
namespace Rector\Tests\Php70\Rector\FuncCall\NonVariableToVariableOnFunctionCallRector\Fixture;
|
||||
|
||||
class Invokable
|
||||
{
|
||||
public function __invoke(&$bar) {}
|
||||
}
|
||||
use Rector\Tests\Php70\Rector\FuncCall\NonVariableToVariableOnFunctionCallRector\Source\InvokableConstructorArgument;
|
||||
|
||||
function invokable()
|
||||
{
|
||||
$invokable = new Invokable();
|
||||
$invokable = new InvokableConstructorArgument();
|
||||
$invokable(bar());
|
||||
}
|
||||
|
||||
|
@ -19,14 +16,11 @@ function invokable()
|
|||
|
||||
namespace Rector\Tests\Php70\Rector\FuncCall\NonVariableToVariableOnFunctionCallRector\Fixture;
|
||||
|
||||
class Invokable
|
||||
{
|
||||
public function __invoke(&$bar) {}
|
||||
}
|
||||
use Rector\Tests\Php70\Rector\FuncCall\NonVariableToVariableOnFunctionCallRector\Source\InvokableConstructorArgument;
|
||||
|
||||
function invokable()
|
||||
{
|
||||
$invokable = new Invokable();
|
||||
$invokable = new InvokableConstructorArgument();
|
||||
$bar = bar();
|
||||
$invokable($bar);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\Php70\Rector\FuncCall\NonVariableToVariableOnFunctionCallRector\Source;
|
||||
|
||||
final class InvokableConstructorArgument
|
||||
{
|
||||
public function __invoke(&$bar)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -13,8 +13,8 @@ use PHPStan\Reflection\FunctionReflection;
|
|||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Reflection\Php\PhpFunctionReflection;
|
||||
use Rector\CodingStyle\NodeAnalyzer\SpreadVariablesCollector;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
|
@ -25,7 +25,7 @@ final class UnSpreadOperatorRector extends AbstractRector
|
|||
{
|
||||
public function __construct(
|
||||
private SpreadVariablesCollector $spreadVariablesCollector,
|
||||
private CallReflectionResolver $callReflectionResolver,
|
||||
private ReflectionResolver $reflectionResolver
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -101,18 +101,18 @@ CODE_SAMPLE
|
|||
|
||||
private function processUnspreadOperatorMethodCallArgs(MethodCall $methodCall): ?MethodCall
|
||||
{
|
||||
$functionLikeReflection = $this->callReflectionResolver->resolveCall($methodCall);
|
||||
if ($functionLikeReflection === null) {
|
||||
$methodReflection = $this->reflectionResolver->resolveMethodReflectionFromMethodCall($methodCall);
|
||||
if (! $methodReflection instanceof MethodReflection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// skip those in vendor
|
||||
if ($this->skipForVendor($functionLikeReflection)) {
|
||||
if ($this->skipForVendor($methodReflection)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$spreadParameterReflections = $this->spreadVariablesCollector->resolveFromMethodReflection(
|
||||
$functionLikeReflection
|
||||
$methodReflection
|
||||
);
|
||||
if ($spreadParameterReflections === []) {
|
||||
return null;
|
||||
|
|
|
@ -6,13 +6,14 @@ namespace Rector\Defluent\NodeAnalyzer;
|
|||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Rector\Defluent\Contract\ValueObject\FirstCallFactoryAwareInterface;
|
||||
|
||||
final class SameClassMethodCallAnalyzer
|
||||
{
|
||||
public function __construct(
|
||||
private CallReflectionResolver $callReflectionResolver
|
||||
private ReflectionResolver $reflectionResolver,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -24,10 +25,10 @@ final class SameClassMethodCallAnalyzer
|
|||
// are method calls located in the same class?
|
||||
$classOfClassMethod = [];
|
||||
foreach ($chainMethodCalls as $chainMethodCall) {
|
||||
$functionLikeReflection = $this->callReflectionResolver->resolveCall($chainMethodCall);
|
||||
$methodReflection = $this->reflectionResolver->resolveMethodReflectionFromMethodCall($chainMethodCall);
|
||||
|
||||
if ($functionLikeReflection instanceof MethodReflection) {
|
||||
$declaringClass = $functionLikeReflection->getDeclaringClass();
|
||||
if ($methodReflection instanceof MethodReflection) {
|
||||
$declaringClass = $methodReflection->getDeclaringClass();
|
||||
$classOfClassMethod[] = $declaringClass->getName();
|
||||
} else {
|
||||
$classOfClassMethod[] = null;
|
||||
|
|
|
@ -18,8 +18,8 @@ use PHPStan\Reflection\MethodReflection;
|
|||
use PHPStan\Reflection\ParameterReflection;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\VerbosityLevel;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
|
@ -29,7 +29,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
final class DowngradeNamedArgumentRector extends AbstractRector
|
||||
{
|
||||
public function __construct(
|
||||
private CallReflectionResolver $callReflectionResolver,
|
||||
private ReflectionResolver $reflectionResolver
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ CODE_SAMPLE
|
|||
private function removeNamedArguments(MethodCall | StaticCall | New_ $node, array $args): ?Node
|
||||
{
|
||||
if ($node instanceof New_) {
|
||||
$methodReflection = $this->callReflectionResolver->resolveConstructor($node);
|
||||
$methodReflection = $this->reflectionResolver->resolveMethodReflectionFromNew($node);
|
||||
if (! $methodReflection instanceof MethodReflection) {
|
||||
return null;
|
||||
}
|
||||
|
@ -107,12 +107,12 @@ CODE_SAMPLE
|
|||
return $this->processRemoveNamedArgument($methodReflection, $node, $args);
|
||||
}
|
||||
|
||||
$callerReflection = $this->callReflectionResolver->resolveCall($node);
|
||||
if ($callerReflection === null) {
|
||||
$functionLikeReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node);
|
||||
if ($functionLikeReflection === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->processRemoveNamedArgument($callerReflection, $node, $args);
|
||||
return $this->processRemoveNamedArgument($functionLikeReflection, $node, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,8 +22,8 @@ use PHPStan\Analyser\Scope;
|
|||
use PHPStan\Reflection\ParameterReflection;
|
||||
use PHPStan\Reflection\ParametersAcceptor;
|
||||
use PHPStan\Type\MixedType;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Rector\Naming\Naming\VariableNaming;
|
||||
use Rector\NodeNestingScope\ParentScopeFinder;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
@ -39,9 +39,9 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
final class NonVariableToVariableOnFunctionCallRector extends AbstractRector
|
||||
{
|
||||
public function __construct(
|
||||
private CallReflectionResolver $callReflectionResolver,
|
||||
private VariableNaming $variableNaming,
|
||||
private ParentScopeFinder $parentScopeFinder
|
||||
private ParentScopeFinder $parentScopeFinder,
|
||||
private ReflectionResolver $reflectionResolver
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -107,18 +107,19 @@ final class NonVariableToVariableOnFunctionCallRector extends AbstractRector
|
|||
}
|
||||
|
||||
/**
|
||||
* @param FuncCall|MethodCall|StaticCall $node
|
||||
*
|
||||
* @return Expr[]
|
||||
*/
|
||||
private function getNonVariableArguments(Node $node): array
|
||||
private function getNonVariableArguments(FuncCall|MethodCall|StaticCall $call): array
|
||||
{
|
||||
$arguments = [];
|
||||
|
||||
$parametersAcceptor = $this->callReflectionResolver->resolveParametersAcceptor(
|
||||
$this->callReflectionResolver->resolveCall($node),
|
||||
);
|
||||
$functionLikeReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($call);
|
||||
|
||||
if ($functionLikeReflection === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$parametersAcceptor = $functionLikeReflection->getVariants()[0] ?? null;
|
||||
if (! $parametersAcceptor instanceof ParametersAcceptor) {
|
||||
return [];
|
||||
}
|
||||
|
@ -126,7 +127,7 @@ final class NonVariableToVariableOnFunctionCallRector extends AbstractRector
|
|||
/** @var ParameterReflection $parameterReflection */
|
||||
foreach ($parametersAcceptor->getParameters() as $key => $parameterReflection) {
|
||||
// omitted optional parameter
|
||||
if (! isset($node->args[$key])) {
|
||||
if (! isset($call->args[$key])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -134,7 +135,7 @@ final class NonVariableToVariableOnFunctionCallRector extends AbstractRector
|
|||
continue;
|
||||
}
|
||||
|
||||
$argument = $node->args[$key]->value;
|
||||
$argument = $call->args[$key]->value;
|
||||
|
||||
if ($this->isVariableLikeNode($argument)) {
|
||||
continue;
|
||||
|
|
|
@ -14,8 +14,8 @@ use PHPStan\Reflection\MethodReflection;
|
|||
use PHPStan\Reflection\Php\PhpMethodReflection;
|
||||
use PHPStan\Reflection\Type\UnionTypeMethodReflection;
|
||||
use Rector\Core\NodeAnalyzer\VariadicAnalyzer;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
|
@ -28,8 +28,8 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
final class RemoveExtraParametersRector extends AbstractRector
|
||||
{
|
||||
public function __construct(
|
||||
private CallReflectionResolver $callReflectionResolver,
|
||||
private VariadicAnalyzer $variadicAnalyzer
|
||||
private VariadicAnalyzer $variadicAnalyzer,
|
||||
private ReflectionResolver $reflectionResolver
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ final class RemoveExtraParametersRector extends AbstractRector
|
|||
}
|
||||
|
||||
// unreliable count of arguments
|
||||
$functionLikeReflection = $this->callReflectionResolver->resolveCall($node);
|
||||
$functionLikeReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node);
|
||||
if ($functionLikeReflection instanceof UnionTypeMethodReflection) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ use PhpParser\Node\Expr\MethodCall;
|
|||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
@ -28,7 +27,6 @@ final class OptionalParametersAfterRequiredRector extends AbstractRector
|
|||
public function __construct(
|
||||
private RequireOptionalParamResolver $requireOptionalParamResolver,
|
||||
private ArgumentSorter $argumentSorter,
|
||||
private CallReflectionResolver $callReflectionResolver,
|
||||
private ReflectionResolver $reflectionResolver
|
||||
) {
|
||||
}
|
||||
|
@ -137,7 +135,7 @@ CODE_SAMPLE
|
|||
|
||||
private function refactorMethodCall(MethodCall $methodCall): ?MethodCall
|
||||
{
|
||||
$methodReflection = $this->callReflectionResolver->resolveCall($methodCall);
|
||||
$methodReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($methodCall);
|
||||
if (! $methodReflection instanceof MethodReflection) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ use PHPStan\Type\MixedType;
|
|||
use PHPStan\Type\NullType;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\TypeDeclaration\NodeAnalyzer\TypeNodeUnwrapper;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
|
@ -35,7 +35,7 @@ final class ReturnTypeFromStrictTypedCallRector extends AbstractRector
|
|||
{
|
||||
public function __construct(
|
||||
private TypeNodeUnwrapper $typeNodeUnwrapper,
|
||||
private CallReflectionResolver $callReflectionResolver
|
||||
private ReflectionResolver $reflectionResolver
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ CODE_SAMPLE
|
|||
|
||||
private function resolveMethodCallReturnNode(MethodCall | StaticCall | FuncCall $call): ?Node
|
||||
{
|
||||
$methodReflection = $this->callReflectionResolver->resolveCall($call);
|
||||
$methodReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($call);
|
||||
if ($methodReflection === null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ use PHPStan\Type\Type;
|
|||
use PHPStan\Type\VoidType;
|
||||
use Rector\Core\PhpParser\AstResolver;
|
||||
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
|
||||
|
@ -41,9 +41,9 @@ final class ReturnedNodesReturnTypeInferer implements ReturnTypeInfererInterface
|
|||
private SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
|
||||
private TypeFactory $typeFactory,
|
||||
private SplArrayFixedTypeNarrower $splArrayFixedTypeNarrower,
|
||||
private CallReflectionResolver $callReflectionResolver,
|
||||
private AstResolver $reflectionAstResolver,
|
||||
private BetterStandardPrinter $betterStandardPrinter
|
||||
private BetterStandardPrinter $betterStandardPrinter,
|
||||
private ReflectionResolver $reflectionResolver
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -143,20 +143,12 @@ final class ReturnedNodesReturnTypeInferer implements ReturnTypeInfererInterface
|
|||
return new MixedType();
|
||||
}
|
||||
|
||||
$callReflection = $this->callReflectionResolver->resolveCall($return->expr);
|
||||
if ($callReflection === null) {
|
||||
$methodReflection = $this->reflectionResolver->resolveMethodReflectionFromMethodCall($return->expr);
|
||||
if (! $methodReflection instanceof MethodReflection) {
|
||||
return new MixedType();
|
||||
}
|
||||
|
||||
if ($callReflection instanceof MethodReflection) {
|
||||
return $this->resolveClassMethod($callReflection, $originalFunctionLike);
|
||||
}
|
||||
|
||||
if ($callReflection instanceof PhpFunctionReflection) {
|
||||
return $this->resolveFunction($callReflection, $originalFunctionLike);
|
||||
}
|
||||
|
||||
return new MixedType();
|
||||
return $this->resolveClassMethod($methodReflection, $originalFunctionLike);
|
||||
}
|
||||
|
||||
private function isArrayTypeMixed(Type $type): bool
|
||||
|
@ -202,21 +194,4 @@ final class ReturnedNodesReturnTypeInferer implements ReturnTypeInfererInterface
|
|||
|
||||
return $this->inferFunctionLike($classMethod);
|
||||
}
|
||||
|
||||
private function resolveFunction(PhpFunctionReflection $phpFunctionReflection, FunctionLike $functionLike): Type
|
||||
{
|
||||
$function = $this->reflectionAstResolver->resolveFunctionFromFunctionReflection($phpFunctionReflection);
|
||||
if (! $function instanceof Function_) {
|
||||
return new MixedType();
|
||||
}
|
||||
|
||||
$classMethodCacheKey = $this->betterStandardPrinter->print($function);
|
||||
$functionLikeCacheKey = $this->betterStandardPrinter->print($functionLike);
|
||||
|
||||
if ($classMethodCacheKey === $functionLikeCacheKey) {
|
||||
return new MixedType();
|
||||
}
|
||||
|
||||
return $this->inferFunctionLike($function);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ use PHPStan\Type\Type;
|
|||
use Rector\Core\PhpParser\Comparing\NodeComparator;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
|
||||
|
@ -44,8 +44,8 @@ final class ClassMethodAssignManipulator
|
|||
private NodeFactory $nodeFactory,
|
||||
private NodeNameResolver $nodeNameResolver,
|
||||
private VariableManipulator $variableManipulator,
|
||||
private CallReflectionResolver $callReflectionResolver,
|
||||
private NodeComparator $nodeComparator
|
||||
private NodeComparator $nodeComparator,
|
||||
private ReflectionResolver $reflectionResolver
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -294,13 +294,14 @@ final class ClassMethodAssignManipulator
|
|||
return false;
|
||||
}
|
||||
|
||||
$methodReflection = $this->callReflectionResolver->resolveCall($node);
|
||||
$methodReflection = $this->reflectionResolver->resolveMethodReflectionFromMethodCall($node);
|
||||
if (! $methodReflection instanceof MethodReflection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$variableName = $this->nodeNameResolver->getName($variable);
|
||||
$parametersAcceptor = $this->callReflectionResolver->resolveParametersAcceptor($methodReflection);
|
||||
$parametersAcceptor = $methodReflection->getVariants()[0] ?? null;
|
||||
|
||||
if (! $parametersAcceptor instanceof ParametersAcceptor) {
|
||||
return false;
|
||||
}
|
||||
|
@ -348,9 +349,12 @@ final class ClassMethodAssignManipulator
|
|||
|
||||
private function isParameterReferencedInMethodReflection(New_ $new, int $argumentPosition): bool
|
||||
{
|
||||
$methodReflection = $this->callReflectionResolver->resolveConstructor($new);
|
||||
$parametersAcceptor = $this->callReflectionResolver->resolveParametersAcceptor($methodReflection);
|
||||
$methodReflection = $this->reflectionResolver->resolveMethodReflectionFromNew($new);
|
||||
if (! $methodReflection instanceof MethodReflection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parametersAcceptor = $methodReflection->getVariants()[0] ?? null;
|
||||
if (! $parametersAcceptor instanceof ParametersAcceptor) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ use PhpParser\Node\Stmt\Property;
|
|||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\PhpParser\NodeFinder\PropertyFetchFinder;
|
||||
use Rector\Core\PHPStan\Reflection\CallReflectionResolver;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\ReadWrite\Guard\VariableToConstantGuard;
|
||||
use Rector\ReadWrite\NodeAnalyzer\ReadWritePropertyAnalyzer;
|
||||
|
@ -39,7 +39,7 @@ final class PropertyManipulator
|
|||
private PhpDocInfoFactory $phpDocInfoFactory,
|
||||
private TypeChecker $typeChecker,
|
||||
private PropertyFetchFinder $propertyFetchFinder,
|
||||
private CallReflectionResolver $callReflectionResolver,
|
||||
private ReflectionResolver $reflectionResolver
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ final class PropertyManipulator
|
|||
|
||||
private function isFoundByRefParam(MethodCall | StaticCall $node): bool
|
||||
{
|
||||
$functionLikeReflection = $this->callReflectionResolver->resolveCall($node);
|
||||
$functionLikeReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node);
|
||||
if ($functionLikeReflection === null) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\PHPStan\Reflection;
|
||||
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Name;
|
||||
use PHPStan\Analyser\Scope;
|
||||
use PHPStan\Reflection\FunctionReflection;
|
||||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Reflection\ParametersAcceptor;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\ThisType;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\Core\PHPStan\Reflection\TypeToCallReflectionResolver\TypeToCallReflectionResolverRegistry;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
|
||||
final class CallReflectionResolver
|
||||
{
|
||||
public function __construct(
|
||||
private NodeNameResolver $nodeNameResolver,
|
||||
private NodeTypeResolver $nodeTypeResolver,
|
||||
private ReflectionProvider $reflectionProvider,
|
||||
private TypeToCallReflectionResolverRegistry $typeToCallReflectionResolverRegistry
|
||||
) {
|
||||
}
|
||||
|
||||
public function resolveConstructor(New_ $new): ?MethodReflection
|
||||
{
|
||||
$scope = $new->getAttribute(AttributeKey::SCOPE);
|
||||
if (! $scope instanceof Scope) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classType = $this->nodeTypeResolver->resolve($new->class);
|
||||
|
||||
if ($classType instanceof UnionType) {
|
||||
return $this->matchConstructorMethodInUnionType($classType, $scope);
|
||||
}
|
||||
|
||||
if (! $classType->hasMethod(MethodName::CONSTRUCT)->yes()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $classType->getMethod(MethodName::CONSTRUCT, $scope);
|
||||
}
|
||||
|
||||
public function resolveCall(FuncCall | MethodCall | StaticCall $call): MethodReflection | FunctionReflection | null
|
||||
{
|
||||
if ($call instanceof FuncCall) {
|
||||
return $this->resolveFunctionCall($call);
|
||||
}
|
||||
|
||||
return $this->resolveMethodCall($call);
|
||||
}
|
||||
|
||||
public function resolveParametersAcceptor(
|
||||
FunctionReflection | MethodReflection | null $reflection
|
||||
): ?ParametersAcceptor {
|
||||
if ($reflection === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $reflection->getVariants()[0];
|
||||
}
|
||||
|
||||
private function matchConstructorMethodInUnionType(UnionType $unionType, Scope $scope): ?MethodReflection
|
||||
{
|
||||
foreach ($unionType->getTypes() as $unionedType) {
|
||||
if (! $unionedType instanceof TypeWithClassName) {
|
||||
continue;
|
||||
}
|
||||
if (! $unionedType->hasMethod(MethodName::CONSTRUCT)->yes()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $unionedType->getMethod(MethodName::CONSTRUCT, $scope);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function resolveFunctionCall(FuncCall $funcCall): FunctionReflection | MethodReflection | null
|
||||
{
|
||||
/** @var Scope|null $scope */
|
||||
$scope = $funcCall->getAttribute(AttributeKey::SCOPE);
|
||||
|
||||
if ($funcCall->name instanceof Name) {
|
||||
if ($this->reflectionProvider->hasFunction($funcCall->name, $scope)) {
|
||||
return $this->reflectionProvider->getFunction($funcCall->name, $scope);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $scope instanceof Scope) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$funcCallNameType = $scope->getType($funcCall->name);
|
||||
return $this->typeToCallReflectionResolverRegistry->resolve($funcCallNameType, $scope);
|
||||
}
|
||||
|
||||
private function resolveMethodCall(MethodCall | StaticCall $expr): ?MethodReflection
|
||||
{
|
||||
$scope = $expr->getAttribute(AttributeKey::SCOPE);
|
||||
if (! $scope instanceof Scope) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$methodName = $this->nodeNameResolver->getName($expr->name);
|
||||
if ($methodName === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classType = $this->nodeTypeResolver->resolve($expr instanceof MethodCall ? $expr->var : $expr->class);
|
||||
|
||||
if ($classType instanceof ThisType) {
|
||||
$classType = $classType->getStaticObjectType();
|
||||
}
|
||||
|
||||
if ($classType instanceof ObjectType) {
|
||||
if (! $this->reflectionProvider->hasClass($classType->getClassName())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classReflection = $this->reflectionProvider->getClass($classType->getClassName());
|
||||
if ($classReflection->hasMethod($methodName)) {
|
||||
return $classReflection->getMethod($methodName, $scope);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ use PhpParser\Node\Expr\FuncCall;
|
|||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Analyser\Scope;
|
||||
|
@ -16,6 +17,7 @@ use PHPStan\Reflection\MethodReflection;
|
|||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use PHPStan\Type\TypeUtils;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use Rector\Core\PHPStan\Reflection\TypeToCallReflectionResolver\TypeToCallReflectionResolverRegistry;
|
||||
use Rector\Core\ValueObject\MethodName;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
@ -27,7 +29,8 @@ final class ReflectionResolver
|
|||
public function __construct(
|
||||
private ReflectionProvider $reflectionProvider,
|
||||
private NodeTypeResolver $nodeTypeResolver,
|
||||
private NodeNameResolver $nodeNameResolver
|
||||
private NodeNameResolver $nodeNameResolver,
|
||||
private TypeToCallReflectionResolverRegistry $typeToCallReflectionResolverRegistry
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -147,18 +150,20 @@ final class ReflectionResolver
|
|||
return $this->resolveMethodReflection($newClassType->getClassName(), MethodName::CONSTRUCT, $scope);
|
||||
}
|
||||
|
||||
private function resolveFunctionReflectionFromFuncCall(FuncCall $funcCall): ?FunctionReflection
|
||||
private function resolveFunctionReflectionFromFuncCall(FuncCall $funcCall): FunctionReflection | MethodReflection | null
|
||||
{
|
||||
$functionName = $this->nodeNameResolver->getName($funcCall);
|
||||
if ($functionName === null) {
|
||||
$scope = $funcCall->getAttribute(AttributeKey::SCOPE);
|
||||
|
||||
if ($funcCall->name instanceof Name) {
|
||||
if ($this->reflectionProvider->hasFunction($funcCall->name, $scope)) {
|
||||
return $this->reflectionProvider->getFunction($funcCall->name, $scope);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$functionNameFullyQualified = new FullyQualified($functionName);
|
||||
if (! $this->reflectionProvider->hasFunction($functionNameFullyQualified, null)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->reflectionProvider->getFunction($functionNameFullyQualified, null);
|
||||
// fallback to callable
|
||||
$funcCallNameType = $scope->getType($funcCall->name);
|
||||
return $this->typeToCallReflectionResolverRegistry->resolve($funcCallNameType, $scope);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user