Updated Rector to commit 1374e15d742f4f36f0bef45db9f8920a589865b3

1374e15d74 [CodeQuality] Add Function_ and FuncCall support on OptionalParametersAfterRequiredRector (#5835)
This commit is contained in:
Tomas Votruba 2024-04-20 11:01:46 +00:00
parent 6db496ec6b
commit 8aefc5e967
4 changed files with 70 additions and 32 deletions

View File

@ -4,11 +4,14 @@ declare (strict_types=1);
namespace Rector\CodeQuality\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\MethodReflection;
use Rector\CodingStyle\Reflection\VendorLocationDetector;
use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper;
@ -81,41 +84,49 @@ CODE_SAMPLE
*/
public function getNodeTypes() : array
{
return [ClassMethod::class, New_::class, MethodCall::class, StaticCall::class];
return [ClassMethod::class, Function_::class, New_::class, MethodCall::class, StaticCall::class, FuncCall::class];
}
/**
* @param ClassMethod|New_|MethodCall|StaticCall $node
* @return \PhpParser\Node\Stmt\ClassMethod|null|\PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall
* @param ClassMethod|Function_|New_|MethodCall|StaticCall|FuncCall $node
* @return \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|null|\PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall
*/
public function refactorWithScope(Node $node, Scope $scope)
{
if ($node instanceof ClassMethod) {
return $this->refactorClassMethod($node, $scope);
if ($node instanceof ClassMethod || $node instanceof Function_) {
return $this->refactorClassMethodOrFunction($node, $scope);
}
if ($node instanceof New_) {
return $this->refactorNew($node, $scope);
}
return $this->refactorMethodCall($node, $scope);
return $this->refactorMethodCallOrFuncCall($node, $scope);
}
private function refactorClassMethod(ClassMethod $classMethod, Scope $scope) : ?ClassMethod
/**
* @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $node
* @return \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|null
*/
private function refactorClassMethodOrFunction($node, Scope $scope)
{
if ($classMethod->params === []) {
if ($node->params === []) {
return null;
}
if ($classMethod->getAttribute(self::HAS_SWAPPED_PARAMS, \false) === \true) {
if ($node->getAttribute(self::HAS_SWAPPED_PARAMS, \false) === \true) {
return null;
}
$classMethodReflection = $this->reflectionResolver->resolveMethodReflectionFromClassMethod($classMethod, $scope);
if (!$classMethodReflection instanceof MethodReflection) {
if ($node instanceof ClassMethod) {
$reflection = $this->reflectionResolver->resolveMethodReflectionFromClassMethod($node, $scope);
} else {
$reflection = $this->reflectionResolver->resolveFunctionReflectionFromFunction($node, $scope);
}
if (!$reflection instanceof MethodReflection && !$reflection instanceof FunctionReflection) {
return null;
}
$expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($classMethodReflection, $classMethod, $scope);
$expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($reflection, $node, $scope);
if ($expectedArgOrParamOrder === null) {
return null;
}
$classMethod->params = $this->argumentSorter->sortArgsByExpectedParamOrder($classMethod->params, $expectedArgOrParamOrder);
$classMethod->setAttribute(self::HAS_SWAPPED_PARAMS, \true);
return $classMethod;
$node->params = $this->argumentSorter->sortArgsByExpectedParamOrder($node->params, $expectedArgOrParamOrder);
$node->setAttribute(self::HAS_SWAPPED_PARAMS, \true);
return $node;
}
private function refactorNew(New_ $new, Scope $scope) : ?New_
{
@ -137,39 +148,43 @@ CODE_SAMPLE
return $new;
}
/**
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall $methodCall
* @return \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|null
* @param \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall $node
* @return \PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall|null
*/
private function refactorMethodCall($methodCall, Scope $scope)
private function refactorMethodCallOrFuncCall($node, Scope $scope)
{
if ($methodCall->isFirstClassCallable()) {
if ($node->isFirstClassCallable()) {
return null;
}
$methodReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($methodCall);
if (!$methodReflection instanceof MethodReflection) {
$reflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node);
if (!$reflection instanceof MethodReflection && !$reflection instanceof FunctionReflection) {
return null;
}
$expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($methodReflection, $methodCall, $scope);
$expectedArgOrParamOrder = $this->resolveExpectedArgParamOrderIfDifferent($reflection, $node, $scope);
if ($expectedArgOrParamOrder === null) {
return null;
}
$newArgs = $this->argumentSorter->sortArgsByExpectedParamOrder($methodCall->getArgs(), $expectedArgOrParamOrder);
if ($methodCall->args === $newArgs) {
$newArgs = $this->argumentSorter->sortArgsByExpectedParamOrder($node->getArgs(), $expectedArgOrParamOrder);
if ($node->args === $newArgs) {
return null;
}
$methodCall->args = $newArgs;
return $methodCall;
$node->args = $newArgs;
return $node;
}
/**
* @return int[]|null
* @param \PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Expr\StaticCall $node
* @param \PHPStan\Reflection\MethodReflection|\PHPStan\Reflection\FunctionReflection $reflection
* @param \PhpParser\Node\Expr\New_|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\FuncCall $node
*/
private function resolveExpectedArgParamOrderIfDifferent(MethodReflection $methodReflection, $node, Scope $scope) : ?array
private function resolveExpectedArgParamOrderIfDifferent($reflection, $node, Scope $scope) : ?array
{
if ($this->vendorLocationDetector->detectMethodReflection($methodReflection)) {
if ($reflection instanceof MethodReflection && $this->vendorLocationDetector->detectMethodReflection($reflection)) {
return null;
}
$parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($methodReflection, $node, $scope);
if ($reflection instanceof FunctionReflection && $this->vendorLocationDetector->detectFunctionReflection($reflection)) {
return null;
}
$parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($reflection, $node, $scope);
$expectedParameterReflections = $this->requireOptionalParamResolver->resolveFromParametersAcceptor($parametersAcceptor);
if ($expectedParameterReflections === $parametersAcceptor->getParameters()) {
return null;

View File

@ -3,6 +3,7 @@
declare (strict_types=1);
namespace Rector\CodingStyle\Reflection;
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\MethodReflection;
use Rector\FileSystem\FilePathHelper;
final class VendorLocationDetector
@ -20,6 +21,15 @@ final class VendorLocationDetector
{
$declaringClassReflection = $methodReflection->getDeclaringClass();
$fileName = $declaringClassReflection->getFileName();
return $this->detect($fileName);
}
public function detectFunctionReflection(FunctionReflection $functionReflection) : bool
{
$fileName = $functionReflection->getFileName();
return $this->detect($fileName);
}
private function detect(?string $fileName = null) : bool
{
// probably internal
if ($fileName === null) {
return \false;

View File

@ -19,12 +19,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = 'b81ef2f28aee9da0861eb67d90d134ec1c537786';
public const PACKAGE_VERSION = '1374e15d742f4f36f0bef45db9f8920a589865b3';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2024-04-20 04:52:33';
public const RELEASE_DATE = '2024-04-20 17:59:14';
/**
* @var int
*/

View File

@ -15,6 +15,7 @@ use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\FunctionReflection;
@ -183,6 +184,18 @@ final class ReflectionResolver
$methodName = $this->nodeNameResolver->getName($classMethod);
return $this->resolveMethodReflection($className, $methodName, $scope);
}
public function resolveFunctionReflectionFromFunction(Function_ $function, Scope $scope) : ?FunctionReflection
{
$name = $this->nodeNameResolver->getName($function);
if ($name === null) {
return null;
}
$functionName = new Name($name);
if ($this->reflectionProvider->hasFunction($functionName, $scope)) {
return $this->reflectionProvider->getFunction($functionName, $scope);
}
return null;
}
public function resolveMethodReflectionFromNew(New_ $new) : ?MethodReflection
{
$newClassType = $this->nodeTypeResolver->getType($new->class);