Browse Source

feat: `NoEmptyPhpdocFixer` - do not leave empty line after removing PHPDoc (#7820)

Kuba Werłos 1 year ago
parent
commit
e383c84c63

+ 25 - 3
src/Fixer/Phpdoc/NoEmptyPhpdocFixer.php

@@ -19,6 +19,7 @@ use PhpCsFixer\FixerDefinition\CodeSample;
 use PhpCsFixer\FixerDefinition\FixerDefinition;
 use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
 use PhpCsFixer\Preg;
+use PhpCsFixer\Tokenizer\Token;
 use PhpCsFixer\Tokenizer\Tokens;
 
 final class NoEmptyPhpdocFixer extends AbstractFixer
@@ -34,7 +35,7 @@ final class NoEmptyPhpdocFixer extends AbstractFixer
     /**
      * {@inheritdoc}
      *
-     * Must run before NoExtraBlankLinesFixer, NoTrailingWhitespaceFixer, NoWhitespaceInBlankLineFixer, PhpdocAlignFixer.
+     * Must run before NoExtraBlankLinesFixer, NoTrailingWhitespaceFixer, PhpdocAlignFixer.
      * Must run after AlignMultilineCommentFixer, CommentToPhpdocFixer, GeneralPhpdocAnnotationRemoveFixer, NoSuperfluousPhpdocTagsFixer, PhpUnitNoExpectationAnnotationFixer, PhpUnitTestAnnotationFixer, PhpdocAddMissingParamAnnotationFixer, PhpdocIndentFixer, PhpdocNoAccessFixer, PhpdocNoEmptyReturnFixer, PhpdocNoPackageFixer, PhpdocNoUselessInheritdocFixer, PhpdocReadonlyClassCommentToKeywordFixer, PhpdocScalarFixer, PhpdocToCommentFixer, PhpdocTypesFixer.
      */
     public function getPriority(): int
@@ -54,9 +55,30 @@ final class NoEmptyPhpdocFixer extends AbstractFixer
                 continue;
             }
 
-            if (Preg::match('#^/\*\*[\s\*]*\*/$#', $token->getContent())) {
-                $tokens->clearTokenAndMergeSurroundingWhitespace($index);
+            if (!Preg::match('#^/\*\*[\s\*]*\*/$#', $token->getContent())) {
+                continue;
             }
+
+            if (
+                $tokens[$index - 1]->isGivenKind([T_OPEN_TAG, T_WHITESPACE])
+                && substr_count($tokens[$index - 1]->getContent(), "\n") > 0
+                && $tokens[$index + 1]->isGivenKind(T_WHITESPACE)
+                && Preg::match('/^\R/', $tokens[$index + 1]->getContent())
+            ) {
+                $tokens[$index - 1] = new Token([
+                    $tokens[$index - 1]->getId(),
+                    Preg::replace('/\h*$/', '', $tokens[$index - 1]->getContent()),
+                ]);
+
+                $newContent = Preg::replace('/^\R/', '', $tokens[$index + 1]->getContent());
+                if ('' === $newContent) {
+                    $tokens->clearAt($index + 1);
+                } else {
+                    $tokens[$index + 1] = new Token([T_WHITESPACE, $newContent]);
+                }
+            }
+
+            $tokens->clearTokenAndMergeSurroundingWhitespace($index);
         }
     }
 }

+ 1 - 1
src/Fixer/Whitespace/NoWhitespaceInBlankLineFixer.php

