From 70b8468a69a26d4c3e629b6138ae0df1fd8d273b Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Fri, 14 Jul 2023 16:16:08 +0000 Subject: [PATCH] Updated Rector to commit 875b2a319f2d01db4ca0d64a6a15d497117f70c8 https://github.com/rectorphp/rector-src/commit/875b2a319f2d01db4ca0d64a6a15d497117f70c8 Implement ReturnTypeFromStrictParamRector (#4501) --- config/set/type-declaration.php | 3 +- .../ReturnTypeFromStrictParamRector.php | 200 ++++++++++++++++++ src/Application/VersionResolver.php | 4 +- vendor/autoload.php | 2 +- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_real.php | 10 +- vendor/composer/autoload_static.php | 9 +- 7 files changed, 216 insertions(+), 13 deletions(-) create mode 100644 rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictParamRector.php diff --git a/config/set/type-declaration.php b/config/set/type-declaration.php index b7f811a7be1..a2da695702d 100644 --- a/config/set/type-declaration.php +++ b/config/set/type-declaration.php @@ -27,6 +27,7 @@ use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictBoolReturnExpr use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictConstantReturnRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictNativeCallRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictNewArrayRector; +use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictParamRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedCallRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictTypedPropertyRector; use Rector\TypeDeclaration\Rector\ClassMethod\StrictArrayParamDimFetchRector; @@ -41,5 +42,5 @@ use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictGetterMethodRe use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictSetUpRector; use Rector\TypeDeclaration\Rector\Property\VarAnnotationIncorrectNullableRector; return static function (RectorConfig $rectorConfig) : void { - $rectorConfig->rules([AddClosureReturnTypeRector::class, AddArrowFunctionReturnTypeRector::class, ParamTypeByMethodCallTypeRector::class, TypedPropertyFromAssignsRector::class, ReturnAnnotationIncorrectNullableRector::class, VarAnnotationIncorrectNullableRector::class, ParamAnnotationIncorrectNullableRector::class, AddReturnTypeDeclarationBasedOnParentClassMethodRector::class, ReturnTypeFromStrictTypedPropertyRector::class, TypedPropertyFromStrictConstructorRector::class, ParamTypeFromStrictTypedPropertyRector::class, AddVoidReturnTypeWhereNoReturnRector::class, ReturnTypeFromReturnNewRector::class, TypedPropertyFromStrictGetterMethodReturnTypeRector::class, AddMethodCallBasedStrictParamTypeRector::class, ArrayShapeFromConstantArrayReturnRector::class, ReturnTypeFromStrictBoolReturnExprRector::class, ReturnTypeFromStrictNativeCallRector::class, ReturnTypeFromStrictNewArrayRector::class, ReturnTypeFromStrictScalarReturnExprRector::class, TypedPropertyFromStrictSetUpRector::class, ParamTypeByParentCallTypeRector::class, AddParamTypeSplFixedArrayRector::class, AddParamTypeBasedOnPHPUnitDataProviderRector::class, AddParamTypeFromPropertyTypeRector::class, AddReturnTypeDeclarationFromYieldsRector::class, ReturnTypeFromReturnDirectArrayRector::class, ReturnTypeFromStrictConstantReturnRector::class, ReturnTypeFromStrictTypedCallRector::class, ReturnNeverTypeRector::class, EmptyOnNullableObjectToInstanceOfRector::class, PropertyTypeFromStrictSetterGetterRector::class, ReturnTypeFromStrictTernaryRector::class, BoolReturnTypeFromStrictScalarReturnsRector::class, NumericReturnTypeFromStrictScalarReturnsRector::class, StrictArrayParamDimFetchRector::class]); + $rectorConfig->rules([AddClosureReturnTypeRector::class, AddArrowFunctionReturnTypeRector::class, ParamTypeByMethodCallTypeRector::class, TypedPropertyFromAssignsRector::class, ReturnAnnotationIncorrectNullableRector::class, VarAnnotationIncorrectNullableRector::class, ParamAnnotationIncorrectNullableRector::class, AddReturnTypeDeclarationBasedOnParentClassMethodRector::class, ReturnTypeFromStrictTypedPropertyRector::class, TypedPropertyFromStrictConstructorRector::class, ParamTypeFromStrictTypedPropertyRector::class, AddVoidReturnTypeWhereNoReturnRector::class, ReturnTypeFromReturnNewRector::class, TypedPropertyFromStrictGetterMethodReturnTypeRector::class, AddMethodCallBasedStrictParamTypeRector::class, ArrayShapeFromConstantArrayReturnRector::class, ReturnTypeFromStrictBoolReturnExprRector::class, ReturnTypeFromStrictNativeCallRector::class, ReturnTypeFromStrictNewArrayRector::class, ReturnTypeFromStrictScalarReturnExprRector::class, ReturnTypeFromStrictParamRector::class, TypedPropertyFromStrictSetUpRector::class, ParamTypeByParentCallTypeRector::class, AddParamTypeSplFixedArrayRector::class, AddParamTypeBasedOnPHPUnitDataProviderRector::class, AddParamTypeFromPropertyTypeRector::class, AddReturnTypeDeclarationFromYieldsRector::class, ReturnTypeFromReturnDirectArrayRector::class, ReturnTypeFromStrictConstantReturnRector::class, ReturnTypeFromStrictTypedCallRector::class, ReturnNeverTypeRector::class, EmptyOnNullableObjectToInstanceOfRector::class, PropertyTypeFromStrictSetterGetterRector::class, ReturnTypeFromStrictTernaryRector::class, BoolReturnTypeFromStrictScalarReturnsRector::class, NumericReturnTypeFromStrictScalarReturnsRector::class, StrictArrayParamDimFetchRector::class]); }; diff --git a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictParamRector.php b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictParamRector.php new file mode 100644 index 00000000000..6993690c704 --- /dev/null +++ b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictParamRector.php @@ -0,0 +1,200 @@ +parentClassMethodTypeOverrideGuard = $parentClassMethodTypeOverrideGuard; + $this->returnTypeInferer = $returnTypeInferer; + } + public function getRuleDefinition() : RuleDefinition + { + return new RuleDefinition('Add return type based on strict parameter type', [new CodeSample(<<<'CODE_SAMPLE' +class SomeClass +{ + public function resolve(ParamType $item) + { + return $item; + } +} +CODE_SAMPLE +, <<<'CODE_SAMPLE' +class SomeClass +{ + public function resolve(ParamType $item): ParamType + { + return $item; + } +} +CODE_SAMPLE +)]); + } + /** + * @return array> + */ + public function getNodeTypes() : array + { + return [ClassMethod::class, Function_::class]; + } + public function provideMinPhpVersion() : int + { + return PhpVersionFeature::NULLABLE_TYPE; + } + /** + * @param ClassMethod|Function_ $node + */ + public function refactorWithScope(Node $node, Scope $scope) : ?Node + { + if ($this->shouldSkipNode($node)) { + return null; + } + $return = $this->findCurrentScopeReturn($node); + if ($return === null || $return->expr === null) { + return null; + } + $returnName = $this->getName($return->expr); + foreach ($node->getParams() as $param) { + if (!$param->type instanceof Node) { + continue; + } + if ($this->shouldSkipParam($param, $node)) { + continue; + } + $paramName = $this->getName($param); + if ($returnName !== $paramName) { + continue; + } + $node->returnType = $param->type; + return $node; + } + return null; + } + /** + * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $node + */ + private function findCurrentScopeReturn($node) : ?Return_ + { + $return = null; + if ($node->stmts === null) { + return null; + } + $this->traverseNodesWithCallable($node->stmts, function (Node $node) use(&$return) : ?int { + if (!$node instanceof Return_) { + return null; + } + // skip scope nesting + if ($node instanceof FunctionLike) { + $return = null; + return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN; + } + if (!$node->expr instanceof Variable) { + $return = null; + return NodeTraverser::STOP_TRAVERSAL; + } + $return = $node; + return null; + }); + return $return; + } + /** + * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $functionLike + */ + private function shouldSkipParam(Param $param, $functionLike) : bool + { + $paramName = $this->getName($param); + $isParamModified = \false; + if ($functionLike->stmts === null) { + return \true; + } + $this->traverseNodesWithCallable($functionLike->stmts, function (Node $node) use($paramName, &$isParamModified) : ?int { + if ($node instanceof Expr\AssignRef) { + if ($this->isName($node->expr, $paramName)) { + $isParamModified = \true; + return NodeTraverser::STOP_TRAVERSAL; + } + } + if (!$node instanceof Expr\Assign) { + return null; + } + if (!$node->var instanceof Variable) { + return null; + } + if (!$this->isName($node->var, $paramName)) { + return null; + } + $isParamModified = \true; + return NodeTraverser::STOP_TRAVERSAL; + }); + return $isParamModified; + } + /** + * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_ $node + */ + private function shouldSkipNode($node) : bool + { + if ($node->returnType !== null) { + return \true; + } + if ($node instanceof ClassMethod) { + if ($this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($node)) { + return \true; + } + if ($node->isMagic()) { + return \true; + } + } + $returnType = $this->returnTypeInferer->inferFunctionLike($node); + if ($returnType instanceof MixedType) { + return \true; + } + $returnType = TypeCombinator::removeNull($returnType); + if ($returnType instanceof UnionType) { + return \true; + } + return \false; + } +} diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index cbb85c6d3a2..066c3791e9f 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 = 'b3c4aff2ad46d78c1c03800c7301129601aefc4e'; + public const PACKAGE_VERSION = '875b2a319f2d01db4ca0d64a6a15d497117f70c8'; /** * @api * @var string */ - public const RELEASE_DATE = '2023-07-14 14:29:05'; + public const RELEASE_DATE = '2023-07-14 18:11:28'; /** * @var int */ diff --git a/vendor/autoload.php b/vendor/autoload.php index 5edf95d2fc9..ee54c57cd1c 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) { require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInitaee7c0d4830994391cda22ff148fbc69::getLoader(); +return ComposerAutoloaderInitac080fa2a0af7d5d0027d02ac2277463::getLoader(); diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 5ca1740ed10..6a797bb4bfa 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -2700,6 +2700,7 @@ return array( 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictConstantReturnRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictConstantReturnRector.php', 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictNativeCallRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictNativeCallRector.php', 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictNewArrayRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictNewArrayRector.php', + 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictParamRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictParamRector.php', 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictTypedCallRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedCallRector.php', 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictTypedPropertyRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedPropertyRector.php', 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\StrictArrayParamDimFetchRector' => $baseDir . '/rules/TypeDeclaration/Rector/ClassMethod/StrictArrayParamDimFetchRector.php', diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 1f158ef252a..2651f3e8c50 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitaee7c0d4830994391cda22ff148fbc69 +class ComposerAutoloaderInitac080fa2a0af7d5d0027d02ac2277463 { private static $loader; @@ -22,17 +22,17 @@ class ComposerAutoloaderInitaee7c0d4830994391cda22ff148fbc69 return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitaee7c0d4830994391cda22ff148fbc69', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInitac080fa2a0af7d5d0027d02ac2277463', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInitaee7c0d4830994391cda22ff148fbc69', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInitac080fa2a0af7d5d0027d02ac2277463', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInitaee7c0d4830994391cda22ff148fbc69::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInitac080fa2a0af7d5d0027d02ac2277463::getInitializer($loader)); $loader->setClassMapAuthoritative(true); $loader->register(true); - $filesToLoad = \Composer\Autoload\ComposerStaticInitaee7c0d4830994391cda22ff148fbc69::$files; + $filesToLoad = \Composer\Autoload\ComposerStaticInitac080fa2a0af7d5d0027d02ac2277463::$files; $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index d46e0d8cda0..275b0f2dbc9 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInitaee7c0d4830994391cda22ff148fbc69 +class ComposerStaticInitac080fa2a0af7d5d0027d02ac2277463 { public static $files = array ( 'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php', @@ -2954,6 +2954,7 @@ class ComposerStaticInitaee7c0d4830994391cda22ff148fbc69 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictConstantReturnRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictConstantReturnRector.php', 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictNativeCallRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictNativeCallRector.php', 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictNewArrayRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictNewArrayRector.php', + 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictParamRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictParamRector.php', 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictTypedCallRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedCallRector.php', 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\ReturnTypeFromStrictTypedPropertyRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictTypedPropertyRector.php', 'Rector\\TypeDeclaration\\Rector\\ClassMethod\\StrictArrayParamDimFetchRector' => __DIR__ . '/../..' . '/rules/TypeDeclaration/Rector/ClassMethod/StrictArrayParamDimFetchRector.php', @@ -3027,9 +3028,9 @@ class ComposerStaticInitaee7c0d4830994391cda22ff148fbc69 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInitaee7c0d4830994391cda22ff148fbc69::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitaee7c0d4830994391cda22ff148fbc69::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInitaee7c0d4830994391cda22ff148fbc69::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInitac080fa2a0af7d5d0027d02ac2277463::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitac080fa2a0af7d5d0027d02ac2277463::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInitac080fa2a0af7d5d0027d02ac2277463::$classMap; }, null, ClassLoader::class); }