Browse Source

feature: BlankLineBeforeStatementFixer - take into account comment before statement (#7166)

Kuba Werłos 1 year ago
parent
commit
9cfc224ce3

+ 6 - 4
doc/rules/whitespace/blank_line_before_statement.rst

@@ -220,11 +220,13 @@ With configuration: ``['statements' => ['yield']]``.
    --- Original
    +++ New
     <?php
-
-    if (true) {
-        $foo = $bar;
+    function getValues() {
+        yield 1;
+   +
+        yield 2;
    +
-        yield $foo;
+        // comment
+        yield 3;
     }
 
 Rule sets

+ 1 - 0
src/Fixer/ClassNotation/NoPhp4ConstructorFixer.php

@@ -106,6 +106,7 @@ class Foo
                                 ++$i;
                             }
                         }
+
                         // and continue checking the classes that might follow
                         continue;
                     }

+ 31 - 6
src/Fixer/Whitespace/BlankLineBeforeStatementFixer.php

@@ -221,10 +221,11 @@ try {
                 ),
                 new CodeSample(
                     '<?php
-
-if (true) {
-    $foo = $bar;
-    yield $foo;
+function getValues() {
+    yield 1;
+    yield 2;
+    // comment
+    yield 3;
 }
 ',
                     [
@@ -265,10 +266,11 @@ if (true) {
                 continue;
             }
 
-            $prevNonWhitespace = $tokens->getPrevNonWhitespace($index);
+            $insertBlankLineIndex = $this->getInsertBlankLineIndex($tokens, $index);
+            $prevNonWhitespace = $tokens->getPrevNonWhitespace($insertBlankLineIndex);
 
             if ($this->shouldAddBlankLine($tokens, $prevNonWhitespace)) {
-                $this->insertBlankLine($tokens, $index);
+                $this->insertBlankLine($tokens, $insertBlankLineIndex);
             }
 
             $index = $prevNonWhitespace;
@@ -293,6 +295,29 @@ if (true) {
         ]);
     }
 
+    private function getInsertBlankLineIndex(Tokens $tokens, int $index): int
+    {
+        while ($index > 0) {
+            $prevIndex = $tokens->getPrevNonWhitespace($index);
+
+            if (!$tokens[$prevIndex]->isComment()) {
+                break;
+            }
+
+            if (!$tokens[$prevIndex - 1]->isWhitespace()) {
+                break;
+            }
+
+            if (1 !== substr_count($tokens[$prevIndex - 1]->getContent(), "\n")) {
+                break;
+            }
+
+            $index = $prevIndex;
+        }
+
+        return $index;
+    }
+
     private function shouldAddBlankLine(Tokens $tokens, int $prevNonWhitespace): bool
     {
         $prevNonWhitespaceToken = $tokens[$prevNonWhitespace];

+ 1 - 0
tests/Console/Output/ErrorOutputTest.php

@@ -151,6 +151,7 @@ EOT;
     {
         rewind($output->getStream());
         $displayed = stream_get_contents($output->getStream());
+
         // normalize line breaks,
         // as we output using SF `writeln` we are not sure what line ending has been used as it is
         // based on the platform/console/terminal used

+ 3 - 0
tests/Fixer/Alias/NoMixedEchoPrintFixerTest.php

@@ -55,6 +55,7 @@ final class NoMixedEchoPrintFixerTest extends AbstractFixerTestCase
                 print("test");
                 ',
         ];
+
         // `echo` can take multiple parameters (although such usage is rare) while `print` can take only one argument,
         // @see https://php.net/manual/en/function.echo.php and @see https://php.net/manual/en/function.print.php
         yield [
@@ -177,12 +178,14 @@ final class NoMixedEchoPrintFixerTest extends AbstractFixerTestCase
                 echo("test");
                 ',
         ];
+
         // https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/1502#issuecomment-156436229
         yield [
             '<?php
                 ($some_var) ? print "true" : print "false";
                 ',
         ];
+
         // echo has no return value while print has a return value of 1 so it can be used in expressions.
         // https://www.w3schools.com/php/php_echo_print.asp
         yield [

+ 3 - 0
tests/Fixer/ControlStructure/YodaStyleFixerTest.php

@@ -255,6 +255,7 @@ if ($a = $obj instanceof A === true) {
             '<?php echo 1 === $a ? 1 : 2;',
             '<?php echo $a === 1 ? 1 : 2;',
         ];
+
         // Don't fix cases.
         yield ['<?php $a = 1 === 1;'];
 
@@ -293,6 +294,7 @@ if ($a = $obj instanceof A === true) {
         yield ['<?php return $x === 2 - 1;'];
 
         yield ['<?php return $x === 2-1;'];
+
         // https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/pull/693
         yield ['<?php return array(2) == $o;'];
 
@@ -323,6 +325,7 @@ if ($a = $obj instanceof A === true) {
         yield ['<?php $z = $n == list($a) = $b;'];
 
         yield ['<?php return $n == list($a) = $b;'];
+
         // Fix cases.
         yield 'Array destruct by ternary.' => [
             '<?php list($a) = 11 === $c ? $b : $d;',

+ 1 - 0
tests/Fixer/FunctionNotation/NoSpacesAfterFunctionNameFixerTest.php

@@ -96,6 +96,7 @@ final class NoSpacesAfterFunctionNameFixerTest extends AbstractFixerTestCase
             '<?php include (isHtml())? "1.html": "1.php";',
             '<?php include (isHtml ())? "1.html": "1.php";',
         ];
+
         // skip other language constructs
         yield [
             '<?php $a = 2 * (1 + 1);',

+ 1 - 0
tests/Fixer/Operator/TernaryToNullCoalescingFixerTest.php

@@ -87,6 +87,7 @@ final class TernaryToNullCoalescingFixerTest extends AbstractFixerTestCase
         yield ['<?php $y = isset($a) ? 2**3 : 3**2;'];
 
         yield ['<?php $x = function(){isset($a[yield from $a]) ? $a[yield from $a] : null;};'];
+
         // Fix cases.
         yield 'Common fix case (I).' => [
             '<?php $x = $a ?? null;',

+ 34 - 0
tests/Fixer/Whitespace/BlankLineBeforeStatementFixerTest.php

@@ -1142,8 +1142,10 @@ function foo() {
 yield $e;#
 
 yield $f;
+
     /* @var int $g */
     yield $g;
+
 /* @var int $h */
 yield $i;
 
@@ -1216,6 +1218,38 @@ function foo() {
     yield $a;
 }',
             ],
+            [
+                '<?php function foo() {
+                    // yield 1
+                    yield 1;
+
+                    // yield 2
+                    yield 2;
+                }',
+                '<?php function foo() {
+                    // yield 1
+                    yield 1;
+                    // yield 2
+                    yield 2;
+                }',
+            ],
+            [
+                '<?php function foo() {
+                    yield 1;
+
+                    // yield 2
+                    // or maybe yield 3
+                    // better compromise
+                    yield 2.5;
+                }',
+                '<?php function foo() {
+                    yield 1;
+                    // yield 2
+                    // or maybe yield 3
+                    // better compromise
+                    yield 2.5;
+                }',
+            ],
         ];
     }
 

+ 2 - 0
tests/Tokenizer/TokensTest.php

@@ -400,6 +400,7 @@ PHP;
         yield [false, 'Hello<?php echo "World!"; ?>'];
 
         yield [false, '<?php echo "Hello"; ?> World!'];
+
         // short open tag
         yield [(bool) \ini_get('short_open_tag'), "<?\n"];
 
@@ -418,6 +419,7 @@ PHP;
         yield [false, "<?php\n?><?\n"];
 
         yield [false, "<?=' '\n?><?\n"];
+
         // short open tag echo
         yield [true, "<?=' ';\n"];