@@ -38,7 +38,7 @@ final class NoWhitespaceInBlankLineFixer extends AbstractFixer implements Whites
     /**
      * {@inheritdoc}
      *
-     * Must run after AssignNullCoalescingToCoalesceEqualFixer, CombineConsecutiveIssetsFixer, CombineConsecutiveUnsetsFixer, FunctionToConstantFixer, NoEmptyCommentFixer, NoEmptyPhpdocFixer, NoEmptyStatementFixer, NoUselessElseFixer, NoUselessReturnFixer, YieldFromArrayToYieldsFixer.
+     * Must run after AssignNullCoalescingToCoalesceEqualFixer, CombineConsecutiveIssetsFixer, CombineConsecutiveUnsetsFixer, FunctionToConstantFixer, NoEmptyCommentFixer, NoEmptyStatementFixer, NoUselessElseFixer, NoUselessReturnFixer, YieldFromArrayToYieldsFixer.
      */
     public function getPriority(): int
     {

+ 0 - 1
tests/AutoReview/FixerFactoryTest.php

@@ -586,7 +586,6 @@ final class FixerFactoryTest extends TestCase
             'no_empty_phpdoc' => [
                 'no_extra_blank_lines',
                 'no_trailing_whitespace',
-                'no_whitespace_in_blank_line',
             ],
             'no_empty_statement' => [
                 'braces',

+ 140 - 1
tests/Fixer/Phpdoc/NoEmptyPhpdocFixerTest.php

@@ -33,7 +33,7 @@ final class NoEmptyPhpdocFixerTest extends AbstractFixerTestCase
 
     public static function provideFixCases(): iterable
     {
-        yield [
+        yield 'multiple PHPdocs' => [
             '<?php
                     /** a */
 
@@ -73,5 +73,144 @@ final class NoEmptyPhpdocFixerTest extends AbstractFixerTestCase
                      /** *test* */
                 ',
         ];
+
+        yield 'PHPDoc on its own line' => [
+            <<<'PHP'
+                <?php
+                echo $a;
+                echo $b;
+                PHP,
+            <<<'PHP'
+                <?php
+                echo $a;
+                /** */
+                echo $b;
+                PHP,
+        ];
+
+        yield 'PHPDoc on its own line with empty line before' => [
+            <<<'PHP'
+                <?php
+                function f() {
+                    echo $a;
+
+                    echo $b;
+                }
+                PHP,
+            <<<'PHP'
+                <?php
+                function f() {
+                    echo $a;
+
+                    /** */
+                    echo $b;
+                }
+                PHP,
+        ];
+
+        yield 'PHPDoc on its own line with empty line after' => [
+            <<<'PHP'
+                <?php
+                echo $a;
+
+                echo $b;
+                PHP,
+            <<<'PHP'
+                <?php
+                echo $a;
+                /** */
+
+                echo $b;
+                PHP,
+        ];
+
+        yield 'PHPDoc on its own line with empty line before and after' => [
+            <<<'PHP'
+                <?php
+                echo $a;
+
+
+                echo $b;
+                PHP,
+            <<<'PHP'
+                <?php
+                echo $a;
+
+                /** */
+
+                echo $b;
+                PHP,
+        ];
+
+        yield 'PHPDoc with empty line before and content after' => [
+            <<<'PHP'
+                <?php
+                function f() {
+                    echo $a;
+                    echo $b;
+                }
+                PHP,
+            <<<'PHP'
+                <?php
+                function f() {
+                    echo $a;
+                    /** */echo $b;
+                }
+                PHP,
+        ];
+
+        yield 'PHPDoc with content before and empty line after' => [
+            <<<'PHP'
+                <?php
+                function f() {
+                    echo $a;
+                    echo $b;
+                }
+                PHP,
+            <<<'PHP'
+                <?php
+                function f() {
+                    echo $a;/** */
+                    echo $b;
+                }
+                PHP,
+        ];
+
+        yield 'PHPDoc after open tag - the same line' => [
+            '<?php '.'
+                foo();
+                ',
+            '<?php /** */
+                foo();
+                ',
+        ];
+
+        yield 'PHPDoc after open tag - next line' => [
+            <<<'PHP'
+                <?php
+                foo();
+                PHP,
+            <<<'PHP'
+                <?php
+                /** */
+                foo();
+                PHP,
+        ];
+
+        yield 'PHPDoc after open tag - next next next line' => [
+            <<<'PHP'
+                <?php
+
+
+                foo();
+                PHP,
+            <<<'PHP'
+                <?php
+
+
+                /** */
+                foo();
+                PHP,
+        ];
     }
 }

+ 0 - 1
tests/Fixtures/Integration/misc/phpdocs.test-out.php

@@ -1,7 +1,6 @@
 <?php
 
 class Foo {
-    
     public $bar;
 
     /**

+ 0 - 1
tests/Fixtures/Integration/priority/general_phpdoc_annotation_remove,no_empty_phpdoc.test

@@ -4,7 +4,6 @@ Integration of fixers: general_phpdoc_annotation_remove,no_empty_phpdoc.
 {"general_phpdoc_annotation_remove": {"annotations": ["test", "return", "param"] }, "no_empty_phpdoc": true}
 --EXPECT--
 <?php
-
 function hello($name)
 {
     return 'hello'. $name;

+ 0 - 13
tests/Fixtures/Integration/priority/no_empty_phpdoc,no_whitespace_in_blank_line.test

@@ -1,13 +0,0 @@
---TEST--
-Integration of fixers: no_empty_phpdoc,no_whitespace_in_blank_line.
---RULESET--
-{"no_empty_phpdoc": true, "no_whitespace_in_blank_line": true}
---EXPECT--
-<?php
-echo 1;
-
-
---INPUT--
-<?php
-echo 1;
-    /** */

+ 0 - 1
tests/Fixtures/Integration/priority/no_superfluous_phpdoc_tags,no_empty_phpdoc.test

@@ -6,7 +6,6 @@ Integration of fixers: no_superfluous_phpdoc_tags,no_empty_phpdoc.
 <?php
 
 class Foo {
-    
     public function doFoo(Bar $bar) {}
 }
 

+ 0 - 1
tests/Fixtures/Integration/priority/php_unit_no_expectation_annotation,no_empty_phpdoc.test

@@ -6,7 +6,6 @@ Integration of fixers: php_unit_no_expectation_annotation,no_empty_phpdoc.
 <?php
 class FooTest extends \PHPUnit_Framework_TestCase
 {
-    
     public function testFoo()
     {
         $this->setExpectedException(\FooException::class, 'foo', 123);

+ 0 - 1
tests/Fixtures/Integration/priority/php_unit_test_annotation,no_empty_phpdoc.test

@@ -6,7 +6,6 @@ Integration of fixers: php_unit_test_annotation,no_empty_phpdoc.
 <?php
 class Test extends TestCase
 {
-    
     public function testFooBar() {}
 }
 

Some files were not shown because too many files changed in this diff