From 5454cfa6b9ed92ee23ab22f2511b8c5f1646d55d Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 3 Aug 2023 15:09:44 +0000 Subject: [PATCH] Updated Rector to commit 527f2140e38fba2f9419686552402e41d9893d81 https://github.com/rectorphp/rector-src/commit/527f2140e38fba2f9419686552402e41d9893d81 [TypeDeclaration] Add nullable param from null compare on StrictStringParamConcatRector (#4636) --- .../StrictStringParamConcatRector.php | 60 ++++++++++++------- src/Application/VersionResolver.php | 4 +- vendor/autoload.php | 2 +- vendor/composer/autoload_real.php | 10 ++-- vendor/composer/autoload_static.php | 8 +-- 5 files changed, 52 insertions(+), 32 deletions(-) diff --git a/rules/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector.php b/rules/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector.php index 8eafacc94e67..8b1091bf7f83 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector.php @@ -10,11 +10,15 @@ use PhpParser\Node\Expr\Variable; use PhpParser\Node\FunctionLike; use PhpParser\Node\Identifier; +use PhpParser\Node\NullableType; use PhpParser\Node\Param; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Function_; use PhpParser\NodeTraverser; +use PHPStan\Type\MixedType; +use PHPStan\Type\Type; +use PHPStan\Type\TypeCombinator; use Rector\Core\Rector\AbstractRector; use Rector\VendorLocker\ParentClassMethodTypeOverrideGuard; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -75,10 +79,16 @@ public function refactor(Node $node) : ?Node if ($param->type instanceof Node) { continue; } - if (!$this->isParamConcatted($param, $node)) { + $variableConcattedFromParam = $this->resolveVariableConcattedFromParam($param, $node); + if (!$variableConcattedFromParam instanceof Variable) { continue; } - $param->type = new Identifier('string'); + $nativeType = $this->nodeTypeResolver->getNativeType($variableConcattedFromParam); + if ($nativeType instanceof MixedType && $nativeType->getSubtractedType() instanceof Type && TypeCombinator::containsNull($nativeType->getSubtractedType())) { + $param->type = new NullableType(new Identifier('string')); + } else { + $param->type = new Identifier('string'); + } $hasChanged = \true; } if ($hasChanged) { @@ -89,30 +99,34 @@ public function refactor(Node $node) : ?Node /** * @param \PhpParser\Node\Stmt\ClassMethod|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Expr\Closure $functionLike */ - private function isParamConcatted(Param $param, $functionLike) : bool + private function resolveVariableConcattedFromParam(Param $param, $functionLike) : ?Variable { if ($functionLike->stmts === null) { - return \false; + return null; } if ($param->default instanceof Expr && !$this->getType($param->default)->isString()->yes()) { - return \false; + return null; } $paramName = $this->getName($param); - $isParamConcatted = \false; - $this->traverseNodesWithCallable($functionLike->stmts, function (Node $node) use($paramName, &$isParamConcatted) : ?int { + $variableConcatted = null; + $this->traverseNodesWithCallable($functionLike->stmts, function (Node $node) use($paramName, &$variableConcatted) : ?int { // skip nested class and function nodes if ($node instanceof FunctionLike || $node instanceof Class_) { return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN; } - if ($this->isAssignConcat($node, $paramName)) { - $isParamConcatted = \true; + $expr = $this->resolveAssignConcatVariable($node, $paramName); + if ($expr instanceof Variable) { + $variableConcatted = $node; + return NodeTraverser::STOP_TRAVERSAL; } - if ($this->isBinaryConcat($node, $paramName)) { - $isParamConcatted = \true; + $variableBinaryConcat = $this->resolveBinaryConcatVariable($node, $paramName); + if ($variableBinaryConcat instanceof Variable) { + $variableConcatted = $variableBinaryConcat; + return NodeTraverser::STOP_TRAVERSAL; } return null; }); - return $isParamConcatted; + return $variableConcatted; } private function isVariableWithSameParam(Expr $expr, string $paramName) : bool { @@ -121,24 +135,30 @@ private function isVariableWithSameParam(Expr $expr, string $paramName) : bool } return $this->isName($expr, $paramName); } - private function isAssignConcat(Node $node, string $paramName) : bool + private function resolveAssignConcatVariable(Node $node, string $paramName) : ?Expr { if (!$node instanceof Concat) { - return \false; + return null; } if ($this->isVariableWithSameParam($node->var, $paramName)) { - return \true; + return $node->var; } - return $this->isVariableWithSameParam($node->expr, $paramName); + if ($this->isVariableWithSameParam($node->expr, $paramName)) { + return $node->expr; + } + return null; } - private function isBinaryConcat(Node $node, string $paramName) : bool + private function resolveBinaryConcatVariable(Node $node, string $paramName) : ?Expr { if (!$node instanceof Expr\BinaryOp\Concat) { - return \false; + return null; } if ($this->isVariableWithSameParam($node->left, $paramName)) { - return \true; + return $node->left; + } + if ($this->isVariableWithSameParam($node->right, $paramName)) { + return $node->right; } - return $this->isVariableWithSameParam($node->right, $paramName); + return null; } } diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index 8bf3d0af110e..08cb97b9a201 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 = '25b6142f69577a83fc86fd4a3ddad57af470ba26'; + public const PACKAGE_VERSION = '527f2140e38fba2f9419686552402e41d9893d81'; /** * @api * @var string */ - public const RELEASE_DATE = '2023-08-03 21:25:18'; + public const RELEASE_DATE = '2023-08-03 22:05:24'; /** * @var int */ diff --git a/vendor/autoload.php b/vendor/autoload.php index c46477d564c6..eb30bfd56ec8 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -22,4 +22,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInitf0e80ee6aec55dbed7080efbd3bec8fa::getLoader(); +return ComposerAutoloaderInitb42cfa24f57ca8b6e92b28f61afe53ef::getLoader(); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 7a0600dea657..5e4cc8fed8fd 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitf0e80ee6aec55dbed7080efbd3bec8fa +class ComposerAutoloaderInitb42cfa24f57ca8b6e92b28f61afe53ef { private static $loader; @@ -22,17 +22,17 @@ public static function getLoader() return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitf0e80ee6aec55dbed7080efbd3bec8fa', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInitb42cfa24f57ca8b6e92b28f61afe53ef', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInitf0e80ee6aec55dbed7080efbd3bec8fa', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInitb42cfa24f57ca8b6e92b28f61afe53ef', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInitf0e80ee6aec55dbed7080efbd3bec8fa::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInitb42cfa24f57ca8b6e92b28f61afe53ef::getInitializer($loader)); $loader->setClassMapAuthoritative(true); $loader->register(true); - $filesToLoad = \Composer\Autoload\ComposerStaticInitf0e80ee6aec55dbed7080efbd3bec8fa::$files; + $filesToLoad = \Composer\Autoload\ComposerStaticInitb42cfa24f57ca8b6e92b28f61afe53ef::$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 b5333286a4b9..84ccd3bd3497 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInitf0e80ee6aec55dbed7080efbd3bec8fa +class ComposerStaticInitb42cfa24f57ca8b6e92b28f61afe53ef { public static $files = array ( 'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php', @@ -3025,9 +3025,9 @@ class ComposerStaticInitf0e80ee6aec55dbed7080efbd3bec8fa public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInitf0e80ee6aec55dbed7080efbd3bec8fa::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitf0e80ee6aec55dbed7080efbd3bec8fa::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInitf0e80ee6aec55dbed7080efbd3bec8fa::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInitb42cfa24f57ca8b6e92b28f61afe53ef::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitb42cfa24f57ca8b6e92b28f61afe53ef::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInitb42cfa24f57ca8b6e92b28f61afe53ef::$classMap; }, null, ClassLoader::class); }