From 7eb9eec801a8a1d3ce89e1b21ebb509aa8896aa1 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 22 May 2023 10:21:31 +0000 Subject: [PATCH] Updated Rector to commit 6c3f2cdf953587cdf0945c7fb6c05fd0083c25fc https://github.com/rectorphp/rector-src/commit/6c3f2cdf953587cdf0945c7fb6c05fd0083c25fc [DX] Deprecate parent node attribute, allow return of NodeTraverser::* in refactor() method (#3922) --- .../NodeTypeResolver/Node/AttributeKey.php | 3 + .../ChangeArrayPushToArrayAssignRector.php | 5 +- .../Rector/FuncCall/SetTypeToCastRector.php | 67 +++++++++++++------ src/Application/VersionResolver.php | 4 +- src/Contract/Rector/PhpRectorInterface.php | 3 +- src/Rector/AbstractRector.php | 6 +- vendor/autoload.php | 2 +- vendor/composer/autoload_real.php | 10 +-- vendor/composer/autoload_static.php | 8 +-- 9 files changed, 73 insertions(+), 35 deletions(-) diff --git a/packages/NodeTypeResolver/Node/AttributeKey.php b/packages/NodeTypeResolver/Node/AttributeKey.php index 0b147bf959f..e7361ea6628 100644 --- a/packages/NodeTypeResolver/Node/AttributeKey.php +++ b/packages/NodeTypeResolver/Node/AttributeKey.php @@ -63,6 +63,9 @@ final class AttributeKey */ public const RESOLVED_NAME = 'resolvedName'; /** + * @deprecated Refactor to a custom visitors/parent node instead, + * @see https://phpstan.org/blog/preprocessing-ast-for-custom-rules + * * @internal of php-parser, do not change * @see https://github.com/nikic/PHP-Parser/pull/681/files * @var string diff --git a/rules/CodeQuality/Rector/FuncCall/ChangeArrayPushToArrayAssignRector.php b/rules/CodeQuality/Rector/FuncCall/ChangeArrayPushToArrayAssignRector.php index 329d168b074..ab5c22f9375 100644 --- a/rules/CodeQuality/Rector/FuncCall/ChangeArrayPushToArrayAssignRector.php +++ b/rules/CodeQuality/Rector/FuncCall/ChangeArrayPushToArrayAssignRector.php @@ -7,6 +7,7 @@ use PhpParser\Node; use PhpParser\Node\Expr\ArrayDimFetch; use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\FuncCall; +use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Expression; use Rector\Core\Rector\AbstractRector; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -38,8 +39,8 @@ CODE_SAMPLE return [Expression::class]; } /** - * @param Expression[] $node - * @param Expression[]|null $node + * @param Expression $node + * @return Stmt[]|null */ public function refactor(Node $node) : ?array { diff --git a/rules/CodeQuality/Rector/FuncCall/SetTypeToCastRector.php b/rules/CodeQuality/Rector/FuncCall/SetTypeToCastRector.php index 772828a7e2f..28d8f0d7037 100644 --- a/rules/CodeQuality/Rector/FuncCall/SetTypeToCastRector.php +++ b/rules/CodeQuality/Rector/FuncCall/SetTypeToCastRector.php @@ -3,8 +3,9 @@ declare (strict_types=1); namespace Rector\CodeQuality\Rector\FuncCall; -use PhpParser\Node; +use PhpParser\Node\Expr\ArrayItem; use PhpParser\Node\Arg; +use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\Cast; @@ -16,8 +17,8 @@ use PhpParser\Node\Expr\Cast\Object_; use PhpParser\Node\Expr\Cast\String_; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Stmt\Expression; +use PhpParser\NodeTraverser; use Rector\Core\Rector\AbstractRector; -use Rector\NodeTypeResolver\Node\AttributeKey; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** @@ -62,42 +63,70 @@ CODE_SAMPLE */ public function getNodeTypes() : array { - return [FuncCall::class]; + return [FuncCall::class, Expression::class, Assign::class, ArrayItem::class, Arg::class]; } /** - * @param FuncCall $node + * @param FuncCall|Expression|Assign|Expr\ArrayItem|Node\Arg $node */ - public function refactor(Node $node) : ?Node + public function refactor(Node $node) { - if (!$this->isName($node, 'settype')) { + if ($node instanceof Arg || $node instanceof ArrayItem) { + if ($this->isSetTypeFuncCall($node->value)) { + return NodeTraverser::STOP_TRAVERSAL; + } return null; } - if ($node->isFirstClassCallable()) { + if ($node instanceof Assign) { + if (!$this->isSetTypeFuncCall($node->expr)) { + return null; + } + return NodeTraverser::DONT_TRAVERSE_CHILDREN; + } + if ($node instanceof Expression) { + if (!$node->expr instanceof FuncCall) { + return null; + } + return $this->refactorFuncCall($node->expr, \true); + } + return $this->refactorFuncCall($node, \false); + } + /** + * @return \PhpParser\Node\Expr\Assign|null|\PhpParser\Node\Expr\Cast + */ + private function refactorFuncCall(FuncCall $funcCall, bool $isStandaloneExpression) + { + if (!$this->isSetTypeFuncCall($funcCall)) { return null; } - $typeValue = $this->valueResolver->getValue($node->getArgs()[1]->value); + if ($funcCall->isFirstClassCallable()) { + return null; + } + $typeValue = $this->valueResolver->getValue($funcCall->getArgs()[1]->value); if (!\is_string($typeValue)) { return null; } $typeValue = \strtolower($typeValue); - $variable = $node->getArgs()[0]->value; - $parentNode = $node->getAttribute(AttributeKey::PARENT_NODE); - // result of function or probably used - if ($parentNode instanceof Expr || $parentNode instanceof Arg) { - return null; - } + $variable = $funcCall->getArgs()[0]->value; if (isset(self::TYPE_TO_CAST[$typeValue])) { $castClass = self::TYPE_TO_CAST[$typeValue]; $castNode = new $castClass($variable); - if ($parentNode instanceof Expression) { - // bare expression? → assign - return new Assign($variable, $castNode); + if (!$isStandaloneExpression) { + return $castNode; } - return $castNode; + // bare expression? → assign + return new Assign($variable, $castNode); } if ($typeValue === 'null') { return new Assign($variable, $this->nodeFactory->createNull()); } - return $node; + return null; + } + private function isSetTypeFuncCall(Expr $expr) : bool + { + // skip assign of settype() calls + if (!$expr instanceof FuncCall) { + return \false; + } + return $this->isName($expr, 'settype'); } } diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index 940185a4d47..30f5aed0a0c 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 = '71f00d95fc16f31f7af4a524d5e179f467089e16'; + public const PACKAGE_VERSION = '6c3f2cdf953587cdf0945c7fb6c05fd0083c25fc'; /** * @api * @var string */ - public const RELEASE_DATE = '2023-05-22 09:36:48'; + public const RELEASE_DATE = '2023-05-22 11:17:13'; /** * @var int */ diff --git a/src/Contract/Rector/PhpRectorInterface.php b/src/Contract/Rector/PhpRectorInterface.php index 880cbd44aef..68952f53a61 100644 --- a/src/Contract/Rector/PhpRectorInterface.php +++ b/src/Contract/Rector/PhpRectorInterface.php @@ -4,6 +4,7 @@ declare (strict_types=1); namespace Rector\Core\Contract\Rector; use PhpParser\Node; +use PhpParser\NodeTraverser; use PhpParser\NodeVisitor; interface PhpRectorInterface extends NodeVisitor, \Rector\Core\Contract\Rector\RectorInterface { @@ -16,7 +17,7 @@ interface PhpRectorInterface extends NodeVisitor, \Rector\Core\Contract\Rector\R public function getNodeTypes() : array; /** * Process Node of matched type - * @return Node|Node[]|null + * @return Node|Node[]|null|NodeTraverser::* */ public function refactor(Node $node); } diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index 6878b0c5124..7bbf8b8be22 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -198,7 +198,7 @@ CODE_SAMPLE; $this->file = $file; return parent::beforeTraverse($nodes); } - public final function enterNode(Node $node) : ?Node + public final function enterNode(Node $node) { $nodeClass = \get_class($node); if (!$this->isMatchingNodeType($nodeClass)) { @@ -226,6 +226,10 @@ CODE_SAMPLE; if ($isDebug) { $this->printConsumptions($startTime, $previousMemory); } + // @see NodeTravser::* codes, e.g. removal of node of stopping the traversing + if (\is_int($refactoredNode)) { + return $refactoredNode; + } // nothing to change or just removed via removeNode() → continue if ($refactoredNode === null) { return null; diff --git a/vendor/autoload.php b/vendor/autoload.php index c131dd3a271..c20b3f6f858 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 ComposerAutoloaderInit3712b0afac0260aa32da597f12f94421::getLoader(); +return ComposerAutoloaderInit0496443b94e3d99fc8b2d4c433dfc95e::getLoader(); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 0e2d44112f1..6dd536d0a3a 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit3712b0afac0260aa32da597f12f94421 +class ComposerAutoloaderInit0496443b94e3d99fc8b2d4c433dfc95e { private static $loader; @@ -22,17 +22,17 @@ class ComposerAutoloaderInit3712b0afac0260aa32da597f12f94421 return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit3712b0afac0260aa32da597f12f94421', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit0496443b94e3d99fc8b2d4c433dfc95e', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); - spl_autoload_unregister(array('ComposerAutoloaderInit3712b0afac0260aa32da597f12f94421', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit0496443b94e3d99fc8b2d4c433dfc95e', 'loadClassLoader')); require __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit3712b0afac0260aa32da597f12f94421::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit0496443b94e3d99fc8b2d4c433dfc95e::getInitializer($loader)); $loader->setClassMapAuthoritative(true); $loader->register(true); - $filesToLoad = \Composer\Autoload\ComposerStaticInit3712b0afac0260aa32da597f12f94421::$files; + $filesToLoad = \Composer\Autoload\ComposerStaticInit0496443b94e3d99fc8b2d4c433dfc95e::$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 2e3ff5341ad..f0c506aa238 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit3712b0afac0260aa32da597f12f94421 +class ComposerStaticInit0496443b94e3d99fc8b2d4c433dfc95e { public static $files = array ( 'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php', @@ -3114,9 +3114,9 @@ class ComposerStaticInit3712b0afac0260aa32da597f12f94421 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit3712b0afac0260aa32da597f12f94421::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit3712b0afac0260aa32da597f12f94421::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit3712b0afac0260aa32da597f12f94421::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit0496443b94e3d99fc8b2d4c433dfc95e::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit0496443b94e3d99fc8b2d4c433dfc95e::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit0496443b94e3d99fc8b2d4c433dfc95e::$classMap; }, null, ClassLoader::class); }