From 8aefc5e967eaf162355eda9f366328be03ceaa76 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sat, 20 Apr 2024 11:01:46 +0000 Subject: [PATCH] Updated Rector to commit 1374e15d742f4f36f0bef45db9f8920a589865b3 https://github.com/rectorphp/rector-src/commit/1374e15d742f4f36f0bef45db9f8920a589865b3 [CodeQuality] Add Function_ and FuncCall support on OptionalParametersAfterRequiredRector (#5835) --- .../OptionalParametersAfterRequiredRector.php | 75 +++++++++++-------- .../Reflection/VendorLocationDetector.php | 10 +++ src/Application/VersionResolver.php | 4 +- src/Reflection/ReflectionResolver.php | 13 ++++ 4 files changed, 70 insertions(+), 32 deletions(-) diff --git a/rules/CodeQuality/Rector/ClassMethod/OptionalParametersAfterRequiredRector.php b/rules/CodeQuality/Rector/ClassMethod/OptionalParametersAfterRequiredRector.php index ff231e82402..e0ea1e6f0f7 100644 --- a/rules/CodeQuality/Rector/ClassMethod/OptionalParametersAfterRequiredRector.php +++ b/rules/CodeQuality/Rector/ClassMethod/OptionalParametersAfterRequiredRector.php @@ -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; diff --git a/rules/CodingStyle/Reflection/VendorLocationDetector.php b/rules/CodingStyle/Reflection/VendorLocationDetector.php index 6a295d3363e..b8d255613be 100644 --- a/rules/CodingStyle/Reflection/VendorLocationDetector.php +++ b/rules/CodingStyle/Reflection/VendorLocationDetector.php @@ -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; diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index 1ae1ab0a6a9..042458285b6 100644 --- a/src/Application/VersionResolver.php +++ b/src/Application/VersionResolver.php @@ -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 */ diff --git a/src/Reflection/ReflectionResolver.php b/src/Reflection/ReflectionResolver.php index da71c143ae6..0273d196b4b 100644 --- a/src/Reflection/ReflectionResolver.php +++ b/src/Reflection/ReflectionResolver.php @@ -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);