Skip to content

Commit

Permalink
Unite any extra reflection parsing to single ReflectionResolver servi…
Browse files Browse the repository at this point in the history
…ce (#313)
  • Loading branch information
TomasVotruba committed Jun 27, 2021
1 parent 9d4c4ff commit a435716
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 242 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Php70\Rector\FuncCall\NonVariableToVariableOnFunctionCallRector\Source;

final class InvokableConstructorArgument
{
public function __invoke(&$bar)
{
}
}
12 changes: 6 additions & 6 deletions rules/CodingStyle/Rector/ClassMethod/UnSpreadOperatorRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
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;

Expand All @@ -25,7 +25,7 @@ final class UnSpreadOperatorRector extends AbstractRector
{
public function __construct(
private SpreadVariablesCollector $spreadVariablesCollector,
private CallReflectionResolver $callReflectionResolver,
private ReflectionResolver $reflectionResolver
) {
}

Expand Down Expand Up @@ -101,18 +101,18 @@ private function processUnspreadOperatorClassMethodParams(ClassMethod $classMeth

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;
Expand Down
11 changes: 6 additions & 5 deletions rules/Defluent/NodeAnalyzer/SameClassMethodCallAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@

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,
) {
}

Expand All @@ -24,10 +25,10 @@ public function haveSingleClass(array $chainMethodCalls): bool
// 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
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;

Expand All @@ -29,7 +29,7 @@
final class DowngradeNamedArgumentRector extends AbstractRector
{
public function __construct(
private CallReflectionResolver $callReflectionResolver,
private ReflectionResolver $reflectionResolver
) {
}

Expand Down Expand Up @@ -99,20 +99,20 @@ public function refactor(Node $node): ?Node
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;
}

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);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
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;
Expand All @@ -39,9 +39,9 @@
final class NonVariableToVariableOnFunctionCallRector extends AbstractRector
{
public function __construct(
private CallReflectionResolver $callReflectionResolver,
private VariableNaming $variableNaming,
private ParentScopeFinder $parentScopeFinder
private ParentScopeFinder $parentScopeFinder,
private ReflectionResolver $reflectionResolver
) {
}

Expand Down Expand Up @@ -107,34 +107,35 @@ public function refactor(Node $node): ?Node
}

/**
* @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 [];
}

/** @var ParameterReflection $parameterReflection */
foreach ($parametersAcceptor->getParameters() as $key => $parameterReflection) {
// omitted optional parameter
if (! isset($node->args[$key])) {
if (! isset($call->args[$key])) {
continue;
}

if ($parameterReflection->passedByReference()->no()) {
continue;
}

$argument = $node->args[$key]->value;
$argument = $call->args[$key]->value;

if ($this->isVariableLikeNode($argument)) {
continue;
Expand Down
8 changes: 4 additions & 4 deletions rules/Php71/Rector/FuncCall/RemoveExtraParametersRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
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;

Expand All @@ -28,8 +28,8 @@
final class RemoveExtraParametersRector extends AbstractRector
{
public function __construct(
private CallReflectionResolver $callReflectionResolver,
private VariadicAnalyzer $variadicAnalyzer
private VariadicAnalyzer $variadicAnalyzer,
private ReflectionResolver $reflectionResolver
) {
}

Expand Down Expand Up @@ -58,7 +58,7 @@ public function refactor(Node $node): ?Node
}

// unreliable count of arguments
$functionLikeReflection = $this->callReflectionResolver->resolveCall($node);
$functionLikeReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node);
if ($functionLikeReflection instanceof UnionTypeMethodReflection) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
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;
Expand All @@ -28,7 +27,6 @@ final class OptionalParametersAfterRequiredRector extends AbstractRector
public function __construct(
private RequireOptionalParamResolver $requireOptionalParamResolver,
private ArgumentSorter $argumentSorter,
private CallReflectionResolver $callReflectionResolver,
private ReflectionResolver $reflectionResolver
) {
}
Expand Down Expand Up @@ -137,7 +135,7 @@ private function refactorNew(New_ $new): ?New_

private function refactorMethodCall(MethodCall $methodCall): ?MethodCall
{
$methodReflection = $this->callReflectionResolver->resolveCall($methodCall);
$methodReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($methodCall);
if (! $methodReflection instanceof MethodReflection) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
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;
Expand All @@ -35,7 +35,7 @@ final class ReturnTypeFromStrictTypedCallRector extends AbstractRector
{
public function __construct(
private TypeNodeUnwrapper $typeNodeUnwrapper,
private CallReflectionResolver $callReflectionResolver
private ReflectionResolver $reflectionResolver
) {
}

Expand Down Expand Up @@ -179,7 +179,7 @@ private function collectStrictReturnTypes(array $returns): array

private function resolveMethodCallReturnNode(MethodCall | StaticCall | FuncCall $call): ?Node
{
$methodReflection = $this->callReflectionResolver->resolveCall($call);
$methodReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($call);
if ($methodReflection === null) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
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;
Expand All @@ -41,9 +41,9 @@ public function __construct(
private SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
private TypeFactory $typeFactory,
private SplArrayFixedTypeNarrower $splArrayFixedTypeNarrower,
private CallReflectionResolver $callReflectionResolver,
private AstResolver $reflectionAstResolver,
private BetterStandardPrinter $betterStandardPrinter
private BetterStandardPrinter $betterStandardPrinter,
private ReflectionResolver $reflectionResolver
) {
}

Expand Down Expand Up @@ -143,20 +143,12 @@ private function inferFromReturnedMethodCall(Return_ $return, FunctionLike $orig
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
Expand Down Expand Up @@ -202,21 +194,4 @@ private function resolveClassMethod(MethodReflection $methodReflection, Function

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);
}
}

0 comments on commit a435716

Please sign in to comment.