Skip to content

Commit

Permalink
feat: StatementIndentationFixer - introduce stick_comment_to_next_con…
Browse files Browse the repository at this point in the history
…tinuous_control_statement config (PHP-CS-Fixer#7624)
  • Loading branch information
keradus authored and danog committed Feb 2, 2024
1 parent 2fa8986 commit f94173e
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 43 deletions.
4 changes: 4 additions & 0 deletions doc/ruleSets/Symfony.rst
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ Rules

- `standardize_increment <./../rules/operator/standardize_increment.rst>`_
- `standardize_not_equals <./../rules/operator/standardize_not_equals.rst>`_
- `statement_indentation <./../rules/whitespace/statement_indentation.rst>`_ with config:

``['stick_comment_to_next_continuous_control_statement' => true]``

- `switch_continue_to_break <./../rules/control_structure/switch_continue_to_break.rst>`_
- `trailing_comma_in_multiline <./../rules/control_structure/trailing_comma_in_multiline.rst>`_
- `trim_array_spaces <./../rules/array_notation/trim_array_spaces.rst>`_
Expand Down
71 changes: 69 additions & 2 deletions doc/rules/whitespace/statement_indentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,26 @@ Rule ``statement_indentation``

Each statement must be indented.

Configuration
-------------

``stick_comment_to_next_continuous_control_statement``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Last comment of code block counts as comment for next block.

Allowed types: ``bool``

Default value: ``false``

Examples
--------

Example #1
~~~~~~~~~~

*Default* configuration.

.. code-block:: diff
--- Original
Expand All @@ -24,6 +38,53 @@ Example #1
+ echo "bar";
}
Example #2
~~~~~~~~~~

With configuration: ``['stick_comment_to_next_continuous_control_statement' => false]``.

.. code-block:: diff
--- Original
+++ New
<?php
- // foo
+// foo
if ($foo) {
echo "foo";
- // this is treated as comment of `if` block, as `stick_comment_to_next_continuous_control_statement` is disabled
+ // this is treated as comment of `if` block, as `stick_comment_to_next_continuous_control_statement` is disabled
} else {
$aaa = 1;
}
Example #3
~~~~~~~~~~

With configuration: ``['stick_comment_to_next_continuous_control_statement' => true]``.

.. code-block:: diff
--- Original
+++ New
<?php
- // foo
+// foo
if ($foo) {
echo "foo";
- // this is treated as comment of `elseif(1)` block, as `stick_comment_to_next_continuous_control_statement` is enabled
+// this is treated as comment of `elseif(1)` block, as `stick_comment_to_next_continuous_control_statement` is enabled
} elseif(1) {
echo "bar";
} elseif(2) {
- // this is treated as comment of `elseif(2)` block, as the only content of that block
+ // this is treated as comment of `elseif(2)` block, as the only content of that block
} elseif(3) {
$aaa = 1;
- // this is treated as comment of `elseif(3)` block, as it is a comment in the final block
+ // this is treated as comment of `elseif(3)` block, as it is a comment in the final block
}
Rule sets
---------

Expand All @@ -35,8 +96,14 @@ The rule is part of the following rule sets:
- `@PER-CS2.0 <./../../ruleSets/PER-CS2.0.rst>`_
- `@PSR2 <./../../ruleSets/PSR2.rst>`_
- `@PSR12 <./../../ruleSets/PSR12.rst>`_
- `@PhpCsFixer <./../../ruleSets/PhpCsFixer.rst>`_
- `@Symfony <./../../ruleSets/Symfony.rst>`_
- `@PhpCsFixer <./../../ruleSets/PhpCsFixer.rst>`_ with config:

``['stick_comment_to_next_continuous_control_statement' => true]``

- `@Symfony <./../../ruleSets/Symfony.rst>`_ with config:

``['stick_comment_to_next_continuous_control_statement' => true]``


Source class
------------
Expand Down
2 changes: 1 addition & 1 deletion phpstan.dist.neon
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ parameters:
-
message: '#^Method PhpCsFixer\\Tests\\.+::provide.+Cases\(\) return type has no value type specified in iterable type iterable\.$#'
path: tests
count: 1039
count: 1035

-
message: '#Call to static method .+ with .+ will always evaluate to true.$#'
Expand Down
47 changes: 45 additions & 2 deletions src/Fixer/Whitespace/StatementIndentationFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@
namespace PhpCsFixer\Fixer\Whitespace;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\Fixer\ConfigurableFixerInterface;
use PhpCsFixer\Fixer\Indentation;
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface;
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
Expand All @@ -26,7 +30,7 @@
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

