diff --git a/CHANGELOG.md b/CHANGELOG.md index eff292d..474ac21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Added - Enh #12: Implemented `Ely\align_multiline_parameters` fixer. +- Enh #13: Implemented `Ely\multiline_if_statement_braces` fixer. - Enabled `Ely\align_multiline_parameters` for Ely.by codestyle in `['types' => false, 'defaults' => false]` mode. +- Enabled `Ely\multiline_if_statement_braces` for Ely.by codestyle in `['keep_on_own_line' => true]` mode. - Enabled [`PhpCsFixerCustomFixers/multiline_promoted_properties`](https://github.com/kubawerlos/php-cs-fixer-custom-fixers#multilinepromotedpropertiesfixer) fixer for Ely.by codestyle in 2+ parameters mode. diff --git a/README.md b/README.md index de27c59..04f1f49 100644 --- a/README.md +++ b/README.md @@ -286,6 +286,28 @@ and `do-while`. $c = 'next statement'; ``` +### `Ely/multiline_if_statement_braces` + +Ensures that multiline if statement body curly brace placed on the right line. + +```diff +--- Original ++++ New +@@ @@ + false], + ), + ], + ); + } + + public function isCandidate(Tokens $tokens): bool { + return $tokens->isTokenKindFound(T_IF); + } + + protected function createConfigurationDefinition(): FixerConfigurationResolverInterface { + return new FixerConfigurationResolver([ + (new FixerOptionBuilder(self::C_KEEP_ON_OWN_LINE, 'adjusts the position of condition closing brace.')) + ->setAllowedTypes(['bool']) + ->setDefault(true) + ->getOption(), + ]); + } + + protected function applyFix(SplFileInfo $file, Tokens $tokens): void { + $keepOnOwnLine = $this->configuration[self::C_KEEP_ON_OWN_LINE]; + $tokensAnalyzer = new TokensAnalyzer($tokens); + $eol = $this->whitespacesConfig->getLineEnding(); + foreach ($tokens as $i => $token) { + if (!$token->isGivenKind(T_IF)) { + continue; + } + + $openBraceIndex = $tokens->getNextTokenOfKind($i, ['(']); + if (!$tokensAnalyzer->isBlockMultiline($tokens, $openBraceIndex)) { + continue; + } + + $closingBraceIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openBraceIndex); + /** @var \PhpCsFixer\Tokenizer\Token $statementBeforeClosingBrace */ + $statementBeforeClosingBrace = $tokens[$closingBraceIndex - 1]; + if ($keepOnOwnLine) { + if (!$statementBeforeClosingBrace->isWhitespace() + || !str_contains($statementBeforeClosingBrace->getContent(), $eol) + ) { + $indent = WhitespacesAnalyzer::detectIndent($tokens, $i); + $tokens->ensureWhitespaceAtIndex($closingBraceIndex, 0, $eol . $indent); + } + } else { + $tokens->removeLeadingWhitespace($closingBraceIndex); + } + } + } + +} diff --git a/src/Rules.php b/src/Rules.php index 42b8630..7d93f57 100644 --- a/src/Rules.php +++ b/src/Rules.php @@ -228,6 +228,7 @@ class Rules { ], 'Ely/blank_line_before_return' => true, 'Ely/line_break_after_statements' => true, + 'Ely/multiline_if_statement_braces' => true, 'Ely/remove_class_name_method_usages' => true, ], $overwrittenRules); } diff --git a/tests/Fixer/Whitespace/MultilineIfStatementBracesFixerTest.php b/tests/Fixer/Whitespace/MultilineIfStatementBracesFixerTest.php new file mode 100644 index 0000000..dd2434b --- /dev/null +++ b/tests/Fixer/Whitespace/MultilineIfStatementBracesFixerTest.php @@ -0,0 +1,68 @@ +doTest($expected, $input); + } + + public function provideFixCases(): iterable { + yield 'simple' => [ + ' [ + 'fixer->configure([ + MultilineIfStatementBracesFixer::C_KEEP_ON_OWN_LINE => false, + ]); + $this->doTest($expected, $input); + } + + public function provideInvertedFixCases(): iterable { + foreach ($this->provideFixCases() as $name => $case) { + yield $name => [$case[1], $case[0]]; + } + } + + protected function createFixer(): AbstractFixer { + return new MultilineIfStatementBracesFixer(); + } + +}