Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
MultipleEmptyLinesSniff
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 2
156
0.00% covered (danger)
0.00%
0 / 1
 register
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 process
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
132
1<?php
2/**
3 * Check multiple consecutive newlines in a file.
4 */
5
6namespace MediaWiki\Sniffs\WhiteSpace;
7
8use PHP_CodeSniffer\Files\File;
9use PHP_CodeSniffer\Sniffs\Sniff;
10
11class MultipleEmptyLinesSniff implements Sniff {
12
13    /**
14     * @inheritDoc
15     */
16    public function register(): array {
17        return [
18            // Assume most comments end with a newline
19            T_COMMENT,
20            // Assume all <?php open tags end with a newline
21            T_OPEN_TAG,
22            T_WHITESPACE,
23        ];
24    }
25
26    /**
27     * @param File $phpcsFile
28     * @param int $stackPtr The current token index.
29     * @return void|int
30     */
31    public function process( File $phpcsFile, $stackPtr ) {
32        $tokens = $phpcsFile->getTokens();
33
34        // This sniff intentionally doesn't care about whitespace at the end of the file
35        if ( !isset( $tokens[$stackPtr + 3] ) ||
36            $tokens[$stackPtr + 2]['line'] === $tokens[$stackPtr + 3]['line']
37        ) {
38            return $stackPtr + 3;
39        }
40
41        if ( $tokens[$stackPtr + 1]['line'] === $tokens[$stackPtr + 2]['line'] ) {
42            return $stackPtr + 2;
43        }
44
45        // Finally, check the assumption the current token is or ends with a newline
46        if ( $tokens[$stackPtr]['line'] === $tokens[$stackPtr + 1]['line'] ) {
47            return;
48        }
49
50        // Search for the next non-newline token
51        $next = $stackPtr + 1;
52        while ( isset( $tokens[$next + 1] ) &&
53            $tokens[$next]['code'] === T_WHITESPACE &&
54            $tokens[$next]['line'] !== $tokens[$next + 1]['line']
55        ) {
56            $next++;
57        }
58        $count = $next - $stackPtr - 1;
59
60        if ( $count > 1 &&
61            $phpcsFile->addFixableError(
62                'Multiple empty lines should not exist in a row; found %s consecutive empty lines',
63                $stackPtr + 1,
64                'MultipleEmptyLines',
65                [ $count ]
66            )
67        ) {
68            $phpcsFile->fixer->beginChangeset();
69            // Remove all newlines except the first two, i.e. keep one empty line
70            for ( $i = $stackPtr + 2; $i < $next; $i++ ) {
71                $phpcsFile->fixer->replaceToken( $i, '' );
72            }
73            $phpcsFile->fixer->endChangeset();
74        }
75
76        // Don't check the current sequence a second time
77        return $next;
78    }
79}