final class StatementIndentationFixer extends AbstractFixer implements WhitespacesAwareFixerInterface
final class StatementIndentationFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface
{
use Indentation;

Expand Down Expand Up @@ -56,6 +60,35 @@ public function getDefinition(): FixerDefinitionInterface
}
'
),
new CodeSample(
'<?php
// foo
if ($foo) {
echo "foo";
// this is treated as comment of `if` block, as `stick_comment_to_next_continuous_control_statement` is disabled
} else {
$aaa = 1;
}
',
['stick_comment_to_next_continuous_control_statement' => false]
),
new CodeSample(
'<?php
// foo
if ($foo) {
echo "foo";
// this is treated as comment of `elseif(1)` block, as `stick_comment_to_next_continuous_control_statement` is enabled
} elseif(1) {
echo "bar";
} elseif(2) {
// this is treated as comment of `elseif(2)` block, as the only content of that block
} elseif(3) {
$aaa = 1;
// this is treated as comment of `elseif(3)` block, as it is a comment in the final block
}
',
['stick_comment_to_next_continuous_control_statement' => true]
),
]
);
}
Expand All @@ -76,6 +109,16 @@ public function isCandidate(Tokens $tokens): bool
return true;
}

protected function createConfigurationDefinition(): FixerConfigurationResolverInterface
{
return new FixerConfigurationResolver([
(new FixerOptionBuilder('stick_comment_to_next_continuous_control_statement', 'Last comment of code block counts as comment for next block.'))
->setAllowedTypes(['bool'])
->setDefault(false)
->getOption(),
]);
}

protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
{
$this->alternativeSyntaxAnalyzer = new AlternativeSyntaxAnalyzer();
Expand Down Expand Up @@ -383,7 +426,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
$nextNextIndex = $tokens->getNextMeaningfulToken($nextIndex);

if (null !== $nextNextIndex && $tokens[$nextNextIndex]->isGivenKind([T_ELSE, T_ELSEIF])) {
$indent = false;
$indent = true !== $this->configuration['stick_comment_to_next_continuous_control_statement'];
} else {
$indent = true;
}
Expand Down
3 changes: 3 additions & 0 deletions src/RuleSet/Sets/SymfonySet.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ public function getRules(): array
],
'standardize_increment' => true,
'standardize_not_equals' => true,
'statement_indentation' => [
'stick_comment_to_next_continuous_control_statement' => true,
],
'switch_continue_to_break' => true,
'trailing_comma_in_multiline' => true,
'trim_array_spaces' => true,
Expand Down
39 changes: 8 additions & 31 deletions tests/Fixer/Basic/BracesFixerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ public static function provideFixMissingBracesAndIndentCases(): iterable
$a = "a";
} elseif (3) {
$b = "b";
// comment
// comment
} else {
$c = "c";
}
Expand Down Expand Up @@ -1898,7 +1898,7 @@ public function __construct(
$a = "a";
} elseif (3) {
$b = "b";
// comment
// comment
} else {
$c = "c";
}
Expand All @@ -1908,40 +1908,17 @@ public function __construct(
self::CONFIGURATION_OOP_POSITION_SAME_LINE,
];

yield 'multiline comment in block' => [
'<?php
if (1) {
$b = "a";
// multiline comment line 1
// multiline comment line 2
} elseif (2) {
// empty
} else {
$c = "b";
}',
'<?php
if (1) {
$b = "a";
// multiline comment line 1
// multiline comment line 2
} elseif (2) {
// empty
} else {
$c = "b";
}',
];

yield [
'<?php
if (1) {
if (2) {
$a = "a";
} elseif (3) {
$b = "b";
// comment line 1
// comment line 2
// comment line 3
// comment line 4
// comment line 1
// comment line 2
// comment line 3
// comment line 4
} else {
$c = "c";
}
Expand Down Expand Up @@ -3245,10 +3222,10 @@ public static function provideFixCommentBeforeBraceCases(): iterable
// 2.5+ API
if (isNewApi()) {
echo "new API";
// 2.4- API
// 2.4- API
} elseif (isOldApi()) {
echo "old API";
// other API
// 2.4- API
} else {
echo "unknown API";
// sth
Expand Down

0 comments on commit f94173e

Please sign in to comment.