diff --git a/rules-tests/CodingStyle/Rector/If_/AlternativeIfToBracketRector/AlternativeIfToBracketRectorTest.php b/rules-tests/CodingStyle/Rector/If_/AlternativeIfToBracketRector/AlternativeIfToBracketRectorTest.php new file mode 100644 index 00000000000..83b23940831 --- /dev/null +++ b/rules-tests/CodingStyle/Rector/If_/AlternativeIfToBracketRector/AlternativeIfToBracketRectorTest.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/CodingStyle/Rector/If_/AlternativeIfToBracketRector/Fixture/if_elseif_else.php.inc b/rules-tests/CodingStyle/Rector/If_/AlternativeIfToBracketRector/Fixture/if_elseif_else.php.inc new file mode 100644 index 00000000000..dcdff5f1af0 --- /dev/null +++ b/rules-tests/CodingStyle/Rector/If_/AlternativeIfToBracketRector/Fixture/if_elseif_else.php.inc @@ -0,0 +1,33 @@ +withRules([AlternativeIfToBracketRector::class]); diff --git a/rules/CodingStyle/Rector/If_/AlternativeIfToBracketRector.php b/rules/CodingStyle/Rector/If_/AlternativeIfToBracketRector.php new file mode 100644 index 00000000000..cef4ce579ae --- /dev/null +++ b/rules/CodingStyle/Rector/If_/AlternativeIfToBracketRector.php @@ -0,0 +1,102 @@ +> + */ + public function getNodeTypes(): array + { + return [If_::class]; + } + + /** + * @param If_ $node + */ + public function refactor(Node $node): ?Node + { + if (! $this->isAlternativeSyntax($node)) { + return null; + } + + // force reprint of the whole if/elseif/else chain with bracket syntax + $node->setAttribute(AttributeKey::ORIGINAL_NODE, null); + + foreach ($node->elseifs as $elseif) { + $elseif->setAttribute(AttributeKey::ORIGINAL_NODE, null); + } + + if ($node->else instanceof Node) { + $node->else->setAttribute(AttributeKey::ORIGINAL_NODE, null); + } + + return $node; + } + + private function isAlternativeSyntax(If_ $if): bool + { + $startTokenPos = $if->cond->getEndTokenPos(); + if ($startTokenPos < 0) { + return false; + } + + $oldTokens = $this->getFile() + ->getOldTokens(); + + for ($i = $startTokenPos + 1; isset($oldTokens[$i]); ++$i) { + $token = $oldTokens[$i]; + if (! $token instanceof Token) { + continue; + } + + if ($token->text === ':') { + return true; + } + + if ($token->text === '{') { + return false; + } + } + + return false; + } +} diff --git a/src/Config/Level/CodeQualityLevel.php b/src/Config/Level/CodeQualityLevel.php index ddeb933c002..dc6c447f637 100644 --- a/src/Config/Level/CodeQualityLevel.php +++ b/src/Config/Level/CodeQualityLevel.php @@ -83,6 +83,7 @@ use Rector\CodeQuality\Rector\Ternary\TernaryEmptyArrayArrayDimFetchToCoalesceRector; use Rector\CodeQuality\Rector\Ternary\TernaryImplodeToImplodeRector; use Rector\CodeQuality\Rector\Ternary\UnnecessaryTernaryExpressionRector; +use Rector\CodingStyle\Rector\If_\AlternativeIfToBracketRector; use Rector\Contract\Rector\RectorInterface; use Rector\Php52\Rector\Property\VarToPublicPropertyRector; use Rector\Php71\Rector\FuncCall\RemoveExtraParametersRector; @@ -186,6 +187,7 @@ final class CodeQualityLevel DisallowedEmptyRuleFixerRector::class, LocallyCalledStaticMethodToNonStaticRector::class, NumberCompareToMaxFuncCallRector::class, + AlternativeIfToBracketRector::class, CompleteMissingIfElseBracketRector::class, RemoveUselessIsObjectCheckRector::class, ConvertStaticToSelfRector::class,