diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/binary_op.php.inc b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/binary_op.php.inc similarity index 100% rename from rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/binary_op.php.inc rename to rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/binary_op.php.inc index cdf5141bfa4..49ce128a63c 100644 --- a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/binary_op.php.inc +++ b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/binary_op.php.inc @@ -64,7 +64,7 @@ function wrapToPreventPhpStanCallingMethods () { foo(); foo(); - foo2(); foo3(); + foo2(); } ?> diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/cast.php.inc b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/cast.php.inc similarity index 100% rename from rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/cast.php.inc rename to rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/cast.php.inc diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/class_constant_fetch.php.inc b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/class_constant_fetch.php.inc similarity index 59% rename from rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/class_constant_fetch.php.inc rename to rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/class_constant_fetch.php.inc index ab267e944bb..42b76d2aac6 100644 --- a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/class_constant_fetch.php.inc +++ b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/class_constant_fetch.php.inc @@ -1,6 +1,6 @@ diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/scalar.php.inc b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/scalar.php.inc similarity index 100% rename from rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/scalar.php.inc rename to rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/scalar.php.inc diff --git a/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/static_property_fetch.php.inc b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/static_property_fetch.php.inc new file mode 100644 index 00000000000..c1ab9f96e65 --- /dev/null +++ b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/static_property_fetch.php.inc @@ -0,0 +1,15 @@ + diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/unairy.php.inc b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/unairy.php.inc similarity index 63% rename from rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/unairy.php.inc rename to rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/unairy.php.inc index ce294f7cfcf..0ed212865a3 100644 --- a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/unairy.php.inc +++ b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/Fixture/unairy.php.inc @@ -1,6 +1,6 @@ diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/FixtureRemovedComments/property_fetch.php.inc b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/FixtureRemovedComments/property_fetch.php.inc similarity index 52% rename from rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/FixtureRemovedComments/property_fetch.php.inc rename to rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/FixtureRemovedComments/property_fetch.php.inc index 2ee32638804..270d7c4de9d 100644 --- a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/FixtureRemovedComments/property_fetch.php.inc +++ b/rules-tests/DeadCode/Rector/Expression/RemoveDeadStmtRector/FixtureRemovedComments/property_fetch.php.inc @@ -18,23 +18,3 @@ function wrapToPreventPhpStanCallingMethods () ${methodCall1()}->{methodCall2()}; } ?> ------ -prop = 1; - - //comment - methodCall(); - - //comment - methodCall(); - - //comment - methodCall1(); - methodCall2(); -} -?> diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/allow_any_type.php.inc b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/allow_any_type.php.inc new file mode 100644 index 00000000000..addcf8cdd51 --- /dev/null +++ b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/allow_any_type.php.inc @@ -0,0 +1,31 @@ + +----- + diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/allow_equal.php.inc b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/allow_equal.php.inc new file mode 100644 index 00000000000..4c80d441029 --- /dev/null +++ b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/allow_equal.php.inc @@ -0,0 +1,31 @@ + +----- + diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/any_expr_compare.php.inc b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/any_expr_compare.php.inc new file mode 100644 index 00000000000..0483501edb8 --- /dev/null +++ b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/any_expr_compare.php.inc @@ -0,0 +1,31 @@ + +----- + diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/skip_different_return.php.inc b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/skip_different_return.php.inc new file mode 100644 index 00000000000..c9c02faae87 --- /dev/null +++ b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/skip_different_return.php.inc @@ -0,0 +1,15 @@ +isMissing(100)) { + return $this->isMissing(100); + } + + return $result; + } + + private function isMissing(int $int): int + { + return mt_rand(0, 1) * $int; + } +} diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/some_class.php.inc b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/some_class.php.inc new file mode 100644 index 00000000000..671f2b07361 --- /dev/null +++ b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/Fixture/some_class.php.inc @@ -0,0 +1,31 @@ + +----- + diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/RemoveConditionExactReturnRectorTest.php b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/RemoveConditionExactReturnRectorTest.php new file mode 100644 index 00000000000..53f37383059 --- /dev/null +++ b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/RemoveConditionExactReturnRectorTest.php @@ -0,0 +1,28 @@ +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/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/config/configured_rule.php b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/config/configured_rule.php new file mode 100644 index 00000000000..38fa889998d --- /dev/null +++ b/rules-tests/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector/config/configured_rule.php @@ -0,0 +1,9 @@ +withRules([RemoveConditionExactReturnRector::class]); diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/empty.php.inc b/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/empty.php.inc deleted file mode 100644 index 2a09b9b296b..00000000000 --- a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/empty.php.inc +++ /dev/null @@ -1,20 +0,0 @@ - ------ - diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/static_property_fetch.php.inc b/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/static_property_fetch.php.inc deleted file mode 100644 index d18db941a02..00000000000 --- a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/Fixture/static_property_fetch.php.inc +++ /dev/null @@ -1,31 +0,0 @@ - ------ - diff --git a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/FixtureRemovedComments/comment_unwrap_keep.php.inc b/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/FixtureRemovedComments/comment_unwrap_keep.php.inc deleted file mode 100644 index 1b5a15d4c11..00000000000 --- a/rules-tests/DeadCode/Rector/Stmt/RemoveDeadStmtRector/FixtureRemovedComments/comment_unwrap_keep.php.inc +++ /dev/null @@ -1,23 +0,0 @@ - ------ - diff --git a/rules/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector.php b/rules/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector.php new file mode 100644 index 00000000000..6e1dece3316 --- /dev/null +++ b/rules/DeadCode/Rector/Stmt/RemoveConditionExactReturnRector.php @@ -0,0 +1,151 @@ +> + */ + public function getNodeTypes(): array + { + return [StmtsAwareInterface::class]; + } + + /** + * @param StmtsAwareInterface $node + */ + public function refactor(Node $node): ?Node + { + if ($node->stmts === null) { + return null; + } + + foreach ($node->stmts as $key => $stmt) { + if (! $stmt instanceof If_) { + continue; + } + + $soleIfReturn = $this->matchSoleIfReturn($stmt); + if (! $soleIfReturn instanceof Return_) { + continue; + } + + if (! $stmt->cond instanceof Identical && ! $stmt->cond instanceof Equal) { + continue; + } + + $identicalOrEqual = $stmt->cond; + // skip obvious complexity + if ($identicalOrEqual->right instanceof MethodCall) { + continue; + } + + if ($identicalOrEqual->right instanceof StaticCall) { + continue; + } + + if (! $this->nodeComparator->areNodesEqual($identicalOrEqual->right, $soleIfReturn->expr)) { + continue; + } + + $comparedVariable = $identicalOrEqual->left; + + // next if must be return of the same var + $nextStmt = $node->stmts[$key + 1] ?? null; + if (! $nextStmt instanceof Return_) { + continue; + } + + if (! $nextStmt->expr instanceof Expr) { + continue; + } + + if (! $this->nodeComparator->areNodesEqual($nextStmt->expr, $comparedVariable)) { + continue; + } + + // remove next if + unset($node->stmts[$key + 1]); + + // replace if with return + $node->stmts[$key] = $nextStmt; + + return $node; + } + + return null; + } + + private function matchSoleIfReturn(If_ $if): ?Return_ + { + if (count($if->stmts) !== 1) { + return null; + } + + $soleIfStmt = $if->stmts[0]; + if (! $soleIfStmt instanceof Return_) { + return null; + } + + return $soleIfStmt; + } +} diff --git a/rules/DeadCode/Rector/Stmt/RemoveUnreachableStatementRector.php b/rules/DeadCode/Rector/Stmt/RemoveUnreachableStatementRector.php index 839c6234047..1ce39353c00 100644 --- a/rules/DeadCode/Rector/Stmt/RemoveUnreachableStatementRector.php +++ b/rules/DeadCode/Rector/Stmt/RemoveUnreachableStatementRector.php @@ -68,6 +68,11 @@ public function refactor(Node $node): ?Node return null; } + // at least 2 items are needed + if (count($node->stmts) < 2) { + return null; + } + $originalStmts = $node->stmts; $cleanedStmts = $this->processCleanUpUnreachableStmts($node, $node->stmts); diff --git a/src/Config/Level/DeadCodeLevel.php b/src/Config/Level/DeadCodeLevel.php index 294cd360aa0..71c5f42f0ae 100644 --- a/src/Config/Level/DeadCodeLevel.php +++ b/src/Config/Level/DeadCodeLevel.php @@ -53,6 +53,7 @@ use Rector\DeadCode\Rector\PropertyProperty\RemoveNullPropertyInitializationRector; use Rector\DeadCode\Rector\Return_\RemoveDeadConditionAboveReturnRector; use Rector\DeadCode\Rector\StaticCall\RemoveParentCallWithoutParentRector; +use Rector\DeadCode\Rector\Stmt\RemoveConditionExactReturnRector; use Rector\DeadCode\Rector\Stmt\RemoveUnreachableStatementRector; use Rector\DeadCode\Rector\Switch_\RemoveDuplicatedCaseInSwitchRector; use Rector\DeadCode\Rector\Ternary\TernaryToBooleanOrFalseToBooleanAndRector; @@ -124,6 +125,7 @@ final class DeadCodeLevel RemoveDeadCatchRector::class, RemoveDeadTryCatchRector::class, RemoveDeadIfForeachForRector::class, + RemoveConditionExactReturnRector::class, RemoveDeadStmtRector::class, UnwrapFutureCompatibleIfPhpVersionRector::class, RemoveParentCallWithoutParentRector::class, diff --git a/src/Testing/PHPUnit/AbstractLazyTestCase.php b/src/Testing/PHPUnit/AbstractLazyTestCase.php index f4236153043..3fc41dd2e3a 100644 --- a/src/Testing/PHPUnit/AbstractLazyTestCase.php +++ b/src/Testing/PHPUnit/AbstractLazyTestCase.php @@ -70,6 +70,7 @@ private function includePreloadFilesAndScoperAutoload(): void if (! class_exists(Version::class, true) || (int) Version::id() < 12) { require_once __DIR__ . '/../../../preload.php'; } + // test case in rector split package } elseif (file_exists(__DIR__ . '/../../../../../../vendor')) { require_once __DIR__ . '/../../../preload-split-package.php';