forked from squizlabs/PHP_CodeSniffer
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLineLengthSniff.php
More file actions
206 lines (171 loc) · 6.75 KB
/
LineLengthSniff.php
File metadata and controls
206 lines (171 loc) · 6.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<?php
/**
* Checks the length of all lines in a file.
*
* Checks all lines in the file, and throws warnings if they are over 80
* characters in length and errors if they are over 100. Both these
* figures can be changed in a ruleset.xml file.
*
* @author Greg Sherwood <gsherwood@squiz.net>
* @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
* @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/
namespace PHP_CodeSniffer\Standards\Generic\Sniffs\Files;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
class LineLengthSniff implements Sniff
{
/**
* The limit that the length of a line should not exceed.
*
* @var integer
*/
public $lineLimit = 80;
/**
* The limit that the length of a line must not exceed.
*
* Set to zero (0) to disable.
*
* @var integer
*/
public $absoluteLineLimit = 100;
/**
* Whether or not to ignore trailing comments.
*
* This has the effect of also ignoring all lines
* that only contain comments.
*
* @var boolean
*/
public $ignoreComments = false;
/**
* Returns an array of tokens this test wants to listen for.
*
* @return array
*/
public function register()
{
return [T_OPEN_TAG];
}//end register()
/**
* Processes this test, when one of its tokens is encountered.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token in
* the stack passed in $tokens.
*
* @return int
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
for ($i = 1; $i < $phpcsFile->numTokens; $i++) {
if ($tokens[$i]['column'] === 1) {
$this->checkLineLength($phpcsFile, $tokens, $i);
}
}
$this->checkLineLength($phpcsFile, $tokens, $i);
// Ignore the rest of the file.
return ($phpcsFile->numTokens + 1);
}//end process()
/**
* Checks if a line is too long.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param array $tokens The token stack.
* @param int $stackPtr The first token on the next line.
*
* @return void
*/
protected function checkLineLength($phpcsFile, $tokens, $stackPtr)
{
// The passed token is the first on the line.
$stackPtr--;
if ($tokens[$stackPtr]['column'] === 1
&& $tokens[$stackPtr]['length'] === 0
) {
// Blank line.
return;
}
if ($tokens[$stackPtr]['column'] !== 1
&& $tokens[$stackPtr]['content'] === $phpcsFile->eolChar
) {
$stackPtr--;
}
$onlyComment = false;
if (isset(Tokens::$commentTokens[$tokens[$stackPtr]['code']]) === true) {
$prevNonWhiteSpace = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
if ($tokens[$stackPtr]['line'] !== $tokens[$prevNonWhiteSpace]['line']) {
$onlyComment = true;
}
}
if ($onlyComment === true
&& isset(Tokens::$phpcsCommentTokens[$tokens[$stackPtr]['code']]) === true
) {
// Ignore PHPCS annotation comments that are on a line by themselves.
return;
}
$lineLength = ($tokens[$stackPtr]['column'] + $tokens[$stackPtr]['length'] - 1);
if ($this->ignoreComments === true
&& isset(Tokens::$commentTokens[$tokens[$stackPtr]['code']]) === true
) {
// Trailing comments are being ignored in line length calculations.
if ($onlyComment === true) {
// The comment is the only thing on the line, so no need to check length.
return;
}
$lineLength -= $tokens[$stackPtr]['length'];
}
// Record metrics for common line length groupings.
if ($lineLength <= 80) {
$phpcsFile->recordMetric($stackPtr, 'Line length', '80 or less');
} else if ($lineLength <= 120) {
$phpcsFile->recordMetric($stackPtr, 'Line length', '81-120');
} else if ($lineLength <= 150) {
$phpcsFile->recordMetric($stackPtr, 'Line length', '121-150');
} else {
$phpcsFile->recordMetric($stackPtr, 'Line length', '151 or more');
}
if ($onlyComment === true) {
// If this is a long comment, check if it can be broken up onto multiple lines.
// Some comments contain unbreakable strings like URLs and so it makes sense
// to ignore the line length in these cases if the URL would be longer than the max
// line length once you indent it to the correct level.
if ($lineLength > $this->lineLimit) {
$content = $tokens[$stackPtr]['content'];
$oldLength = (function_exists('mb_strlen') === true) ? mb_strlen($content, 'UTF-8') : strlen($content);
$newLength = (function_exists('mb_strlen') === true) ? mb_strlen(ltrim($content, "/#\t "), 'UTF-8') : strlen(ltrim($content, "/#\t "));
$indent = (($tokens[$stackPtr]['column'] - 1) + ($oldLength - $newLength));
$nonBreakingLength = $tokens[$stackPtr]['length'];
$space = mb_strrpos($tokens[$stackPtr]['content'], ' ', 0, 'UTF-8');
if ($space === false && function_exists('mb_strrpos') === false) {
$space = strrpos($tokens[$stackPtr]['content'], ' ');
}
if ($space !== false) {
$nonBreakingLength -= ($space + 1);
}
if (($nonBreakingLength + $indent) > $this->lineLimit) {
return;
}
}
}//end if
if ($this->absoluteLineLimit > 0
&& $lineLength > $this->absoluteLineLimit
) {
$data = [
$this->absoluteLineLimit,
$lineLength,
];
$error = 'Line exceeds maximum limit of %s characters; contains %s characters';
$phpcsFile->addError($error, $stackPtr, 'MaxExceeded', $data);
} else if ($lineLength > $this->lineLimit) {
$data = [
$this->lineLimit,
$lineLength,
];
$warning = 'Line exceeds %s characters; contains %s characters';
$phpcsFile->addWarning($warning, $stackPtr, 'TooLong', $data);
}
}//end checkLineLength()
}//end class