InlineCommentSniff::_checkCommentStyle()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
nc 4
nop 2
dl 0
loc 20
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * CodeIgniter_Sniffs_Commenting_InlineCommentSniff.
4
 *
5
 * PHP version 5
6
 *
7
 * @category  PHP
8
 * @package   PHP_CodeSniffer
9
 * @author    Thomas Ernest <[email protected]>
10
 * @copyright 2011 Thomas Ernest
11
 * @license   http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License
12
 * @link      http://pear.php.net/package/PHP_CodeSniffer
13
 */
14
15
/**
16
 * CodeIgniter_Sniffs_Commenting_InlineCommentSniff.
17
 *
18
 * Ensure the use of single line comments within code (i.e //)
19
 * and blank lines between large comment blocks and code.
20
 *
21
 * @category  PHP
22
 * @package   PHP_CodeSniffer
23
 * @author    Thomas Ernest <[email protected]>
24
 * @copyright 2011 Thomas Ernest
25
 * @license   http://thomas.ernest.fr/developement/php_cs/licence GNU General Public License
26
 * @link      http://pear.php.net/package/PHP_CodeSniffer
27
 */
28
namespace CodeIgniter\Sniffs\Commenting;
29
30
use PHP_CodeSniffer\Sniffs\Sniff;
31
use PHP_CodeSniffer\Files\File;
32
33
class InlineCommentSniff implements Sniff
34
{
35
    /**
36
     * @var int Limit defining long comments.
37
     * Long comments count $longCommentLimit or more lines.
38
     */
39
    public $longCommentLimit = 5;
40
41
    /**
42
     * Returns an array of tokens this test wants to listen for.
43
     *
44
     * @return array
45
     */
46
    public function register()
47
    {
48
        return array(
49
            T_COMMENT
50
        );
51
    }//end register()
52
53
    /**
54
     * Processes this test, when one of its tokens is encountered.
55
     *
56
     * @param File $phpcsFile The current file being scanned.
57
     * @param int                  $stackPtr  The position of the current token
58
     *                                        in the stack passed in $tokens.
59
     *
60
     * @return void
61
     */
62
    public function process(File $phpcsFile, $stackPtr)
63
    {
64
        $tokens = $phpcsFile->getTokens();
65
66
        // keep testing only if it's about the first comment of the block
67
        $previousCommentPtr = $phpcsFile->findPrevious($tokens[$stackPtr]['code'], $stackPtr - 1);
68
        if ($tokens[$previousCommentPtr]['line'] !== $tokens[$stackPtr]['line'] - 1) {
69
            if (TRUE !== $this->_checkCommentStyle($phpcsFile, $stackPtr)) {
70
                return;
71
            }
72
73
            $commentLines = $this->_getCommentBlock($phpcsFile, $stackPtr);
74
75
            if (count($commentLines) >= $this->longCommentLimit) {
76
                $this->_checkBlankLinesAroundLongComment($phpcsFile, $commentLines);
77
            }
78
        }
79
    }//end process()
80
81
82
    /**
83
     * Add error to $phpcsFile, if comment pointed by $stackPtr doesn't start
84
     * with '//'.
85
     *
86
     * @param File $phpcsFile The current file being scanned.
87
     * @param int                  $stackPtr  The position of the current token
88
     *                                        that has to be a comment.
89
     *
90
     * @return bool TRUE if the content of the token pointed by $stackPtr starts
91
     *              with //, FALSE if an error was added to $phpcsFile.
92
     */
93
    private function _checkCommentStyle(File $phpcsFile, $stackPtr)
94
    {
95
        $tokens = $phpcsFile->getTokens();
96
        if ($tokens[$stackPtr]['content']{0} === '#') {
97
            $error  = 'Perl-style comments are not allowed; use "// Comment" or DocBlock comments instead';
98
            $phpcsFile->addError($error, $stackPtr, 'WrongStyle');
99
            return FALSE;
100
        } else if (substr($tokens[$stackPtr]['content'], 0, 2) === '/*'
101
            || $tokens[$stackPtr]['content']{0} === '*'
102
        ) {
103
            $error  = 'Multi lines comments are not allowed; use "// Comment" DocBlock comments instead';
104
            $phpcsFile->addError($error, $stackPtr, 'WrongStyle');
105
            return FALSE;
106
        } else if (substr($tokens[$stackPtr]['content'], 0, 2) !== '//') {
107
            $error  = 'Use single line or DocBlock comments within code';
108
            $phpcsFile->addError($error, $stackPtr, 'WrongStyle');
109
            return FALSE;
110
        }
111
        return TRUE;
112
    }//_checkCommentStyle()
113
114
115
    /**
116
     * Gather into an array all comment lines to which $stackPtr belongs.
117
     *
118
     * @param File $phpcsFile The current file being scanned.
119
     * @param int                  $stackPtr  Pointer to the first comment line.
120
     *
121
     * @return type array Pointers to tokens making up the comment block.
0 ignored issues
show
Documentation introduced by
Should the return type not be integer[]?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
122
     */
123
    private function _getCommentBlock(File $phpcsFile, $stackPtr)
124
    {
125
        $tokens = $phpcsFile->getTokens();
126
        $commentLines = array($stackPtr);
127
        $nextComment  = $stackPtr;
128
        $lastLine     = $tokens[$stackPtr]['line'];
129
130
        while (($nextComment = $phpcsFile->findNext($tokens[$stackPtr]['code'], ($nextComment + 1), null, false)) !== false) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 126 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
131
            if (($tokens[$nextComment]['line'] - 1) !== $lastLine) {
132
                // Not part of the block.
133
                break;
134
            }
135
136
            $lastLine       = $tokens[$nextComment]['line'];
137
            $commentLines[] = $nextComment;
138
        }
139
140
        return $commentLines;
141
    }//_getCommentBlock()
