• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PHPCSStandards / PHP_CodeSniffer / 15253296250

26 May 2025 11:55AM UTC coverage: 78.632% (+0.3%) from 78.375%
15253296250

Pull #1105

github

web-flow
Merge d9441d98f into caf806050
Pull Request #1105: Skip tests when 'git' command is not available

19665 of 25009 relevant lines covered (78.63%)

88.67 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.59
/src/Standards/Squiz/Sniffs/WhiteSpace/SuperfluousWhitespaceSniff.php
1
<?php
2
/**
3
 * Checks for unneeded whitespace.
4
 *
5
 * Checks that no whitespace precedes the first content of the file, exists
6
 * after the last content of the file, resides after content on any line, or
7
 * are two empty lines in functions.
8
 *
9
 * @author    Greg Sherwood <gsherwood@squiz.net>
10
 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
11
 * @license   https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
 */
13

14
namespace PHP_CodeSniffer\Standards\Squiz\Sniffs\WhiteSpace;
15

16
use PHP_CodeSniffer\Files\File;
17
use PHP_CodeSniffer\Sniffs\Sniff;
18

19
class SuperfluousWhitespaceSniff implements Sniff
20
{
21

22
    /**
23
     * If TRUE, whitespace rules are not checked for blank lines.
24
     *
25
     * Blank lines are those that contain only whitespace.
26
     *
27
     * @var boolean
28
     */
29
    public $ignoreBlankLines = false;
30

31

32
    /**
33
     * Returns an array of tokens this test wants to listen for.
34
     *
35
     * @return array<int|string>
36
     */
37
    public function register()
3✔
38
    {
39
        return [
2✔
40
            T_OPEN_TAG,
3✔
41
            T_OPEN_TAG_WITH_ECHO,
3✔
42
            T_CLOSE_TAG,
3✔
43
            T_WHITESPACE,
3✔
44
            T_COMMENT,
3✔
45
            T_DOC_COMMENT_WHITESPACE,
3✔
46
            T_CLOSURE,
3✔
47
        ];
2✔
48

49
    }//end register()
50

51

52
    /**
53
     * Processes this sniff, when one of its tokens is encountered.
54
     *
55
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
56
     * @param int                         $stackPtr  The position of the current token in the
57
     *                                               stack passed in $tokens.
58
     *
59
     * @return void
60
     */
61
    public function process(File $phpcsFile, $stackPtr)
3✔
62
    {
63
        $tokens = $phpcsFile->getTokens();
3✔
64

65
        if ($tokens[$stackPtr]['code'] === T_OPEN_TAG) {
3✔
66
            /*
67
                Check for start of file whitespace.
68
            */
69

70
            // If it's the first token, then there is no space.
71
            if ($stackPtr === 0) {
3✔
72
                return;
3✔
73
            }
74

75
            $beforeOpen = '';
3✔
76

77
            for ($i = ($stackPtr - 1); $i >= 0; $i--) {
3✔
78
                // If we find something that isn't inline html then there is something previous in the file.
79
                if ($tokens[$i]['type'] !== 'T_INLINE_HTML') {
3✔
80
                    return;
3✔
81
                }
82

83
                $beforeOpen .= $tokens[$i]['content'];
3✔
84
            }
85

86
            // If we have ended up with inline html make sure it isn't just whitespace.
87
            if (preg_match('`^[\pZ\s]+$`u', $beforeOpen) !== 1) {
3✔
88
                return;
×
89
            }
90

91
            $fix = $phpcsFile->addFixableError('Additional whitespace found at start of file', $stackPtr, 'StartFile');
3✔
92
            if ($fix === true) {
3✔
93
                $phpcsFile->fixer->beginChangeset();
3✔
94
                for ($i = 0; $i < $stackPtr; $i++) {
3✔
95
                    $phpcsFile->fixer->replaceToken($i, '');
3✔
96
                }
97

98
                $phpcsFile->fixer->endChangeset();
3✔
99
            }
100
        } else if ($tokens[$stackPtr]['code'] === T_CLOSE_TAG) {
3✔
101
            /*
102
                Check for end of file whitespace.
103
            */
104

105
            if (isset($tokens[($stackPtr + 1)]) === false) {
3✔
106
                // The close PHP token is the last in the file.
107
                return;
3✔
108
            }
109

110
            $afterClose = '';
3✔
111

112
            for ($i = ($stackPtr + 1); $i < $phpcsFile->numTokens; $i++) {
3✔
113
                // If we find something that isn't inline HTML then there
114
                // is more to the file.
115
                if ($tokens[$i]['type'] !== 'T_INLINE_HTML') {
3✔
116
                    return;
3✔
117
                }
118

119
                $afterClose .= $tokens[$i]['content'];
3✔
120
            }
121

122
            // If we have ended up with inline html make sure it isn't just whitespace.
123
            if (preg_match('`^[\pZ\s]+$`u', $afterClose) !== 1) {
3✔
124
                return;
×
125
            }
126

127
            $fix = $phpcsFile->addFixableError('Additional whitespace found at end of file', $stackPtr, 'EndFile');
3✔
128
            if ($fix === true) {
3✔
129
                $phpcsFile->fixer->beginChangeset();
3✔
130
                for ($i = ($stackPtr + 1); $i < $phpcsFile->numTokens; $i++) {
3✔
131
                    $phpcsFile->fixer->replaceToken($i, '');
3✔
132
                }
133

134
                $phpcsFile->fixer->endChangeset();
3✔
135
            }
136
        } else {
137
            /*
138
                Check for end of line whitespace.
139
            */
140

141
            // Ignore whitespace that is not at the end of a line.
142
            if (isset($tokens[($stackPtr + 1)]['line']) === true
3✔
143
                && $tokens[($stackPtr + 1)]['line'] === $tokens[$stackPtr]['line']
3✔
144
            ) {
145
                return;
3✔
146
            }
147

148
            // Ignore blank lines if required.
149
            if ($this->ignoreBlankLines === true
3✔
150
                && $tokens[$stackPtr]['code'] === T_WHITESPACE
3✔
151
                && $tokens[($stackPtr - 1)]['line'] !== $tokens[$stackPtr]['line']
3✔
152
            ) {
153
                return;
3✔
154
            }
155

156
            $tokenContent = rtrim($tokens[$stackPtr]['content'], $phpcsFile->eolChar);
3✔
157
            if (empty($tokenContent) === false) {
3✔
158
                if ($tokenContent !== rtrim($tokenContent)) {
3✔
159
                    $fix = $phpcsFile->addFixableError('Whitespace found at end of line', $stackPtr, 'EndLine');
3✔
160
                    if ($fix === true) {
3✔
161
                        $phpcsFile->fixer->replaceToken($stackPtr, rtrim($tokenContent).$phpcsFile->eolChar);
3✔
162
                    }
163
                }
164
            } else if ($tokens[($stackPtr - 1)]['content'] !== rtrim($tokens[($stackPtr - 1)]['content'])
3✔
165
                && $tokens[($stackPtr - 1)]['line'] === $tokens[$stackPtr]['line']
3✔
166
            ) {
167
                $fix = $phpcsFile->addFixableError('Whitespace found at end of line', ($stackPtr - 1), 'EndLine');
3✔
168
                if ($fix === true) {
3✔
169
                    $phpcsFile->fixer->replaceToken(($stackPtr - 1), rtrim($tokens[($stackPtr - 1)]['content']));
3✔
170
                }
171
            }
172

173
            /*
174
                Check for multiple blank lines in a function.
175
            */
176

177
            if (($phpcsFile->hasCondition($stackPtr, [T_FUNCTION, T_CLOSURE]) === true)
3✔
178
                && $tokens[($stackPtr - 1)]['line'] < $tokens[$stackPtr]['line']
3✔
179
                && $tokens[($stackPtr - 2)]['line'] === $tokens[($stackPtr - 1)]['line']
3✔
180
            ) {
181
                // Properties and functions in nested classes have their own rules for spacing.
182
                $conditions   = $tokens[$stackPtr]['conditions'];
3✔
183
                $deepestScope = end($conditions);
3✔
184
                if ($deepestScope === T_ANON_CLASS) {
3✔
185
                    return;
3✔
186
                }
187

188
                // This is an empty line and the line before this one is not
189
                // empty, so this could be the start of a multiple empty
190
                // line block.
191
                $next  = $phpcsFile->findNext(T_WHITESPACE, $stackPtr, null, true);
3✔
192
                $lines = ($tokens[$next]['line'] - $tokens[$stackPtr]['line']);
3✔
193
                if ($lines > 1) {
3✔
194
                    $error = 'Functions must not contain multiple empty lines in a row; found %s empty lines';
3✔
195
                    $fix   = $phpcsFile->addFixableError($error, $stackPtr, 'EmptyLines', [$lines]);
3✔
196
                    if ($fix === true) {
3✔
197
                        $phpcsFile->fixer->beginChangeset();
3✔
198
                        $i = $stackPtr;
3✔
199
                        while ($tokens[$i]['line'] !== $tokens[$next]['line']) {
3✔
200
                            $phpcsFile->fixer->replaceToken($i, '');
3✔
201
                            $i++;
3✔
202
                        }
203

204
                        $phpcsFile->fixer->addNewlineBefore($i);
3✔
205
                        $phpcsFile->fixer->endChangeset();
3✔
206
                    }
207
                }
208
            }//end if
209
        }//end if
210

211
    }//end process()
1✔
212

213

214
}//end class
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc