From d603b00818cfabc8aa1699b1154145e68bdb60a0 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Tue, 23 May 2023 15:32:59 +0200 Subject: [PATCH] Remove PARENT_NODE from RemoveUnusedVariableAssignRector (#3935) --- phpstan.neon | 12 +- .../Fixture/on_new_instance.php.inc | 41 ---- .../Fixture/shadowed_local_variable.php.inc | 24 +- .../skip_next_include_another_file.php.inc | 16 +- .../skip_try_catch_on_new_instance.php.inc | 18 ++ .../skip_used_as_variable_variable.php.inc | 16 -- .../Fixture/skip_variable_name.php.inc | 11 + ...ble_variable_not_has_next_variable.php.inc | 26 -- .../RemoveUnusedVariableAssignRector.php | 226 ++++++++---------- .../CurlyToSquareBracketArrayStringRector.php | 24 +- .../FollowedByCurlyBracketAnalyzer.php | 24 -- src/Kernel/RectorKernel.php | 2 +- src/PhpParser/Comparing/ConditionSearcher.php | 109 --------- src/PhpParser/Node/BetterNodeFinder.php | 2 + .../Fixture/fixture.php.inc | 69 ------ .../RemoveUnusedVariableElseToTernaryTest.php | 28 --- .../config/configured_rule.php | 13 - 17 files changed, 154 insertions(+), 507 deletions(-) delete mode 100644 rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/on_new_instance.php.inc create mode 100644 rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/skip_try_catch_on_new_instance.php.inc delete mode 100644 rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/skip_used_as_variable_variable.php.inc create mode 100644 rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/skip_variable_name.php.inc delete mode 100644 rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/variable_variable_not_has_next_variable.php.inc delete mode 100644 rules/Php74/Tokenizer/FollowedByCurlyBracketAnalyzer.php delete mode 100644 src/PhpParser/Comparing/ConditionSearcher.php delete mode 100644 tests/Issues/RemoveUnusedVariableElseToTernary/Fixture/fixture.php.inc delete mode 100644 tests/Issues/RemoveUnusedVariableElseToTernary/RemoveUnusedVariableElseToTernaryTest.php delete mode 100644 tests/Issues/RemoveUnusedVariableElseToTernary/config/configured_rule.php diff --git a/phpstan.neon b/phpstan.neon index 5706374c0c2..75b9dac5b83 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -344,11 +344,6 @@ parameters: message: '#The path "/\.\./\.\./stubs\-rector" was not found#' path: src/Autoloading/BootstrapFilesIncluder.php # 54 - - - message: '#PHPDoc tag @param for parameter \$node with type array\|null is incompatible with native type PhpParser\\Node#' - paths: - - rules/CodeQuality/Rector/FuncCall/ChangeArrayPushToArrayAssignRector.php - - message: '#Access to an undefined property PhpParser\\Node\:\:\$expr#' paths: @@ -743,8 +738,8 @@ parameters: path: src/Kernel/RectorKernel.php # expression generics - - '#PHPDoc tag @return contains generic type PhpParser\\Node\\Stmt\\Expression but class PhpParser\\Node\\Stmt\\Expression is not generic#' - - '#PHPDoc tag @var for variable \$previousStmt contains generic type PhpParser\\Node\\Stmt\\Expression but class PhpParser\\Node\\Stmt\\Expression is not generic#' + - '#PhpParser\\Node\\Stmt\\Expression is not generic#' + - '#Parameter \#3 \$assign of method Rector\\CodeQuality\\Rector\\FunctionLike\\SimplifyUselessVariableRector\:\:processSimplifyUselessVariable\(\) expects PhpParser\\Node\\Expr\\Assign\|PhpParser\\Node\\Expr\\AssignOp, PhpParser\\Node\\Expr given#' - '#Anonymous variable in a (.*?)->stmts\[(.*?)]\->\.\.\.\(\)` method call can lead to false dead methods\. Make sure the variable type is known#' @@ -754,3 +749,6 @@ parameters: # WIP - '#Fetching deprecated class constant PARENT_NODE#' - '#Return type \(int\|PhpParser\\Node\\Expr\\FuncCall\|PhpParser\\Node\\Expr\\Ternary\|null\) of method Rector\\Php71\\Rector\\FuncCall\\CountOnNullRector\:\:refactorWithScope\(\) should be covariant with return type \(1\|2\|3\|4\|array\|PhpParser\\Node\|null\) of method Rector\\Core\\Contract\\Rector\\ScopeAwarePhpRectorInterface\:\:refactorWithScope\(\)#' + + # resolve before 1.0 + - '#Call to deprecated method resolveNextNode\(\) of class Rector\\Core\\PhpParser\\Node\\BetterNodeFinder\:#' diff --git a/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/on_new_instance.php.inc b/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/on_new_instance.php.inc deleted file mode 100644 index 790f8d2a5b2..00000000000 --- a/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/on_new_instance.php.inc +++ /dev/null @@ -1,41 +0,0 @@ - ------ - diff --git a/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/shadowed_local_variable.php.inc b/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/shadowed_local_variable.php.inc index 65ca1cae9b3..3b181fe187c 100644 --- a/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/shadowed_local_variable.php.inc +++ b/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/shadowed_local_variable.php.inc @@ -2,7 +2,8 @@ namespace Rector\Tests\DeadCode\Rector\Assign\RemoveUnusedVariableAssignRector\Fixture; -class ShadowedLocalVariable { +final class SkipShadowedLocalVariable +{ public function run(array $params) { $toDate = null; @@ -17,24 +18,3 @@ class ShadowedLocalVariable { } } -?> ------ -setTimestamp(strtotime('now - 3 month')); - } - - return $toDate; - } -} - -?> diff --git a/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/skip_next_include_another_file.php.inc b/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/skip_next_include_another_file.php.inc index de7fc1f337e..b65cc5a0810 100644 --- a/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/skip_next_include_another_file.php.inc +++ b/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/skip_next_include_another_file.php.inc @@ -2,7 +2,7 @@ namespace Rector\Tests\DeadCode\Rector\Assign\RemoveUnusedVariableAssignRector\Fixture; -class SkipNextIncludeAnotherFile +final class SkipNextIncludeAnotherFile { public function run() { @@ -11,17 +11,5 @@ class SkipNextIncludeAnotherFile if (rand(0, 1)) { include 'test.php'; } - - if (rand(0, 1)) { - include_once 'test.php'; - } - - if (rand(0, 1)) { - require 'test.php'; - } - - if (rand(0, 1)) { - require_once 'test.php'; - } } -} \ No newline at end of file +} diff --git a/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/skip_try_catch_on_new_instance.php.inc b/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/skip_try_catch_on_new_instance.php.inc new file mode 100644 index 00000000000..4a81ecc707e --- /dev/null +++ b/rules-tests/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector/Fixture/skip_try_catch_on_new_instance.php.inc @@ -0,0 +1,18 @@ + ------ - diff --git a/rules/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector.php b/rules/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector.php index 6f44b408853..f5324f669be 100644 --- a/rules/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector.php +++ b/rules/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector.php @@ -7,27 +7,18 @@ use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\Node\Expr\Assign; -use PhpParser\Node\Expr\CallLike; use PhpParser\Node\Expr\Cast; use PhpParser\Node\Expr\FuncCall; -use PhpParser\Node\Expr\MethodCall; -use PhpParser\Node\Expr\New_; -use PhpParser\Node\Expr\NullsafeMethodCall; -use PhpParser\Node\Expr\StaticCall; +use PhpParser\Node\Expr\Include_; use PhpParser\Node\Expr\Variable; -use PhpParser\Node\FunctionLike; +use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Expression; -use PhpParser\Node\Stmt\If_; use PHPStan\Analyser\Scope; use Rector\Core\Php\ReservedKeywordAnalyzer; -use Rector\Core\PhpParser\Comparing\ConditionSearcher; use Rector\Core\Rector\AbstractScopeAwareRector; -use Rector\DeadCode\NodeAnalyzer\ExprUsedInNextNodeAnalyzer; -use Rector\DeadCode\NodeAnalyzer\UsedVariableNameAnalyzer; use Rector\DeadCode\SideEffect\SideEffectNodeDetector; use Rector\NodeTypeResolver\Node\AttributeKey; -use Rector\Php74\Tokenizer\FollowedByCurlyBracketAnalyzer; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -38,11 +29,7 @@ final class RemoveUnusedVariableAssignRector extends AbstractScopeAwareRector { public function __construct( private readonly ReservedKeywordAnalyzer $reservedKeywordAnalyzer, - private readonly ConditionSearcher $conditionSearcher, - private readonly UsedVariableNameAnalyzer $usedVariableNameAnalyzer, private readonly SideEffectNodeDetector $sideEffectNodeDetector, - private readonly ExprUsedInNextNodeAnalyzer $exprUsedInNextNodeAnalyzer, - private readonly FollowedByCurlyBracketAnalyzer $followedByCurlyBracketAnalyzer ) { } @@ -77,39 +64,61 @@ public function run() */ public function getNodeTypes(): array { - return [Assign::class]; + return [ClassMethod::class]; } /** - * @param Assign $node + * @param ClassMethod $node */ - public function refactorWithScope(Node $node, Scope $scope): ?Node + public function refactorWithScope(Node $node, Scope $scope): ?ClassMethod { - if ($this->shouldSkip($node)) { + $classMethodStmts = $node->stmts; + if ($classMethodStmts === null) { return null; } - $variable = $node->var; - if (! $variable instanceof Variable) { + // we cannot be sure here + if ($this->containsCompactFuncCall($node)) { return null; } - $variableName = $this->getName($variable); - if ($variableName !== null && $this->reservedKeywordAnalyzer->isNativeVariable($variableName)) { + if ($this->containsFileIncludes($node)) { return null; } - // variable is used - if ($this->isUsed($node, $variable, $scope)) { - return $this->refactorUsedVariable($node, $scope); + $assignedVariableNamesByStmtPosition = $this->resolvedAssignedVariablesByStmtPosition($classMethodStmts); + + $hasChanged = false; + + foreach ($assignedVariableNamesByStmtPosition as $stmtPosition => $variableName) { + if ($this->isVariableUsedInFollowingStmts($node, $stmtPosition, $variableName)) { + continue; + } + + /** @var Expression $currentStmt */ + $currentStmt = $classMethodStmts[$stmtPosition]; + + /** @var Assign $assign */ + $assign = $currentStmt->expr; + + /** @var Scope $assignScope */ + $assignScope = $assign->getAttribute(AttributeKey::SCOPE); + + if ($this->hasCallLikeInAssignExpr($assign, $assignScope)) { + // clean safely + $cleanAssignedExpr = $this->cleanCastedExpr($assign->expr); + $node->stmts[$stmtPosition] = new Expression($cleanAssignedExpr); + } else { + unset($node->stmts[$stmtPosition]); + } + + $hasChanged = true; } - if ($this->hasCallLikeInAssignExpr($node->expr, $scope)) { - // keep the expr, can have side effect - return $this->cleanCastedExpr($node->expr); + if ($hasChanged) { + return $node; } - $this->removeNode($node); return null; } @@ -119,8 +128,7 @@ private function cleanCastedExpr(Expr $expr): Expr return $expr; } - $castedExpr = $expr->expr; - return $this->cleanCastedExpr($castedExpr); + return $this->cleanCastedExpr($expr->expr); } private function hasCallLikeInAssignExpr(Expr $expr, Scope $scope): bool @@ -131,74 +139,28 @@ private function hasCallLikeInAssignExpr(Expr $expr, Scope $scope): bool ); } - private function shouldSkip(Assign $assign): bool - { - $classMethod = $this->betterNodeFinder->findParentType($assign, ClassMethod::class); - if (! $classMethod instanceof FunctionLike) { - return true; - } - - $variable = $assign->var; - if (! $variable instanceof Variable) { - return true; - } - - $parentNode = $assign->getAttribute(AttributeKey::PARENT_NODE); - if (! $parentNode instanceof Expression) { - return true; - } - - $originalNode = $parentNode->getAttribute(AttributeKey::ORIGINAL_NODE); - if (! $originalNode instanceof Node) { - return true; - } - - if (! $variable->name instanceof Variable) { - return $this->followedByCurlyBracketAnalyzer->isFollowed($this->file, $variable); - } - - return (bool) $this->betterNodeFinder->findFirstNext( - $assign, - static fn (Node $node): bool => $node instanceof Variable - ); - } - - private function isUsed(Assign $assign, Variable $variable, Scope $scope): bool - { - $isUsedPrev = $scope->hasVariableType((string) $this->getName($variable)) - ->yes(); - - if ($isUsedPrev) { - return true; - } - - if ($this->exprUsedInNextNodeAnalyzer->isUsed($variable)) { - return true; - } - - /** @var FuncCall|MethodCall|New_|NullsafeMethodCall|StaticCall $expr */ - $expr = $assign->expr; - if (! $this->sideEffectNodeDetector->detectCallExpr($expr, $scope)) { + private function isVariableUsedInFollowingStmts( + ClassMethod $classMethod, + int $assignStmtPosition, + string $variableName + ): bool { + if ($classMethod->stmts === null) { return false; } - return $this->isUsedInAssignExpr($expr, $assign, $scope); - } - - private function isUsedInAssignExpr(CallLike | Expr $expr, Assign $assign, Scope $scope): bool - { - if (! $expr instanceof CallLike) { - return $this->isUsedInPreviousAssign($assign, $expr, $scope); - } - - if ($expr->isFirstClassCallable()) { - return false; - } + foreach ($classMethod->stmts as $key => $stmt) { + // do not look yet + if ($key <= $assignStmtPosition) { + continue; + } - foreach ($expr->getArgs() as $arg) { - $variable = $arg->value; + $stmtScope = $stmt->getAttribute(AttributeKey::SCOPE); + if (! $stmtScope instanceof Scope) { + continue; + } - if ($this->isUsedInPreviousAssign($assign, $variable, $scope)) { + $foundVariable = $this->betterNodeFinder->findVariableOfName($stmt, $variableName); + if ($foundVariable instanceof Variable) { return true; } } @@ -206,54 +168,58 @@ private function isUsedInAssignExpr(CallLike | Expr $expr, Assign $assign, Scope return false; } - private function isUsedInPreviousAssign(Assign $assign, Expr $expr, Scope $scope): bool + private function containsCompactFuncCall(ClassMethod|Node $node): bool { - if (! $expr instanceof Variable) { - return false; - } + $compactFuncCall = $this->betterNodeFinder->findFirst($node, function (Node $node): bool { + if (! $node instanceof FuncCall) { + return false; + } - $previousAssign = $this->betterNodeFinder->findFirstPrevious( - $assign, - fn (Node $node): bool => $node instanceof Assign && $this->usedVariableNameAnalyzer->isVariableNamed( - $node->var, - $expr - ) - ); + return $this->isName($node, 'compact'); + }); - if ($previousAssign instanceof Assign) { - return $this->isUsed($assign, $expr, $scope); - } + return $compactFuncCall instanceof FuncCall; + } - return false; + private function containsFileIncludes(ClassMethod $classMethod): bool + { + return (bool) $this->betterNodeFinder->findInstancesOf($classMethod, [Include_::class]); } - private function refactorUsedVariable(Assign $assign, Scope $scope): null|Expr + /** + * @param array $stmts + * @return array + */ + private function resolvedAssignedVariablesByStmtPosition(array $stmts): array { - $parentNode = $assign->getAttribute(AttributeKey::PARENT_NODE); - if (! $parentNode instanceof Expression) { - return null; - } + $assignedVariableNamesByStmtPosition = []; - $node = $this->betterNodeFinder->resolveNextNode($parentNode); + foreach ($stmts as $key => $stmt) { + if (! $stmt instanceof Expression) { + continue; + } - // check if next node is if - if (! $node instanceof If_) { - if ( - $assign->var instanceof Variable && - ! $scope->hasVariableType((string) $this->getName($assign->var)) - ->yes() && - ! $this->exprUsedInNextNodeAnalyzer->isUsed($assign->var)) { - return $this->cleanCastedExpr($assign->expr); + if (! $stmt->expr instanceof Assign) { + continue; } - return null; - } + $assign = $stmt->expr; + if (! $assign->var instanceof Variable) { + continue; + } + + $variableName = $this->getName($assign->var); + if (! is_string($variableName)) { + continue; + } - if ($this->conditionSearcher->hasIfAndElseForVariableRedeclaration($assign, $node)) { - $this->removeNode($assign); - return $assign; + if ($this->reservedKeywordAnalyzer->isNativeVariable($variableName)) { + continue; + } + + $assignedVariableNamesByStmtPosition[$key] = $variableName; } - return null; + return $assignedVariableNamesByStmtPosition; } } diff --git a/rules/Php74/Rector/ArrayDimFetch/CurlyToSquareBracketArrayStringRector.php b/rules/Php74/Rector/ArrayDimFetch/CurlyToSquareBracketArrayStringRector.php index c78fa4a866c..7aa0dc86d05 100644 --- a/rules/Php74/Rector/ArrayDimFetch/CurlyToSquareBracketArrayStringRector.php +++ b/rules/Php74/Rector/ArrayDimFetch/CurlyToSquareBracketArrayStringRector.php @@ -7,9 +7,9 @@ use PhpParser\Node; use PhpParser\Node\Expr\ArrayDimFetch; use Rector\Core\Rector\AbstractRector; +use Rector\Core\ValueObject\Application\File; use Rector\Core\ValueObject\PhpVersionFeature; use Rector\NodeTypeResolver\Node\AttributeKey; -use Rector\Php74\Tokenizer\FollowedByCurlyBracketAnalyzer; use Rector\VersionBonding\Contract\MinPhpVersionInterface; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -20,11 +20,6 @@ */ final class CurlyToSquareBracketArrayStringRector extends AbstractRector implements MinPhpVersionInterface { - public function __construct( - private readonly FollowedByCurlyBracketAnalyzer $followedByCurlyBracketAnalyzer - ) { - } - public function provideMinPhpVersion(): int { return PhpVersionFeature::DEPRECATE_CURLY_BRACKET_ARRAY_STRING; @@ -39,6 +34,7 @@ public function getRuleDefinition(): RuleDefinition <<<'CODE_SAMPLE' $string = 'test'; echo $string{0}; + $array = ['test']; echo $array{0}; CODE_SAMPLE @@ -46,6 +42,7 @@ public function getRuleDefinition(): RuleDefinition <<<'CODE_SAMPLE' $string = 'test'; echo $string[0]; + $array = ['test']; echo $array[0]; CODE_SAMPLE @@ -67,7 +64,7 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - if (! $this->followedByCurlyBracketAnalyzer->isFollowed($this->file, $node)) { + if (! $this->isFollowedByCurlyBracket($this->file, $node)) { return null; } @@ -75,4 +72,17 @@ public function refactor(Node $node): ?Node $node->setAttribute(AttributeKey::ORIGINAL_NODE, null); return $node; } + + private function isFollowedByCurlyBracket(File $file, ArrayDimFetch $arrayDimFetch): bool + { + $oldTokens = $file->getOldTokens(); + $endTokenPost = $arrayDimFetch->getEndTokenPos(); + + if (isset($oldTokens[$endTokenPost]) && $oldTokens[$endTokenPost] === '}') { + $startTokenPost = $arrayDimFetch->getStartTokenPos(); + return ! (isset($oldTokens[$startTokenPost][1]) && $oldTokens[$startTokenPost][1] === '${'); + } + + return false; + } } diff --git a/rules/Php74/Tokenizer/FollowedByCurlyBracketAnalyzer.php b/rules/Php74/Tokenizer/FollowedByCurlyBracketAnalyzer.php deleted file mode 100644 index 37899d5fa96..00000000000 --- a/rules/Php74/Tokenizer/FollowedByCurlyBracketAnalyzer.php +++ /dev/null @@ -1,24 +0,0 @@ -getOldTokens(); - $endTokenPost = $node->getEndTokenPos(); - - if (isset($oldTokens[$endTokenPost]) && $oldTokens[$endTokenPost] === '}') { - $startTokenPost = $node->getStartTokenPos(); - return ! (isset($oldTokens[$startTokenPost][1]) && $oldTokens[$startTokenPost][1] === '${'); - } - - return false; - } -} diff --git a/src/Kernel/RectorKernel.php b/src/Kernel/RectorKernel.php index 079de06eaaf..cb228b29879 100644 --- a/src/Kernel/RectorKernel.php +++ b/src/Kernel/RectorKernel.php @@ -17,7 +17,7 @@ final class RectorKernel /** * @var string */ - private const CACHE_KEY = 'v20'; + private const CACHE_KEY = 'v22'; private ContainerInterface|null $container = null; diff --git a/src/PhpParser/Comparing/ConditionSearcher.php b/src/PhpParser/Comparing/ConditionSearcher.php deleted file mode 100644 index a2b253c11af..00000000000 --- a/src/PhpParser/Comparing/ConditionSearcher.php +++ /dev/null @@ -1,109 +0,0 @@ -else instanceof Else_) { - return false; - } - - $ifElse = $if->else; - - /** @var Variable $varNode */ - $varNode = $assign->var; - - if (! $this->hasVariableRedeclaration($varNode, $if->stmts)) { - return false; - } - - foreach ($if->elseifs as $elseifNode) { - if (! $this->hasVariableRedeclaration($varNode, $elseifNode->stmts)) { - return false; - } - } - - $isInCond = (bool) $this->betterNodeFinder->findFirst( - $if->cond, - fn (Node $subNode): bool => $this->nodeComparator->areNodesEqual($varNode, $subNode) - ); - - if ($isInCond) { - return false; - } - - return $this->hasVariableRedeclaration($varNode, $ifElse->stmts); - } - - /** - * @param Stmt[] $stmts - */ - private function hasVariableRedeclaration(Variable $variable, array $stmts): bool - { - foreach ($stmts as $stmt) { - if ($this->hasVariableUsedInExpression($variable, $stmt)) { - return false; - } - - if ($this->hasVariableDeclaration($variable, $stmt)) { - return true; - } - } - - return false; - } - - private function hasVariableUsedInExpression(Variable $variable, Stmt $stmt): bool - { - if ($stmt instanceof Expression) { - $node = $stmt->expr instanceof Assign ? $stmt->expr->expr : $stmt->expr; - } else { - $node = $stmt; - } - - return (bool) $this->betterNodeFinder->findFirst( - $node, - fn (Node $subNode): bool => $this->nodeComparator->areNodesEqual($variable, $subNode) - ); - } - - private function hasVariableDeclaration(Variable $variable, Stmt $stmt): bool - { - if (! $stmt instanceof Expression) { - return false; - } - - if (! $stmt->expr instanceof Assign) { - return false; - } - - $assign = $stmt->expr; - - if (! $assign->var instanceof Variable) { - return false; - } - - $assignedVariable = $assign->var; - - return $variable->name === $assignedVariable->name; - } -} diff --git a/src/PhpParser/Node/BetterNodeFinder.php b/src/PhpParser/Node/BetterNodeFinder.php index 1ceee9e81d9..83e482a068d 100644 --- a/src/PhpParser/Node/BetterNodeFinder.php +++ b/src/PhpParser/Node/BetterNodeFinder.php @@ -576,6 +576,8 @@ public function resolvePreviousNode(Node $node): ?Node /** * @api * + * @deprecated Use StmtsAwareInterface instead + * * Resolve next node from any Node, eg: Expr, Identifier, Name, etc */ public function resolveNextNode(Node $node): ?Node diff --git a/tests/Issues/RemoveUnusedVariableElseToTernary/Fixture/fixture.php.inc b/tests/Issues/RemoveUnusedVariableElseToTernary/Fixture/fixture.php.inc deleted file mode 100644 index 0af48f6f894..00000000000 --- a/tests/Issues/RemoveUnusedVariableElseToTernary/Fixture/fixture.php.inc +++ /dev/null @@ -1,69 +0,0 @@ -createImage(); - - if (function_exists('imagecreatetruecolor')) { - $create = 'imagecreatetruecolor'; - $copy = 'imagecopyresampled'; - } else { - $create = 'imagecreate'; - $copy = 'imagecopyresized'; - } - $dest = $create($this->width, $this->height); - - $matte = imagecolorallocate($dest, $red, $green, $blue); - - imagefilledrectangle($dest, 0, 0, $this->width, $this->height, $matte); - imagecopy($dest, $srcImg, 0, 0, 0, 0, $this->width, $this->height); - - // Kill the file handles - imagedestroy($srcImg); - - $this->resource = $dest; - - return $this; - } - -} - -?> ------ -createImage(); - - $create = function_exists('imagecreatetruecolor') ? 'imagecreatetruecolor' : 'imagecreate'; - $dest = $create($this->width, $this->height); - - $matte = imagecolorallocate($dest, $red, $green, $blue); - - imagefilledrectangle($dest, 0, 0, $this->width, $this->height, $matte); - imagecopy($dest, $srcImg, 0, 0, 0, 0, $this->width, $this->height); - - // Kill the file handles - imagedestroy($srcImg); - - $this->resource = $dest; - - return $this; - } - -} - -?> diff --git a/tests/Issues/RemoveUnusedVariableElseToTernary/RemoveUnusedVariableElseToTernaryTest.php b/tests/Issues/RemoveUnusedVariableElseToTernary/RemoveUnusedVariableElseToTernaryTest.php deleted file mode 100644 index 2d5a5c83f36..00000000000 --- a/tests/Issues/RemoveUnusedVariableElseToTernary/RemoveUnusedVariableElseToTernaryTest.php +++ /dev/null @@ -1,28 +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/tests/Issues/RemoveUnusedVariableElseToTernary/config/configured_rule.php b/tests/Issues/RemoveUnusedVariableElseToTernary/config/configured_rule.php deleted file mode 100644 index 5ac6242b728..00000000000 --- a/tests/Issues/RemoveUnusedVariableElseToTernary/config/configured_rule.php +++ /dev/null @@ -1,13 +0,0 @@ -rules([ - RemoveUnusedVariableAssignRector::class, - SimplifyIfElseToTernaryRector::class - ]); -};