142
143
144
    /**
145
     * Add errors to $phpcsFile, if $commentLines isn't enclosed with blank lines.
146
     *
147
     * @param File $phpcsFile    The current file being scanned.
148
     * @param array                $commentLines Lines of the comment block being checked.
149
     *
150
     * @return bool TRUE if $commentLines is enclosed with at least a blank line
151
     * before and after, FALSE otherwise.
152
     */
153
    private function _checkBlankLinesAroundLongComment(File $phpcsFile, array $commentLines)
154
    {
155
        $hasBlankLinesAround = TRUE;
156
        $tokens = $phpcsFile->getTokens();
157
158
        // check blank line before the long comment
159
        $firstCommentPtr = reset($commentLines);
160
        $firstPreviousSpacePtr = $firstCommentPtr - 1;
161
        while (T_WHITESPACE === $tokens[$firstPreviousSpacePtr]['code'] && $firstPreviousSpacePtr > 0) {
162
            $firstPreviousSpacePtr--;
163
        }
164 View Code Duplication
        if ($tokens[$firstPreviousSpacePtr]['line'] >= $tokens[$firstCommentPtr]['line'] - 1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
165
            $error  = "Please add a blank line before comments counting more than {$this->longCommentLimit} lines.";
166
            $phpcsFile->addError($error, $firstCommentPtr, 'LongCommentWithoutSpacing');
167
            $hasBlankLinesAround = FALSE;
168
        }
169
170
        // check blank line after the long comment
171
        $lastCommentPtr = end($commentLines);
172
        $lastNextSpacePtr = $lastCommentPtr + 1;
173
        while (T_WHITESPACE === $tokens[$lastNextSpacePtr]['code'] && $lastNextSpacePtr < count($tokens)) {
174
            $lastNextSpacePtr++;
175
        }
176 View Code Duplication
        if ($tokens[$lastNextSpacePtr]['line'] <= $tokens[$lastCommentPtr]['line'] + 1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
177
            $error  = "Please add a blank line after comments counting more than {$this->longCommentLimit} lines.";
178
            $phpcsFile->addError($error, $lastCommentPtr, 'LongCommentWithoutSpacing');
179
            $hasBlankLinesAround = FALSE;
180
        }
181
182
        return $hasBlankLinesAround;
183
    }//end _checkBlanksAroundLongComment()
184
185
}//end class
186
187
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...