Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@17
|
3 * \Drupal\Sniffs\Files\LineLengthSniff.
|
Chris@0
|
4 *
|
Chris@0
|
5 * @category PHP
|
Chris@0
|
6 * @package PHP_CodeSniffer
|
Chris@0
|
7 * @link http://pear.php.net/package/PHP_CodeSniffer
|
Chris@0
|
8 */
|
Chris@0
|
9
|
Chris@17
|
10 namespace Drupal\Sniffs\Files;
|
Chris@17
|
11
|
Chris@17
|
12 use PHP_CodeSniffer\Files\File;
|
Chris@17
|
13 use PHP_CodeSniffer\Standards\Generic\Sniffs\Files\LineLengthSniff as GenericLineLengthSniff;
|
Chris@17
|
14 use PHP_CodeSniffer\Util\Tokens;
|
Chris@17
|
15
|
Chris@0
|
16 /**
|
Chris@0
|
17 * Checks comment lines in the file, and throws warnings if they are over 80
|
Chris@0
|
18 * characters in length.
|
Chris@0
|
19 *
|
Chris@0
|
20 * @category PHP
|
Chris@0
|
21 * @package PHP_CodeSniffer
|
Chris@0
|
22 * @link http://pear.php.net/package/PHP_CodeSniffer
|
Chris@0
|
23 */
|
Chris@17
|
24 class LineLengthSniff extends GenericLineLengthSniff
|
Chris@0
|
25 {
|
Chris@0
|
26
|
Chris@0
|
27 /**
|
Chris@0
|
28 * The limit that the length of a line should not exceed.
|
Chris@0
|
29 *
|
Chris@0
|
30 * @var int
|
Chris@0
|
31 */
|
Chris@0
|
32 public $lineLimit = 80;
|
Chris@0
|
33
|
Chris@0
|
34 /**
|
Chris@0
|
35 * The limit that the length of a line must not exceed.
|
Chris@0
|
36 * But just check the line length of comments....
|
Chris@0
|
37 *
|
Chris@0
|
38 * Set to zero (0) to disable.
|
Chris@0
|
39 *
|
Chris@0
|
40 * @var int
|
Chris@0
|
41 */
|
Chris@0
|
42 public $absoluteLineLimit = 0;
|
Chris@0
|
43
|
Chris@0
|
44
|
Chris@0
|
45 /**
|
Chris@0
|
46 * Checks if a line is too long.
|
Chris@0
|
47 *
|
Chris@17
|
48 * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
|
Chris@17
|
49 * @param array $tokens The token stack.
|
Chris@17
|
50 * @param int $stackPtr The first token on the next line.
|
Chris@0
|
51 *
|
Chris@0
|
52 * @return void
|
Chris@0
|
53 */
|
Chris@17
|
54 protected function checkLineLength($phpcsFile, $tokens, $stackPtr)
|
Chris@0
|
55 {
|
Chris@17
|
56 if (isset(Tokens::$commentTokens[$tokens[($stackPtr - 1)]['code']]) === true) {
|
Chris@0
|
57 $doc_comment_tag = $phpcsFile->findFirstOnLine(T_DOC_COMMENT_TAG, ($stackPtr - 1));
|
Chris@0
|
58 if ($doc_comment_tag !== false) {
|
Chris@0
|
59 // Allow doc comment tags such as long @param tags to exceed the 80
|
Chris@0
|
60 // character limit.
|
Chris@0
|
61 return;
|
Chris@0
|
62 }
|
Chris@0
|
63
|
Chris@0
|
64 if ($tokens[($stackPtr - 1)]['code'] === T_COMMENT
|
Chris@0
|
65 // Allow @link and @see documentation to exceed the 80 character
|
Chris@0
|
66 // limit.
|
Chris@0
|
67 && (preg_match('/^[[:space:]]*\/\/ @.+/', $tokens[($stackPtr - 1)]['content']) === 1
|
Chris@0
|
68 // Allow anything that does not contain spaces (like URLs) to be
|
Chris@0
|
69 // longer.
|
Chris@0
|
70 || strpos(trim($tokens[($stackPtr - 1)]['content'], "/ \n"), ' ') === false)
|
Chris@0
|
71 ) {
|
Chris@0
|
72 return;
|
Chris@0
|
73 }
|
Chris@0
|
74
|
Chris@0
|
75 // Code examples between @code and @endcode are allowed to exceed 80
|
Chris@0
|
76 // characters.
|
Chris@0
|
77 if (isset($tokens[$stackPtr]) === true && $tokens[$stackPtr]['code'] === T_DOC_COMMENT_WHITESPACE) {
|
Chris@0
|
78 $tag = $phpcsFile->findPrevious(array(T_DOC_COMMENT_TAG, T_DOC_COMMENT_OPEN_TAG), ($stackPtr - 1));
|
Chris@0
|
79 if ($tokens[$tag]['content'] === '@code') {
|
Chris@0
|
80 return;
|
Chris@0
|
81 }
|
Chris@0
|
82 }
|
Chris@0
|
83
|
Chris@0
|
84 // Drupal 8 annotations can have long translatable descriptions and we
|
Chris@0
|
85 // allow them to exceed 80 characters.
|
Chris@0
|
86 if ($tokens[($stackPtr - 2)]['code'] === T_DOC_COMMENT_STRING
|
Chris@0
|
87 && (strpos($tokens[($stackPtr - 2)]['content'], '@Translation(') !== false
|
Chris@0
|
88 // Also allow anything without whitespace (like URLs) to exceed 80
|
Chris@0
|
89 // characters.
|
Chris@0
|
90 || strpos($tokens[($stackPtr - 2)]['content'], ' ') === false
|
Chris@0
|
91 // Allow long "Contains ..." comments in @file doc blocks.
|
Chris@0
|
92 || preg_match('/^Contains [a-zA-Z_\\\\.]+$/', $tokens[($stackPtr - 2)]['content']) === 1
|
Chris@0
|
93 // Allow long paths or namespaces in annotations such as
|
Chris@0
|
94 // "list_builder" = "Drupal\rules\Entity\Controller\RulesReactionListBuilder"
|
Chris@0
|
95 // cardinality = \Drupal\webform\WebformHandlerInterface::CARDINALITY_UNLIMITED.
|
Chris@0
|
96 || preg_match('#= ("|\')?\S+[\\\\/]\S+("|\')?,*$#', $tokens[($stackPtr - 2)]['content']) === 1)
|
Chris@0
|
97 // Allow @link tags in lists.
|
Chris@0
|
98 || strpos($tokens[($stackPtr - 2)]['content'], '- @link') !== false
|
Chris@0
|
99 // Allow hook implementation line to exceed 80 characters.
|
Chris@0
|
100 || preg_match('/^Implements hook_[a-zA-Z0-9_]+\(\)/', $tokens[($stackPtr - 2)]['content']) === 1
|
Chris@0
|
101 ) {
|
Chris@0
|
102 return;
|
Chris@0
|
103 }
|
Chris@0
|
104
|
Chris@0
|
105 parent::checkLineLength($phpcsFile, $tokens, $stackPtr);
|
Chris@0
|
106 }//end if
|
Chris@0
|
107
|
Chris@0
|
108 }//end checkLineLength()
|
Chris@0
|
109
|
Chris@0
|
110
|
Chris@0
|
111 /**
|
Chris@0
|
112 * Returns the length of a defined line.
|
Chris@0
|
113 *
|
Chris@17
|
114 * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
|
Chris@17
|
115 * @param int $currentLine The current line.
|
Chris@0
|
116 *
|
Chris@0
|
117 * @return int
|
Chris@0
|
118 */
|
Chris@17
|
119 public function getLineLength(File $phpcsFile, $currentLine)
|
Chris@0
|
120 {
|
Chris@0
|
121 $tokens = $phpcsFile->getTokens();
|
Chris@0
|
122
|
Chris@0
|
123 $tokenCount = 0;
|
Chris@0
|
124 $currentLineContent = '';
|
Chris@0
|
125
|
Chris@0
|
126 $trim = (strlen($phpcsFile->eolChar) * -1);
|
Chris@0
|
127 for (; $tokenCount < $phpcsFile->numTokens; $tokenCount++) {
|
Chris@0
|
128 if ($tokens[$tokenCount]['line'] === $currentLine) {
|
Chris@0
|
129 $currentLineContent .= $tokens[$tokenCount]['content'];
|
Chris@0
|
130 }
|
Chris@0
|
131 }
|
Chris@0
|
132
|
Chris@0
|
133 return strlen($currentLineContent);
|
Chris@0
|
134
|
Chris@0
|
135 }//end getLineLength()
|
Chris@0
|
136
|
Chris@0
|
137
|
Chris@0
|
138 }//end class
|