From 8c599b458a43f422ebe56c37936e271663162502 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 11 Oct 2026 01:13:46 +0200 Subject: [PATCH] [CodeQuality] Deprecate MoveInnerFunctionToTopLevelRector as niche rule, not part of PHP upgrade path --- .../Fixture/inner_function.php.inc | 30 ------ .../Fixture/skip_name_collision.php.inc | 17 --- .../skip_redefine_native_function.php.inc | 20 ---- .../Fixture/skip_top_level_function.php.inc | 13 --- .../MoveInnerFunctionToTopLevelRectorTest.php | 28 ----- .../config/configured_rule.php | 9 -- .../MoveInnerFunctionToTopLevelRector.php | 102 ++---------------- src/Config/Level/CodeQualityLevel.php | 2 - 8 files changed, 8 insertions(+), 213 deletions(-) delete mode 100644 rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/Fixture/inner_function.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/Fixture/skip_name_collision.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/Fixture/skip_redefine_native_function.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/Fixture/skip_top_level_function.php.inc delete mode 100644 rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/MoveInnerFunctionToTopLevelRectorTest.php delete mode 100644 rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/config/configured_rule.php diff --git a/rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/Fixture/inner_function.php.inc b/rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/Fixture/inner_function.php.inc deleted file mode 100644 index d906ce3818e..00000000000 --- a/rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/Fixture/inner_function.php.inc +++ /dev/null @@ -1,30 +0,0 @@ - ------ - diff --git a/rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/Fixture/skip_name_collision.php.inc b/rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/Fixture/skip_name_collision.php.inc deleted file mode 100644 index 2759ca25fb8..00000000000 --- a/rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/Fixture/skip_name_collision.php.inc +++ /dev/null @@ -1,17 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule.php'; - } -} diff --git a/rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/config/configured_rule.php b/rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/config/configured_rule.php deleted file mode 100644 index 4d63cf96529..00000000000 --- a/rules-tests/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector/config/configured_rule.php +++ /dev/null @@ -1,9 +0,0 @@ -withRules([MoveInnerFunctionToTopLevelRector::class]); diff --git a/rules/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector.php b/rules/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector.php index 00d29f4fcfc..96692ccd4a3 100644 --- a/rules/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector.php +++ b/rules/CodeQuality/Rector/StmtsAwareInterface/MoveInnerFunctionToTopLevelRector.php @@ -5,26 +5,18 @@ namespace Rector\CodeQuality\Rector\StmtsAwareInterface; use PhpParser\Node; -use PhpParser\Node\Name; -use PhpParser\Node\Stmt\Function_; -use PHPStan\Reflection\Native\NativeFunctionReflection; -use PHPStan\Reflection\ReflectionProvider; +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; +use Rector\Exception\ShouldNotHappenException; use Rector\PhpParser\Enum\NodeGroup; use Rector\Rector\AbstractRector; use Rector\RuleDoc\CodeSample\CodeSample; use Rector\RuleDoc\RuleDefinition; /** - * @see \Rector\Tests\CodeQuality\Rector\StmtsAwareInterface\MoveInnerFunctionToTopLevelRector\MoveInnerFunctionToTopLevelRectorTest + * @deprecated This rule is deprecated, as it handles a niche inner-function case that is not part of the PHP upgrade path. Use a custom rule instead. */ -final class MoveInnerFunctionToTopLevelRector extends AbstractRector +final class MoveInnerFunctionToTopLevelRector extends AbstractRector implements DeprecatedInterface { - public function __construct( - private readonly ReflectionProvider $reflectionProvider - ) { - - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( @@ -72,87 +64,9 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - $stmts = (array) $node->stmts; - - $newStmts = []; - $hasChanged = false; - - foreach ($stmts as $stmt) { - if (! $stmt instanceof Function_) { - $newStmts[] = $stmt; - continue; - } - - $innerFunctions = $this->extractInnerFunctions($stmt, $stmts); - foreach ($innerFunctions as $innerFunction) { - $newStmts[] = $innerFunction; - $hasChanged = true; - } - - $newStmts[] = $stmt; - } - - if (! $hasChanged) { - return null; - } - - $node->stmts = $newStmts; - - return $node; - } - - /** - * @param Node\Stmt[] $siblingStmts - * @return Function_[] - */ - private function extractInnerFunctions(Function_ $outerFunction, array $siblingStmts): array - { - $innerFunctions = []; - - foreach ($outerFunction->stmts as $key => $innerStmt) { - if (! $innerStmt instanceof Function_) { - continue; - } - - // avoid fatal error on name collision with an existing top-level function - if ($this->hasSiblingFunctionOfSameName($innerStmt, $siblingStmts)) { - continue; - } - - $innerFunctions[] = $innerStmt; - unset($outerFunction->stmts[$key]); - } - - if ($innerFunctions !== []) { - $outerFunction->stmts = array_values($outerFunction->stmts); - } - - return $innerFunctions; - } - - /** - * @param Node\Stmt[] $siblingStmts - */ - private function hasSiblingFunctionOfSameName(Function_ $innerFunction, array $siblingStmts): bool - { - $innerFunctionName = new Name($innerFunction->name->toString()); - foreach ($siblingStmts as $siblingStmt) { - if (! $siblingStmt instanceof Function_) { - continue; - } - - if ($this->nodeNameResolver->areNamesEqual($siblingStmt, $innerFunction)) { - return true; - } - - if ($this->reflectionProvider->hasFunction($innerFunctionName, null)) { - $functionReflection = $this->reflectionProvider->getFunction($innerFunctionName, null); - if ($functionReflection instanceof NativeFunctionReflection) { - return true; - } - } - } - - return false; + throw new ShouldNotHappenException(sprintf( + '"%s" rule is deprecated, as it handles a niche inner-function case that is not part of the PHP upgrade path', + self::class + )); } } diff --git a/src/Config/Level/CodeQualityLevel.php b/src/Config/Level/CodeQualityLevel.php index 17026f84675..00f30ab95a3 100644 --- a/src/Config/Level/CodeQualityLevel.php +++ b/src/Config/Level/CodeQualityLevel.php @@ -63,7 +63,6 @@ use Rector\CodeQuality\Rector\NotEqual\CommonNotEqualRector; use Rector\CodeQuality\Rector\NullsafeMethodCall\CleanupUnneededNullsafeOperatorRector; use Rector\CodeQuality\Rector\Property\FixClassCaseSensitivityVarDocblockRector; -use Rector\CodeQuality\Rector\StmtsAwareInterface\MoveInnerFunctionToTopLevelRector; use Rector\CodeQuality\Rector\Switch_\SingularSwitchToIfRector; use Rector\CodeQuality\Rector\Switch_\SwitchTrueToMatchRector; use Rector\CodeQuality\Rector\Ternary\ArrayKeyExistsTernaryThenValueToCoalescingRector; @@ -113,7 +112,6 @@ final class CodeQualityLevel ForeachToInArrayRector::class, RepeatedOrEqualToInArrayRector::class, RepeatedAndNotEqualToNotInArrayRector::class, - MoveInnerFunctionToTopLevelRector::class, InnerFunctionToPrivateMethodRector::class, SimplifyForeachToCoalescingRector::class, SimplifyFuncGetArgsCountRector::class,